使用PaddlePaddle框架实现MNIST手写数字识别

数据集说明

MNIST数据集上的手写数字识别问题是机器学习(或深度学习)的入门课程,属于典型的图像分类问题。MNIST数据集作为一个简单的计算机视觉数据集,包含一系列如下图所示的手写数字图片和对应的标签。图片是28x28的像素矩阵,标签则对应着0~9的10个数字。每张图片都经过了大小归一化和居中处理。
mnist_example_image.png
接下来我们就来一起使用Inifinite平台实现MNIST数据集上的手写数字识别。

准备工作 - 开通数据存储服务

Infinite平台与BOS(百度对象存储)进行了深度的融合和打通,方便了您从云端读取数据以及保存代码或模型到云端。所以请您先开通BOS服务并创建Bucket。详细了解对象存储BOS

登录百度智能云管理控制台,产品服务导航选择“存储与CDN->对象存储BOS”,进入“开通对象存储BOS”页面,点击『立即开通』,在页面的文字引导下完成实名认证并开通BOS。

开通BOS后,进入BOS管理控制台,点击『新建Bucket』按钮,在弹出的浮层中按照提示创建Bucket。注意,Infinite目前只支持读取或写入华北-北京区域的Bucket,创建Bucket时需要选择华北-北京(Bucket具有区域属性,只能位于一个区域,Bucket名称创建后不能修改所属区域)。

01-creat-a-bucket.png

新建两个文件夹notebook和training,分别用来存放工作区和训练作业的数据。

02-creat-2-folders.png

使用工作区进行代码调试

在工作区,您可以在Jupyter Notebook环境下,编写、调试代码,完成训练、预测,并保存模型。

新建工作区实例

进入Infinite控制台,默认选择工作区,点击『创建实例』。

03-creat-an-instance.png

在弹窗中填写实例名称,如下图所示指定代码保存路径为bos:/your-bucket-name/notebook/(your-bucket-name是您创建的Bucket的名称,下同),选择资源套餐,即可完成创建。

04-new-instance.png

启用Jupyter Notebook进行代码调试

我们创建了一个实例叫做paddle-mnist,点击『打开Jupyter』,启用Jupyter Notebook。

05-open-jupyter.png

在左侧的demo文件夹下,我们预置了四个.ipynb格式示例代码供您学习使用。您可以逐单元执行,实现数据下载、网络模型构建、训练和预测。另外,我们还提供了一个paddle-mnsit.py文件用来发起训练作业,我们在后面的作业管理部分会用到。

双击打开paddlepaddle-mnist.ipynb,执行结束后,你可以看到,它实现了从Infinite公共BOS下载训练和预测数据到本地train_data文件夹下,并将训练好的模型保存到output/recognize_digits.inference.model/下。

06-model-save.png

工作区会不断将本地数据同步到您的BOS路径下bos:/your-bucket-name/notebook/demo/。您可以在BOS控制台看到下载下来的数据和保存的预测模型。刚刚保存在output/recognize_digits.inference.model/路径下的模型可以直接用作预测。

07-save-model.png

工作区Jupyter Notebook环境目前只支持单机单卡,如果您对资源有更高要求,需要大规模分布式训练作业,您可以通过作业管理,发起作业到集群进行训练。工作区和训练作业保存的模型都可以用来预测。

使用作业管理发起训练

对于大规模训练作业,您可以发起作业到集群进行训练。导航选择“作业管理->深度学习作业”,点击『新建作业』,进入新建作业流程。填写作业名称,选择算法框架为paddle-fluid-v1.4.0,默认选项为『选取代码文件』,代码文件路径从bos:/your-bucket-name/notebook/demo/选取代码文件paddle-mnist.py,我们在此路径下,为您预置了一个.py格式示例代码paddle-mnist.py供您学习使用。然后完成计算集群的配置,选择数据输出路径、日志存储路径,填写训练数据路径为bos:/infinite-aibook/data/MNIST/,这是Infinite的公共BOS,您只有公共READ+LIST权限。完成以上配置即可发起训练作业,作业完成后模型保存在bos:/quick-guide/training/your-job-id/rank-00000/recognize_digits.inference.model/(your-job-id是您创建的作业的ID,下同)路径下。

