手写数字识别
程序员文章站
2022-03-28 13:48:43
...
模型训练代码
#模型训练以及预测代码
import paddle
import paddle.fluid as fluid
from paddle.fluid.dygraph.nn import FC,Conv2D,Pool2D
import numpy as np
import os
import matplotlib.pyplot as plt
from PIL import Image
import gzip
import json
import random
#定义数据集读取器
def load_data(mode='train'):
datafile='./work/mnist.json.gz'
print('loading mnist dataset from {}...'.format(datafile))
data=json.load(gzip.open(datafile))
print('mnist dataset load done')
#读取到的数据区分训练集,验证集,测试集
train_set,val_set,eval_set=data
IMG_ROWS=28
IMG_COLS=28
if mode=='train':
imgs=train_set[0]
labels=train_set[1]
elif mode=='valid':
imgs=val_set[0]
labels=val_set[1]
elif mode=='eval':
imgs=eval_set[0]
labels=eval_set[1]
else:
raise Exception("mode can only be one of ['train', 'valid', 'eval']")
imgs_length=len(imgs)
assert len(imgs)==len(labels),\
'length of train_imgs({}) should be the same as train_label({})'.format(len(imgs), len(labels))
#定义数据集每个数据的序号,之后根据序号读取数据
index_list=list(range(imgs_length))
BATCHSIZE=100
def data_generator():
if mode=='train':
random.shuffle(index_list)
imgs_list=[]
labels_list=[]
for i in index_list:
img=np.reshape(imgs[i],[1,IMG_ROWS,IMG_COLS]).astype('float32')
label=np.reshape(labels[i],[1]).astype('int64')
imgs_list.append(img)
labels_list.append(label)
if len(imgs_list)==BATCHSIZE:
yield np.array(imgs_list),np.array(labels_list)
#清空数据读取的列表
imgs_list=[]
labels_list=[]
#如果剩余数据的数目小于BATCHSIZE
if len(imgs_list)>0:
yield np.array(imgs_list),np.array(labels_list)
return data_generator
#模型设计部分
class MNIST(fluid.dygraph.Layer):
def __init__(self,name_scope):
super(MNIST,self).__init__(name_scope)
name_scope=self.full_name()
self.conv1=Conv2D(name_scope,num_filters=20,filter_size=5,stride=1,padding=2,act='relu')
self.pool1=Pool2D(name_scope,pool_size=2,pool_stride=2,pool_type='max')
self.conv2=Conv2D(name_scope,num_filters=20,filter_size=5,stride=1,padding=2,act='relu')
self.pool2=Pool2D(name_scope,pool_size=2,pool_stride=2,pool_type='max')
# self.conv3=Conv2D(name_scope,num_filters=20,filter_size=5,stride=1,padding=2,act='relu')
# self.pool3=Pool2D(name_scope,pool_size=2,pool_stride=2,pool_type='max')
self.fc=FC(name_scope,size=10,act='softmax')
def forward(self,inputs,label=None):
x=self.conv1(inputs)
x=self.pool1(x)
x=self.conv2(x)
x=self.pool2(x)
# x=self.conv3(x)
# x=self.pool3(x)
x=self.fc(x)
if label is not None:
acc=fluid.layers.accuracy(input=x,label=label)
return x,acc
else:
return x
use_gpu=False
place=fluid.CPUPlace(0) if use_gpu else fluid.CPUPlace()
with fluid.dygraph.guard():
model=MNIST('mnist')
model.train()
train_loader=load_data('train')
#定义dataloader对象用于加载python生成器产生的数据
data_loader=fluid.io.DataLoader.from_generator(capacity=5,return_list=True)
data_loader.set_batch_generator(train_loader,places=place)
#optimizer=fluid.optimizer.SGDOptimizer(learning_rate=0.001,regularization=fluid.regularizer.L2Decay(regularization_coeff=0.1))
optimizer=fluid.optimizer.MomentumOptimizer(learning_rate=0.01,momentum=0.86)
#optimizer=fluid.optimizer.AdagradOptimizer(learning_rate=0.01)
#optimizer=fluid.optimizer.AdamOptimizer(learning_rate=0.01)
EPOCH_NUM=20
iter=0
iters=[]
losses=[]
for epoch_id in range(EPOCH_NUM):
for batch_id,data in enumerate(data_loader):
image_data,label_data=data
# image_data=np.array([x[0] for x in data]).astype('float32')
# label_data=np.array([x[1] for x in data]).astype('float32').reshape(-1,1)
#数据转成paddle动态图格式
image=fluid.dygraph.to_variable(image_data)
label=fluid.dygraph.to_variable(label_data)
#前向计算
predict,avg_acc=model(image,label)
loss=fluid.layers.cross_entropy(predict,label)
avg_loss=fluid.layers.mean(loss)
if batch_id!=0 and batch_id%100==0:
print('epoch:{},batch:{},loss is:{}'.format(epoch_id,batch_id,avg_loss.numpy()))
iters.append(iter)
losses.append(avg_loss.numpy())
iter=iter+100
#后向传播,更新参数
avg_loss.backward()
optimizer.minimize(avg_loss)
model.clear_gradients()
fluid.save_dygraph(model.state_dict(),'mnist')
import matplotlib.pyplot as plt
plt.figure()
plt.title('train loss',fontsize=24)
plt.xlabel('iter',fontsize=14)
plt.ylabel('loss',fontsize=14)
plt.plot(iters,losses,color='red',label='train loss')
plt.grid()
plt.show()
调用模型进行预测
import paddle
import paddle.fluid as fluid
from paddle.fluid.dygraph.nn import FC,Conv2D,Pool2D
import numpy as np
import os
from PIL import Image
import matplotlib.pyplot as plt
import gzip
import json
import random
#模型设计部分
class MNIST(fluid.dygraph.Layer):
def __init__(self,name_scope):
super(MNIST,self).__init__(name_scope)
name_scope=self.full_name()
self.conv1=Conv2D(name_scope,num_filters=20,filter_size=5,stride=1,padding=2,act='relu')
self.pool1=Pool2D(name_scope,pool_size=2,pool_stride=2,pool_type='max')
self.conv2=Conv2D(name_scope,num_filters=20,filter_size=5,stride=1,padding=2,act='relu')
self.pool2=Pool2D(name_scope,pool_size=2,pool_stride=2,pool_type='max')
# self.conv3=Conv2D(name_scope,num_filters=20,filter_size=5,stride=1,padding=2,act='relu')
# self.pool3=Pool2D(name_scope,pool_size=2,pool_stride=2,pool_type='max')
self.fc=FC(name_scope,size=10,act='softmax')
def forward(self,inputs,label=None):
x=self.conv1(inputs)
x=self.pool1(x)
x=self.conv2(x)
x=self.pool2(x)
# x=self.conv3(x)
# x=self.pool3(x)
x=self.fc(x)
if label is not None:
acc=fluid.layers.accuracy(input=x,label=label)
return x,acc
else:
return x
# 定义预测过程
with fluid.dygraph.guard():
print('start evaluation.....')
model = MNIST("mnist")
# params_file_path = 'mnist'
# img_path = './work/example_0.png'
# 加载模型参数
image = Image.open('./work/2.jpg').convert('L')
image = np.array(image)
plt.imshow(image)
img=np.reshape(image,[1,1,28,28]).astype('float32')
image=fluid.dygraph.to_variable(img)
model_dict, _ = fluid.load_dygraph("mnist")
model.load_dict(model_dict)
model.eval()
prediction=model(image)
print(prediction[0])
# print(prediction.dtype)
lab = np.argsort(prediction.numpy())
print(lab)
print("本次预测的数字是: ", lab[0][-1])
结果: