1 # 1、导包 2 import paddle.fluid as fluid 3 import paddle 4 import time 5 6 start = time.time() 7 8 9 def test_program(exe, feeder, program, fetch_list, reader): 10 """ 11 测试进程 12 :param exe:执行器 13 :param feeder: 数据与网络关系 14 :param program: 测试主进程 15 :param fetch_list: 需要执行之后返回的损失与准确率 16 :param reader: 测试reader 17 :return: 18 """ 19 # 训练次数 20 count = 0 21 # 整个测试集的总损失 22 sum_loss = 0 23 # 整个训练集的准确率 24 sum_acc = 0 25 for test_data in reader(): 26 test_avg_loss_value, test_acc_values = exe.run( 27 program=program, # 测试主进程 28 feed=feeder.feed(test_data), # 给测试喂数据 29 fetch_list=fetch_list # 需要执行之后返回的值 30 ) 31 32 sum_loss += test_avg_loss_value 33 sum_acc += test_acc_values 34 count += 1 35 # 得到整个训练集的平均损失,与整个训练集的准确率 36 test_avg_loss = sum_loss / count 37 test_acc = sum_acc / count 38 39 return test_avg_loss, test_acc 40 41 42 # 2、数据处理---paddlepaddle 自带的mnist数据已经经过了数据处理 43 44 # 3、定义reader 45 # paddlepaddle给我们已经定义好了reader,只需要去调用 46 47 # 4、指定训练场所 48 place = fluid.CPUPlace() 49 50 # 5、配置网络 51 # 特征数据层 52 image = fluid.layers.data(name="image", shape=[1, 28, 28], append_batch_size=True, dtype="float64") 53 # 目标数据层 54 label = fluid.layers.data(name="label", shape=[1], append_batch_size=True, dtype="int64") 55 # 设计2个隐层 一个输出层 共3层的fc网络 56 h1 = fluid.layers.fc(input=image, size=128, name="h1", act="relu") 57 h2 = fluid.layers.fc(input=h1, size=64, name="h2", act="relu") 58 59 # 输出层 60 y_predict = fluid.layers.fc(input=h2, size=10, name="output_layer", act="softmax") 61 62 # 6、损失 63 # 交叉熵损失 64 loss = fluid.layers.cross_entropy(input=y_predict, label=label) 65 # 计算平均损失 66 avg_loss = fluid.layers.mean(loss) 67 68 # 计算准确率 69 acc = fluid.layers.accuracy(input=y_predict, label=label) 70 71 # 7、指定优化---sgd随机梯度下降优化算法 72 sgd_optimizer = fluid.optimizer.SGD(learning_rate=0.1) 73 # 指定去优化损失 74 sgd_optimizer.minimize(avg_loss) 75 76 # 8、指定网络与数据层的关系 77 feeder = fluid.DataFeeder(feed_list=[image, label], place=place) 78 79 # 9、构建执行器 80 # 训练执行器 81 exe_train = fluid.Executor(place=place) 82 # 测试执行器 83 exe_test = fluid.Executor(place=place) 84 85 # 10、初始化网络参数 86 # 初始化参数进程 87 startup_program = fluid.default_startup_program() 88 exe_train.run(startup_program) 89 # 主进程 90 # 训练主进程 91 train_main_program = fluid.default_main_program() 92 # 测试主进程 93 test_main_program = train_main_program.clone(for_test=True) 94 95 # 11、获取图片数据 96 # 并不是直接拿到数据就往网络里面送 97 # 构建一个缓冲区,--打乱顺序,--再往网络里面送 98 # paddle.dataset.mnist.train() ----paddlepaddle的训练reader 99 # 缓冲区大小buf_size与批次大小batch_size 并没有多大的关系 100 # 一般设计的时候注意:buf_size 略微需要比batch_size 大一点就可以 101 # 而且batch_size 不能过大 102 # 训练reader 与测试reader 的batch_size数量必须一致 103 train_reader = paddle.batch( 104 paddle.reader.shuffle(paddle.dataset.mnist.train(), buf_size=50), 105 batch_size=10 106 ) 107 test_reader = paddle.batch( 108 paddle.reader.shuffle(paddle.dataset.mnist.test(), buf_size=50), 109 batch_size=10 110 ) 111 112 # 12、训练 113 # 指定训练轮数 114 loop_num = 2 115 # 定义的执行次数 116 step = 0 117 118 flag = False 119 120 for loop in range(loop_num): 121 print("第%d轮训练" % loop) 122 # train_data 每批次的数据 123 for train_data in train_reader(): 124 # 执行器运行训练主进程 125 train_avg_loss_value, train_acc_value = exe_train.run( 126 program=train_main_program, # 训练主进程 127 feed=feeder.feed(train_data), # 利用数据层与网络构建好的关系,将真实的数据喂给网络 128 fetch_list=[avg_loss, acc] # 执行之后需要返回的结果的值 129 ) 130 # 每隔10步来打印一下损失与准确率 131 if step % 10 == 0 and step != 0: 132 print("第%d次训练的损失为%f,准确率为%f" % (step, train_avg_loss_value, train_acc_value)) 133 134 step += 1 135 136 # 每隔100步 去测试集中测试一下训练效果 137 if step % 100 == 0 and step != 0: 138 test_avg_loss, test_acc = test_program(exe_test, 139 feeder, 140 test_main_program, 141 fetch_list=[avg_loss, acc], 142 reader=test_reader 143 ) 144 print("*" * 100) 145 print("测试集的损失为:%f,准确率为:%f" % (test_avg_loss, test_acc)) 146 print("*" * 100) 147 if test_avg_loss <= 0.1 and test_acc >= 0.98: 148 flag = True 149 print("最终测试集的损失为:%f,准确率为:%f" % (test_avg_loss, test_acc)) 150 151 end = time.time() 152 print("运行总时长为:", end - start) 153 break 154 if flag: 155 break