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