飞桨高层API实现手写数字识别任务

目录

1、介绍

2、问题定义&数据准备

3、模型选择和开发

4、模型训练和调优

5、模型评估测试

 6、部署上线


1、介绍

        手写数字识别项目就相当于是Paddle的Hello Word,就和我们学习编程语言一样,第一个输出的语句是Hello Word,手写数字识别是学习PaddlePaddle的第一个Hello Word级别项目。那么paddle是什么呢?它其实是由百度自主研发的一个深度学习框架,里面集成了许多API,有利于让我们更快的入门深度学习,那么我们面对一个深度学习任务的时候应该怎么去入手呢?其实我们利用paddle来完成一个深度学习任务是有一个万能公式的,它一共分为6步,分别是:1、问题定义;2、数据准备;3、模型选择和开发;4、模型训练和调优;5、模型评估测试;6、部署上线;接下来我们将基于飞桨(PaddlePaddle)的高层API来实现手写数字识别任务。

2、问题定义&数据准备

手写数字识别的问题定义比较简单,这里不过多描述。

导包也是每个程序的准备阶段了,对于手写数字识别任务我们导入的包如下:

import paddle
import numpy as np
import matplotlib.pyplot as plt
import paddle.vision.transforms as T

paddle是paddle框架的核心包,里面内置了许多高效的API。这里使用的 paddle.vision.transforms便是其一,它主要用于对我们的数据进行预处理。接下来我们会正式进入数据准备的阶段。

# 数据的加载和预处理
transform = T.Normalize(mean=[127.5], std=[127.5])
# 训练数据集
train_dataset = paddle.vision.datasets.MNIST(mode='train', transform=transform)
# 评估数据集
eval_dataset = paddle.vision.datasets.MNIST(mode='test', transform=transform)

因为paddle已经内置了手写数字识别项目的数据集,所有我们利用paddle.vision.datasets.MNIST就可以获取我们的数据集,model参数决定了我们取的是训练集还是测试集,对于我们定义的transform,它的作用是对我们的数据进行一个归一化存在,对于图片来讲,它们之间的差异通常会比较大,这时模型的训练效果就可能不是很好,但是归一化后再进行训练,模型就会得到一个比较好的预测分数。

3、模型选择和开发

当我们利用paddle来进行组网时,我们使用paddle.nn.Sequential这个API可以大幅度简化我们的代码,对于手写数字识别我们采用2层的全连接神经网络,在组网时我们会先使用paddle.nn.Flatten对数据进行一个拉平,变成一个一维的数组,作为第一层网络的输入,因为图片是28x28的,所以第一层的输入特征数为784,输出为512,这个不唯一,可以根据实际情况来调整输出值,而其会作为第二层的输入,中间我们会使用ReLu激活函数,其作用是增强神经网络的表达能力,最后的输出层的输出数为10,因为数字从0~9共10个数,网络最后会输出每个值的概率。实现代码如下:

# 模型网络结构搭建
network = paddle.nn.Sequential(
    paddle.nn.Flatten(),           # 拉平,将 (28, 28) => (784)
    paddle.nn.Linear(784, 512),    # 隐层:线性变换层
    paddle.nn.ReLU(),              # 激活函数
    paddle.nn.Linear(512, 10)      # 输出层
)

4、模型训练和调优

 组网结束后,我们会将其封装为一个模型,paddle也为我们提供了封装模型的API(paddle.Model),然后我们会为模型配置优化器、损失函数、评估指标,paddle为我们提供的优化器有许多,详情可以查看飞桨的API文档,手写数字识别任务实际上属于分类任务,对于图片的分类任务我们一般使用交叉熵损失(CrossEntropyLoss损失函数),为了评价模型的好坏,我们还需要指定一个评估指标(paddle.metric.Accuracy)。配置完成后我们马上应用模型进行训练,这里我们要指明训练数据集、训练的总轮次、训练使用的批大小,我们还可以指定日志的展现形式(verbose),一般指定1,以进度条的形式展现,根据实际情况需要,我们也可以指定评估数据集。

# 模型封装
model = paddle.Model(network)
# 配置优化器、损失函数、评估指标
model.prepare(paddle.optimizer.Adam(learning_rate=0.001, parameters=network.parameters()),
              paddle.nn.CrossEntropyLoss(),
              paddle.metric.Accuracy())
# 启动模型全流程训练
model.fit(train_dataset,  # 训练数据集
          eval_dataset,   # 评估数据集
          epochs=5,       # 训练的总轮次
          batch_size=64,  # 训练使用的批大小
          verbose=1)      # 日志展示形式

5、模型评估测试

训练结束后,我们可以使用evaluate进行评估。

# 模型评估,根据prepare接口配置的loss和metric进行返回
result = model.evaluate(eval_dataset, verbose=1)

 如果我们想进行批量的预测,可以使用model.predict接口实现对大量数据集的批量预测,为了展现更加直观的预测结果,我们可以随机输出几张图片的预测结果。

# 进行预测操作
result = model.predict(eval_dataset)
# 定义画图方法
def show_img(img, predict):
    plt.figure()
    plt.title('predict: {}'.format(predict))
    plt.imshow(img.reshape([28, 28]), cmap=plt.cm.binary)
    plt.show()
# 抽样展示
indexs = [2, 15, 38, 211]
for idx in indexs:
    show_img(eval_dataset[idx][0], np.argmax(result[0][idx]))

当然了,除了批量预测我们也可以对单张图片进行预测,这时我们会采用model.predict_batch来实现单张或少量图片的预测。

# 读取单张图片
image = eval_dataset[501][0]
# 单张图片预测
result = model.predict_batch([image])
# 可视化结果
show_img(image, np.argmax(result))

 6、部署上线

预测结束后,根据预测结果,如果我们认为模型的效果较好就可以保存模型了,保存后的模型可以继续进行调优寻练。

# 保存用于后续继续调优训练的模型
model.save('finetuning/mnist')

如果我们想要重新读取模型继续调优训练也很简单,和模型训练和调优时的代码差不多,只要改变封装函数时的代码和多加一条加载之前模型的代码就可以,其中InputSpec是用来规定层输入的尺寸和维度,因为之前模型训练的已经差不多了,所以再次训练我们可以适当降低训练的总轮次。

from paddle.static import InputSpec

# 模型封装,为了后面保存预测模型,这里传入了inputs参数
model_2 = paddle.Model(network, inputs=[InputSpec(shape=[-1, 28, 28], dtype='float32', name='image')])
# 加载之前保存的阶段训练模型
model_2.load('finetuning/mnist')
# 模型配置
model_2.prepare(paddle.optimizer.Adam(learning_rate=0.001, parameters=network.parameters()),
                paddle.nn.CrossEntropyLoss(),
                paddle.metric.Accuracy())
# 模型全流程训练
model_2.fit(train_dataset, 
            eval_dataset,
            epochs=2,
            batch_size=64,
            verbose=1)

最后在保存一下模型就ok了,当我们training设置为false时,代表模型已经结束训练,此时存储的是预测模型结构和网络参数。

# 保存用于后续推理部署的模型
model_2.save('infer/mnist', training=False)

到此手写数字识别任务完成,我们成功实现了paddlepaddle的Hello Word!

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

恒星小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值