您的位置:首页 > 其它

Paddle零基础深度学习-第1周实践作业

2020-08-19 02:14 615 查看

Paddle零基础深度学习-第1周实践作业

1. 作业要求

课程中以1张图片为例,测试了预测效果。请从原始mnist数据集中,『随机抽取』100张图片,测试模型的分类准确率。
注:模型请使用课程中【项目9】的模型 【作业内容】
✓代码跑通 请大家根据课上所学内容,编写代码,保证程序跑通。
✓ 代码运行成功且有结果(打印100张图片的分类准确率)

2. 设计思路说明

  1. 作业的 data 中有数据文件mnist.json.gz,把那个文件拷贝到 work
    文件夹中,或直接下载data/data49019文件夹中的mnist.json.gz,再上传到work文件夹中去;
  2. 测试过程所用的网络结构与训练过程的网络结构是一样的,只不过数据不同,因此测试过程代码与训练过程代码类似;
  3. 而要读取的100个随机的测试数据,也要在前面读取数据的方法load_data()中处理,原来的模型中已经训练类型的数据进行了shuffle()处理,本项目中将其扩展为对所有类型的数据都进行shuffle()处理,这样验证和测试时就都可以使用随机抽取的数据了;
  4. 训练过程需要进行几个epoch来提高模型的准确率,而测试过程直接读取训练过程保存的优化后的模型参数,则不需要循环,只需要运行一次,给出预测结果值即可。

测试程序的实现如下:

3. 代码实现过程

3.1. 导入库

import os
import random
import paddle
import paddle.fluid as fluid
from paddle.fluid.dygraph.nn import Conv2D, Pool2D, Linear
import numpy as np
from PIL import Image

import gzip
import json

3.2. 数据加载处理

# 定义数据集读取器,这里使用 项目9 的程序结构,对程序做“1.”处的修改
'''
定义数据集读取器
@param
mode: 读取数据的类型,有三种值
train: 默认,训练集数据
valid: 验证集数据
eval:  测试集数据
'''
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, 图片宽度IMG_COLS
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))

# 读入数据时用到的batchsize
BATCHSIZE = 100

# 定义数据生成器
def data_generator():
#         if mode == 'train':    #  原来这里只对训练数据做了随机抽取处理
#             random.shuffle(index_list)
# 1. 在这里修改为对所有类型的数据都进行随机抽取处理
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,
# 则剩余数据一起构成一个大小为len(imgs_list)的mini-batch
if len(imgs_list) > 0:
yield np.array(imgs_list), np.array(labels_list)

return data_generator

#调用加载数据的函数
train_loader = load_data('train')

3.3. 定义网络结构

# 定义模型结构
class MNIST(fluid.dygraph.Layer):
def __init__(self):
super(MNIST, self).__init__()
# 定义一个卷积层,使用relu激活函数
self.conv1 = Conv2D(num_channels=1, num_filters=20, filter_size=5, stride=1, padding=2, act='relu')
# 定义一个池化层,池化核为2,步长为2,使用最大池化方式
self.pool1 = Pool2D(pool_size=2, pool_stride=2, pool_type='max')
# 定义一个卷积层,使用relu激活函数
self.conv2 = Conv2D(num_channels=20, num_filters=20, filter_size=5, stride=1, padding=2, act='relu')
# 定义一个池化层,池化核为2,步长为2,使用最大池化方式
self.pool2 = Pool2D(pool_size=2, pool_stride=2, pool_type='max')
# 定义一个全连接层,输出节点数为10
self.fc = Linear(input_dim=980, output_dim=10, act='softmax')
# 定义网络的前向计算过程
def forward(self, inputs, label):
x = self.conv1(inputs)
x = self.pool1(x)
x = self.conv2(x)
x = self.pool2(x)
x = fluid.layers.reshape(x, [x.shape[0], 980])
x = self.fc(x)
if label is not None:
acc = fluid.layers.accuracy(input=x, label=label)
return x, acc
else:
return x

3.4. 进行训练

# 进行训练,这里使用“项目9”的代码,添加“2.保存全局的模型参数” 处的代码
#在使用GPU机器时,可以将use_gpu变量设置成True
use_gpu = True
place = fluid.CUDAPlace(0) if use_gpu else fluid.CPUPlace()

with fluid.dygraph.guard(place):
model = MNIST()
model.train()

