带自己学paddle(四)

项目一 手写数字识别

上文回顾,目前已经揭晓了SGD以及GPU的配置方式,现在将介绍如何把画图函数以及正则化整进去

l2 norm

#各种优化算法均可以加入正则化项,避免过拟合,参数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')




训练效果:
带自己学paddle(四)_第1张图片
在这里插入图片描述
后面两节将体验断点重训以及动态图转静态图的过程,期待hhhh

你可能感兴趣的:(paddle,paddle,python,计算机视觉)