上文回顾,目前已经揭晓了SGD以及GPU的配置方式,现在将介绍如何把画图函数以及正则化整进去
#各种优化算法均可以加入正则化项,避免过拟合,参数regularization_coeff调节正则化项的权重
opt_norm=paddle.optimizer.Adam(learning_rate=1e-3,weight_decay=paddle.regularizer.L2Decay(coeff=1e-5),parameters=model.parameters())
还是用matplotlib画图,我这里改装了一下教程的函数
直接上代码
import matplotlib.pyplot as plt
import numpy as np
def plot_line(train_set,valid_set,title):
plt.figure()
plt.title("{}".format(title), fontsize=24)
plt.xlabel('epoch', fontsize=14)
plt.ylabel('value', fontsize=14)
epoch_id=np.arange(0,len(train_set))
plt.plot(epoch_id, train_set, color='blue', label='train {}'.format(title))
plt.plot(epoch_id, valid_set, color='red', label='valid {}'.format(title))
plt.grid()
plt.legend()
plt.show()
最后整体代码如下:
dataset.py
import os
import random
import paddle
import numpy as np
from PIL import Image
import gzip
import json
def load_data(mode='train'):
datafile='./work/mnist.json.gz'
print("loading mnist dataset from {} ...".format(datafile))
data=json.load(gzip.open(datafile))
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]
imgs_length=len(imgs)
assert len(imgs)==len(labels),"length of train_imgs({}) should be the same as train_labels({})".format(
len(imgs),len(labels)
)
index_list=list(range(imgs_length))
BATCH_SIZE=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)
# 如果当前数据缓存达到batchsize,就返回一个批次数据
if len(imgs_list)==BATCH_SIZE:
yield np.array(imgs_list),np.array(labels_list)
imgs_list=[]
labels_list=[]
if len(imgs_list)>0:
yield np.array(imgs_list),np.array(labels_list)
return data_generator
network.py
import paddle.nn.functional as F
from paddle.nn import Conv2D,MaxPool2D,Linear
import paddle
class MNIST(paddle.nn.Layer):
def __init__(self):
super(MNIST, self).__init__()
# 定义卷积层
self.conv1=Conv2D(in_channels=1,out_channels=20,kernel_size=5,stride=1,padding=2)
# 定义池化层
self.max_pool1=MaxPool2D(kernel_size=2,stride=2)
# 定义卷积层
self.conv2=Conv2D(in_channels=20,out_channels=20,kernel_size=5,stride=1,padding=2)
# 定义池化层
self.max_pool2=MaxPool2D(kernel_size=2,stride=2)
# 全连接层
self.fc=Linear(in_features=980,out_features=10)
def forward(self,inputs,labels):
x=self.conv1(inputs)
x=F.relu(x)
x=self.max_pool1(x)
x=F.relu(x)
x=self.conv2(x)
x=F.relu(x)
x=self.max_pool2(x)
x=paddle.reshape(x,[x.shape[0],980])
x=self.fc(x)
if labels is not None:
acc=paddle.metric.accuracy(input=x,label=labels)
return x,acc
else:
return x
主函数
from dataset import load_data
from network import MNIST
import paddle.nn.functional as F
import paddle
import numpy as np
from plot import plot_line
def train(model):
model.train()
opt=paddle.optimizer.Adam(learning_rate=1e-3,parameters=model.parameters())
# #各种优化算法均可以加入正则化项,避免过拟合,参数regularization_coeff调节正则化项的权重
opt_norm=paddle.optimizer.Adam(learning_rate=1e-3,weight_decay=paddle.regularizer.L2Decay(coeff=1e-5),parameters=model.parameters())
EPOCH_NUM=5
train_acc_set = []
train_avg_loss_set = []
valid_acc_set = []
valid_avg_loss_set = []
for epoch_id in range(EPOCH_NUM):
acc_set = []
avg_loss_set = []
for batch_id,data in enumerate(train_loader()):
images,labels=data
images=paddle.to_tensor(images)
labels=paddle.to_tensor(labels)
predicts,acc=model(images,labels)
loss=F.cross_entropy(predicts,labels)
avg_loss=paddle.mean(loss)
acc_set.append(float(acc.numpy()))
avg_loss_set.append(float(avg_loss.numpy()))
if batch_id % 200 == 0:
print("epoch:{}, batch:{}, loss is {}, acc is {}".format(
epoch_id,batch_id,avg_loss.numpy(),acc.numpy()
))
avg_loss.backward()
opt_norm.step()
opt_norm.clear_grad()
# 统计一个epoch的loss以及train acc
acc_val_mean = np.array(acc_set).mean()
avg_loss_val_mean = np.array(avg_loss_set).mean()
val_acc_set,val_avg_loss_set=evaluation(model)
train_acc_set.append(acc_val_mean)
train_avg_loss_set.append(avg_loss_val_mean)
valid_acc_set.append(val_acc_set)
valid_avg_loss_set.append(val_avg_loss_set)
paddle.save(model.state_dict(),'mnist.pdparams')
return train_acc_set,train_avg_loss_set,valid_acc_set,valid_avg_loss_set
def evaluation(model):
model.eval()
eval_loader=load_data('valid')
acc_set=[]
avg_loss_set=[]
for batch_id,data in enumerate(eval_loader()):
images,labels=data
images=paddle.to_tensor(images)
labels=paddle.to_tensor(labels)
predicts,acc=model(images,labels)
loss=F.cross_entropy(input=predicts,label=labels)
avg_loss=paddle.mean(loss)
acc_set.append(float(acc.numpy()))
avg_loss_set.append(float(avg_loss.numpy()))
acc_val_mean=np.array(acc_set).mean()
avg_loss_val_mean=np.array(avg_loss_set).mean()
print("loss:{} acc:{}".format(avg_loss_val_mean,acc_val_mean))
return acc_val_mean,avg_loss_val_mean
def test(model):
print("start evaluation.............")
params_file_path='mnist.pdparams'
param_dict=paddle.load(params_file_path)
model.load_dict(param_dict)
model.eval()
eval_loader=load_data('eval')
acc_set=[]
avg_loss_set=[]
iters = []
iter = 0
losses = []
for batch_id,data in enumerate(eval_loader()):
images,labels=data
images=paddle.to_tensor(images)
labels=paddle.to_tensor(labels)
predicts,acc=model(images,labels)
loss=F.cross_entropy(input=predicts,label=labels)
avg_loss=paddle.mean(loss)
iters.append(iter)
losses.append(avg_loss.numpy())
iter = iter + 1
acc_set.append(float(acc.numpy()))
avg_loss_set.append(float(avg_loss.numpy()))
acc_val_mean=np.array(acc_set).mean()
avg_loss_val_mean=np.array(avg_loss_set).mean()
print("loss:{} acc:{}".format(avg_loss_val_mean,acc_val_mean))
return iters,losses
train_loader=load_data('train')
use_gpu=True
paddle.set_device("gpu:0") if use_gpu else paddle.set_device("cpu")
model=MNIST()
train_acc_set,train_avg_loss_set,valid_acc_set,valid_avg_loss_set=train(model)
test(model)
'''画图'''
plot_line(train_acc_set,valid_acc_set,'loss')
plot_line(train_avg_loss_set,valid_avg_loss_set,'acc')