08-new-training.jpg

启用预测服务

训练完成后,您可以使用保存的模型来实现预测服务。

创建预测模型库

您首先需要创建模型库,导航选择“预测->预测模型库”,点击『新建模型』,填写模型名称,指定模型格式为paddle-fluid-v1.4.0,选择预测模型的文件路径。这里的模型文件路径可以来自工作区保存的模型bos:/quick-guide/notebook/demo/output/recognize_digits.inference.model/,也可以来自深度学习作业保存的的模型bos:/quick-guide/training/your-job-id/rank-00000/recognize_digits.inference.model/,您可以任选一个填写。

!09-new-inference.png

配置端点模版

接下来您需要配置预测所需的云上所需的计算集群资源和服务策略。

导航选择“预测->端点模板”,点击『新建端点模板』,填写端点模板名称,点击『新建版本』,填写版本名称为v1,选择模型文件为“用户模型->paddle-mnist”,选择资源套餐,设定比重和运行实例数量。

当您指定两个或更多版本时,可以为每个版本选择比重,通过设置不同比重,实现A/B Test功能。

10-endpoint-model.png

创建端点

最后您按照配置好的端点模板新建一个端点。填写端点名称,端点配置选择刚刚创建的端点模板,选择需要的计算资源。

11-new-endpoint.png

创建端点完成后会生成一个端点url,供您调用API进行预测。

12-url.png

调试

您也可以选择在线预测,点击右侧的『调试』,选择调试对象,指定调试方法为输入参数,在调试参数框内输入如下的参数。该参数是由您要解决的问题、选择的深度学习框架和输入数据格式决定的,对于不同预测模型,该参数的格式是不同的。

{"instances": [{"tensors": [{"shape": [1, 1, 28, 28], "type": "FLOAT", "name": "test", "float_data": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.25882354378700256, 1.0, 0.21568629145622253, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.729411780834198, 0.9921569228172302, 0.21568629145622253, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.019607843831181526, 0.7490196228027344, 0.9921569228172302, 0.21568629145622253, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2196078598499298, 0.9921569228172302, 0.9921569228172302, 0.21568629145622253, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2823529541492462, 0.9921569228172302, 0.9921569228172302, 0.21568629145622253, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.40000003576278687, 0.9921569228172302, 0.9921569228172302, 0.21568629145622253, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2196078598499298, 0.9921569228172302, 0.9921569228172302, 0.21568629145622253, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2196078598499298, 0.9921569228172302, 0.9921569228172302, 0.21568629145622253, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3294117748737335, 0.9921569228172302, 0.9921569228172302, 0.21568629145622253, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.7058823704719543, 0.9921569228172302, 0.9254902601242065, 0.16470588743686676, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.7058823704719543, 0.9921569228172302, 0.7254902124404907, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.7058823704719543, 0.9921569228172302, 0.7254902124404907, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.7058823704719543, 0.9921569228172302, 0.7254902124404907, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.7058823704719543, 0.9921569228172302, 0.7254902124404907, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.7058823704719543, 0.9921569228172302, 0.7254902124404907, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.7058823704719543, 0.9921569228172302, 0.2980392277240753, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.7058823704719543, 0.9921569228172302, 0.2392157018184662, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.7058823704719543, 0.9921569228172302, 0.2392157018184662, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.7058823704719543, 0.8784314393997192, 0.12941177189350128, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.7058823704719543, 0.7490196228027344, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]}]}]}

上面的参数是从测试集中随机选取的手写数字输入,代表了数字1,转换成图片如下图所示。

nunber1.png

点击开始调试,可以看到调试结果是一个长度为10的置信度数组,其中第二个标签的置信度最高。手写数字MNIST数据集的标签为0-9,所以预测结果为1,预测是正确的。

13-infer.png

至此,我们一起使用Infinite完成了手写数字识别,您大致对Infinite平台的操作方法有了大体的认识,更多教程请前往操作指南