EPOCH_NUM = 5
BATCH_SIZE = 100
# 定义学习率,并加载优化器参数到模型中
total_steps = (int(60000//BATCH_SIZE) + 1) * EPOCH_NUM
lr = fluid.dygraph.PolynomialDecay(0.01, total_steps, 0.001)

# 使用Adam优化器
optimizer = fluid.optimizer.AdamOptimizer(learning_rate=lr, parameter_list=model.parameters())

for epoch_id in range(EPOCH_NUM):
for batch_id, data in enumerate(train_loader()):
#准备数据,变得更加简洁
image_data, label_data = data
image = fluid.dygraph.to_variable(image_data)
label = fluid.dygraph.to_variable(label_data)

#前向计算的过程,同时拿到模型输出值和分类准确率
predict, acc = model(image, label)
avg_acc = fluid.layers.mean(acc)

#计算损失,取一个批次样本损失的平均值
loss = fluid.layers.cross_entropy(predict, label)
avg_loss = fluid.layers.mean(loss)

#每训练了200批次的数据,打印下当前Loss的情况
if batch_id % 200 == 0:
print("epoch: {}, batch: {}, loss is: {}, acc is {}".format(epoch_id, batch_id, avg_loss.numpy(),avg_acc.numpy()))

#后向传播,更新参数的过程
avg_loss.backward()
optimizer.minimize(avg_loss)
model.clear_gradients()

# 保存模型参数和优化器的参数
fluid.save_dygraph(model.state_dict(), './checkpoint/mnist_epoch{}'.format(epoch_id))
fluid.save_dygraph(optimizer.state_dict(), './checkpoint/mnist_epoch{}'.format(epoch_id))
fluid.save_dygraph(model.state_dict(),'mnist')    # 2.保存全局的模型参数

3.5 进行测试

'''
3. 这里是新增的内容,使用与训练过程类似的代码,完成预测过程,
能从测试集中随机取出100个样本进行预测,并显示各个样本的计算损失及准确率
'''
# 测试数据读取器
test_loader = load_data("eval")

use_gpu = True
place = fluid.CUDAPlace(0) if use_gpu else fluid.CPUPlace()

# 测试过程如下
with fluid.dygraph.guard(place):
print('start testing ......')
# 加载模型参数
model = MNIST()
model_state_dict, _ = fluid.load_dygraph('mnist')
# 这里选择使用set_dict,因为load_dict即将过时
model.set_dict(model_state_dict)

model.eval()

for batch_id, data in enumerate(test_loader()):
#准备数据,变得更加简洁
image_data, label_data = data
image = fluid.dygraph.to_variable(image_data)
label = fluid.dygraph.to_variable(label_data)

#前向计算的过程,同时拿到模型输出值和分类准确率
predict, acc = model(image, label)
avg_acc = fluid.layers.mean(acc)

#计算损失,取一个批次样本损失的平均值
loss = fluid.layers.cross_entropy(predict, label)
avg_loss = fluid.layers.mean(loss)

# 这里将每一个图片的损失与准确率都打印出来,因为要显示结构用,所以通过 batch_id+1 让图片从 1 开始显示
print("batch: {}, loss is: {}, acc is {}".format(batch_id+1, avg_loss.numpy(),avg_acc.numpy()))

4. 心得与体会

1) 从老师留了作业后,一直想做,一直静不下心来做作业,总是有各个事情给耽误了作业:)
2) 前几天的一个打卡作业,感觉看API文档和老师的资料都已经很仔细了,自己认为那天的知识学的很好了,结果打卡作业的分数却很不理想,今天终于有时间了,再返回头去看课件资料和API文档,发现自己的记忆和对内容的理解还是有偏差;
3) 对于这个实践作业,也认真的读了一下老师的课程代码,发现老师在课程中也介绍的很清晰了,作业只是对课程内容的一些扩展,所以以后的学习,也要静下心来,认真的去学习每个知识点和它相关的内容;
4) 另外随着这段时间的代码练习和对paddle的学习,发现自己对python和深度学习的知识和框架的理解,有所加强了,但是还要继续努力学习,小伙伴们,大家一起努力,多学习,多实践,在老美不断的技术和信息封锁、全面压制下,争取把paddle这类优秀的民族框架学习好、发展好、应用好。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