五、手写字符识别
http://yann.lecun.com/exdb/mnist/
准备:
下载语雀--资料中的data1910文件,放入放置Anaconda的盘的home,放置路径如下:
/home/aistudio/data/data1910
1 import numpy as np 2 import paddle as paddle 3 import paddle.fluid as fluid 4 from PIL import Image 5 import matplotlib.pyplot as plt 6 import os 7 8 9 BUF_SIZE=512 10 BATCH_SIZE=128 11 train_reader = paddle.batch( 12 paddle.reader.shuffle(paddle.dataset.mnist.train(), 13 buf_size=BUF_SIZE), 14 batch_size=BATCH_SIZE) 15 #用于测试的数据提供器,每次从缓存中随机读取批次大小的数据 16 test_reader = paddle.batch( 17 paddle.reader.shuffle(paddle.dataset.mnist.test(), 18 buf_size=BUF_SIZE), 19 batch_size=BATCH_SIZE) 20 21 #用于打印,查看mnist数据 22 train_data=paddle.dataset.mnist.train(); 23 sampledata=next(train_data()) 24 print(sampledata) 25 26 27 28 def multilayer_perceptron(input): 29 # 第一个全连接层,激活函数为ReLU 30 hidden1 = fluid.layers.fc(input=input, size=100, act='relu') 31 # 第二个全连接层,激活函数为ReLU 32 hidden2 = fluid.layers.fc(input=hidden1, size=100, act='relu') 33 # 以softmax为激活函数的全连接输出层,输出层的大小必须为数字的个数10 34 prediction = fluid.layers.fc(input=hidden2, size=10, act='softmax') 35 return prediction 36 37 38 # 输入的原始图像数据,大小为1*28*28 39 image = fluid.layers.data(name='image', shape=[1, 28, 28], dtype='float32')#单通道,28*28像素值 40 # 标签,名称为label,对应输入图片的类别标签 41 label = fluid.layers.data(name='label', shape=[1], dtype='int64') #图片标签 42 43 44 45 # 获取分类器 46 predict = multilayer_perceptron(image) 47 48 49 #使用交叉熵损失函数,描述真实样本标签和预测概率之间的差值 50 cost = fluid.layers.cross_entropy(input=predict, label=label) 51 # 使用类交叉熵函数计算predict和label之间的损失函数 52 avg_cost = fluid.layers.mean(cost) 53 # 计算分类准确率 54 acc = fluid.layers.accuracy(input=predict, label=label) 55 56 57 #使用Adam算法进行优化, learning_rate 是学习率(它的大小与网络的训练收敛速度有关系) 58 optimizer = fluid.optimizer.AdamOptimizer(learning_rate=0.001) 59 opts = optimizer.minimize(avg_cost) 60 61 62 63 # 定义使用CPU还是GPU,使用CPU时use_cuda = False,使用GPU时use_cuda = True 64 use_cuda = False 65 place = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace() 66 # 获取测试程序 67 test_program = fluid.default_main_program().clone(for_test=True) 68 exe = fluid.Executor(place) 69 exe.run(fluid.default_startup_program()) 70 71 72 all_train_iter=0 73 all_train_iters=[] 74 all_train_costs=[] 75 all_train_accs=[] 76 77 def draw_train_process(title,iters,costs,accs,label_cost,lable_acc): 78 plt.title(title, fontsize=24) 79 plt.xlabel("iter", fontsize=20) 80 plt.ylabel("cost/acc", fontsize=20) 81 plt.plot(iters, costs,color='red',label=label_cost) 82 plt.plot(iters, accs,color='green',label=lable_acc) 83 plt.legend() 84 plt.grid() 85 plt.show() 86 87 88 feeder = fluid.DataFeeder(place=place, feed_list=[image, label]) 89 90 91 92 93 EPOCH_NUM=2 94 model_save_dir = "/home/aistudio/work/hand.inference.model" 95 for pass_id in range(EPOCH_NUM): 96 # 进行训练 97 for batch_id, data in enumerate(train_reader()): #遍历train_reader 98 train_cost, train_acc = exe.run(program=fluid.default_main_program(),#运行主程序 99 feed=feeder.feed(data), #给模型喂入数据 100 fetch_list=[avg_cost, acc]) #fetch 误差、准确率 101 102 all_train_iter=all_train_iter+BATCH_SIZE 103 all_train_iters.append(all_train_iter) 104 105 all_train_costs.append(train_cost[0]) 106 all_train_accs.append(train_acc[0]) 107 108 # 每200个batch打印一次信息 误差、准确率 109 if batch_id % 200 == 0: 110 print('Pass:%d, Batch:%d, Cost:%0.5f, Accuracy:%0.5f' % 111 (pass_id, batch_id, train_cost[0], train_acc[0])) 112 113 # 进行测试 114 test_accs = [] 115 test_costs = [] 116 #每训练一轮 进行一次测试 117 for batch_id, data in enumerate(test_reader()): #遍历test_reader 118 test_cost, test_acc = exe.run(program=test_program, #执行训练程序 119 feed=feeder.feed(data), #喂入数据 120 fetch_list=[avg_cost, acc]) #fetch 误差、准确率 121 test_accs.append(test_acc[0]) #每个batch的准确率 122 test_costs.append(test_cost[0]) #每个batch的误差 123 124 125 # 求测试结果的平均值 126 test_cost = (sum(test_costs) / len(test_costs)) #每轮的平均误差 127 test_acc = (sum(test_accs) / len(test_accs)) #每轮的平均准确率 128 print('Test:%d, Cost:%0.5f, Accuracy:%0.5f' % (pass_id, test_cost, test_acc)) 129 130 #保存模型 131 # 如果保存路径不存在就创建 132 if not os.path.exists(model_save_dir): 133 os.makedirs(model_save_dir) 134 print ('save models to %s' % (model_save_dir)) 135 fluid.io.save_inference_model(model_save_dir, #保存推理model的路径 136 ['image'], #推理(inference)需要 feed 的数据 137 [predict], #保存推理(inference)结果的 Variables 138 exe) #executor 保存 inference model 139 140 print('训练模型保存完成!') 141 draw_train_process("training",all_train_iters,all_train_costs,all_train_accs,"trainning cost","trainning acc") 142 143 144 145 def load_image(file): 146 147 im = Image.open(file).convert('L') #将RGB转化为灰度图像,L代表灰度图像,像素值在0~255之间 148 im = im.resize((28, 28), Image.ANTIALIAS) #resize image with high-quality 图像大小为28*28 149 im = np.array(im).reshape(1, 1, 28, 28).astype(np.float32)#返回新形状的数组,把它变成一个 numpy 数组以匹配数据馈送格式。 150 # print(im) 151 im = im / 255.0 * 2.0 - 1.0 #归一化到【-1~1】之间 152 return im 153 154 155 infer_path='D:/home/aistudio/data/data1910/infer_9.jpg' 156 #infer_path='D:/home/aistudio/data/data1910/infer_3.png' 157 img = Image.open(infer_path) 158 plt.imshow(img) #根据数组绘制图像 159 plt.show() #显示图像 160 161 162 infer_exe = fluid.Executor(place) 163 inference_scope = fluid.core.Scope() 164 165 166 167 168 # 加载数据并开始预测 169 with fluid.scope_guard(inference_scope): 170 #获取训练好的模型 171 #从指定目录中加载 推理model(inference model) 172 [inference_program, #推理Program 173 feed_target_names, #是一个str列表,它包含需要在推理 Program 中提供数据的变量的名称。 174 fetch_targets] = fluid.io.load_inference_model(model_save_dir,#fetch_targets:是一个 Variable 列表,从中我们可以得到推断结果。model_save_dir:模型保存的路径 175 infer_exe) #infer_exe: 运行 inference model的 executor 176 img = load_image(infer_path) 177 178 results = infer_exe.run(program=inference_program, #运行推测程序 179 feed={feed_target_names[0]: img}, #喂入要预测的img 180 fetch_list=fetch_targets) #得到推测结果, 181 # 获取概率最大的label 182 lab = np.argsort(results) #argsort函数返回的是result数组值从小到大的索引值 183 #print(lab) 184 print("该图片的预测结果的label为: %d" % lab[0][0][-1]) #-1代表读取数组中倒数第一列
越努力越幸运