基于MindSpore Lite端侧框架的图像分类应用的全流程体验
有幸参加了MindSpore 21天实战营,本篇其实是实战营的第一堂课,作业体验相对简单,指导老师何芦微。但因为我之前参加过MindSpore2日集训营,之前略微有些基础,已经不满足于单纯跑通或者完成作业了,想要来点更深入的体验,于是尝试走通全过程。在此过程中几度遭遇波折,在某些关键点,我遇到的难度远超我能力。尝试的念头几近放弃,本文也迟迟未成文。幸得高手指点,我才完成了全流程的体验,也才有了本文的发表。
接下来就是基于MindSpore Lite端侧框架的移动端图像分类应用的全流程体验 ,请高手指正,也希望本文能成为不具备GPU硬件的小伙伴体验的参考。
体验的流程主要记录为四个部分:
“一个艰难的开始”——Docker方式下CPU模式训练Mobilenetv2
“步入正途”——Docker方式下CPU模式增量训练Mobilenetv2
“修成正果”——Mslite生成android手机APP
“竖扫物体”——手机物体检测APP扫描体验
[Docker方式下CPU模式训练Mobilenetv2]
首先,对小白来讲要拿到Mobilenetv2的代码,高手飞过。对代码进行组织、除错和训练,这是开发的过程。其实,课上就被告知,代码可以在GPU或者Ascend环境去训练。但个人的本本是没有配nvdia GPU的,这就有些尴尬了。听大家在群里讲WSL+Docker,我除了了解一下外并无感兴趣的基础。相反,之前在MindSpore 2日集训营使用过本地CPU跑通Lenet模型的经历,让我十分有勇气相信可以尝试Docker+CPU环境,我觉得应该是能跑通的,以往都是可以修改代码嘛。这个我懂!!!
1、Docker 安装mindspore-cpu:0.7.0-beta环境;
1.1 管理员方式运行Microsoft PowerShell;
1.2 执行docker pull mindspore/mindspore-cpu:0.7.0-beta获取mindspore 0.7.0 cpu beta版本image文件;
1.3 执行docker run -it -v /c/test:/mslite mindspore/mindspore-cpu:0.7.0-beta /bin/bash运行mindspore-cpu:0.7.0-beta容器环境;并在windows下C盘根目录建立test文件夹,该文件夹与docker内mslite文件夹具有通用存储空间。
2、mindspore-cpu:0.7.0-beta容器环境下,获取github下mindspore/mindspore-21-days-tutorials/chapter1/mobilenetv2主仓文件;
2.1 执行git config --global user.name "Ming_Empty",设置作者信息;
2.2执行git config --global user.email "summyflyer@163.com",设置作者信息;
2.3 在./mslite目录下执行git init,初始化仓库;
2.4执行git clone https://github.com/mindspore-ai/mindspore-21-days-tutorials.git获取mobilenetv2主仓文件;
进入/mindspore-21-days-tutorials/chapter1#目录,执行复制命令cp -r mobilenetv2 /mslite,将mobilenetv2文件夹复制到我设置的工作目录./mslite目录下。
3、下载CIFAR-10 phython version (suitable for Python programs)并解压、拷贝至程序对应路径。
3.1 下载完成后解压缩;
3.2 在mslite目录下执行mkdir –p /mslite/data/train和mkdir –p /mslite/data/eval,新建train和eval两个文件夹,准备填充训练和测试数据;将5个训练数据集copy到/mslite/data/train目录中;将1个训练数据集copy到/mslite/data/eval目录中。
Ps:因为本次运行container时,将c:\test目录跟容器内\mslite目录做了挂载操作,所以,copy文件就可以在windows下直接常规操作了。解压也是如此。
3.3 执行git add mindspore-ai/,将mslite目录添加到仓库;
3.4 执行 git commit -m提交更改;
3.5 执行 git branch,可见对应的”master”主干;执行 git branch mobilenet_v2,新建mobilenet_v2的分支;执行 git checkout mobilenet_v2切换到mobilenet_v2分支;
Ps:在此执行3.3-3.5步,因为数据集基本操作完成,在此提交,有利于程序修改版本的维护!
4、使用vscode在windows环境下对args.py中训练模式进行修改;
-
错误信息:
路径
文件
v
原因:
硬件无GPU,默认训练的模式值由“GPU”更改为“CPU”;
./mobilenetv2/src/
Args.py
Line31
parser.add_argument('--platform', type=str, default="GPU", choices=("CPU", "GPU", "Ascend"), help='run platform, only support CPU, GPU and Ascend')
parser.add_argument('--platform', type=str, default="CPU", choices=("CPU", "GPU", "Ascend"), help='run platform, only support CPU, GPU and Ascend')
结果
OK!
5、执行python train.py进行训练时,遇到了几个错误,记录如下:
-
错误信息:
ImportError: cannot import name 'set_seed' from 'mindspore.common'
路径
文件
v
原因:
本段程序是基于MindSpore_r1.0.0,而我运行的版本是MindSpore_r0.7.0beta,两者set_seed所调用的位置是不同的。
./mobilenetv2/
train.py
Line31
from mindspore.common import set_seed
import mindspore.dataset as ds
Line41
set_seed(1)
ds.config.set_seed(1)
结果
OK!
-
错误信息:
AttributeError: 'ParameterTensor' object has no attribute 'set_data'
路径
文件
v
原因:
本段程序是基于MindSpore_r1.0.0,而运行的版本是MindSpore_r0.7.0beta,两者set_data方法及所调用的位置是不同的。
./mobilenetv2/src/
mobilenetV2.py
Line215
m.weight.set_data
m.weight.set_parameter_data
Line218
m.bias.set_data
m.bias.set_parameter_data
Line221
m.gamma.set_data
m.gamma.set_parameter_data
Line223
m.beta.set_data
m.beta.set_parameter_data
Line281
m.weight.set_data
m.weight.set_parameter_data
Line284
m.bias.set_data
m.bias.set_parameter_data
结果
OK!
-
错误信息:
ValueError: num_parallel_workers exceeds the boundary between 1 and 2!
路径
文件
v
原因:
并行数目超出>2
./mobilenetv2/src/
dataset.py
Line56
ds = de.Cifar10Dataset(dataset_path, num_parallel_workers=8, shuffle=do_shuffle)
ds = de.Cifar10Dataset(dataset_path, num_parallel_workers=1, shuffle=do_shuffle)
结果
OK!
-
错误信息:
RuntimeError: Currently dataset sink mode is not supported when the device target is CPU.
路径
文件
v
原因:
数据下沉模式是针对asic芯片做的优化 默认是开启的,CPU不支持这种模式。CPU is not supported when dataset_sink_mode is true. If dataset_sink_mode is True, data will be sent to device.
./mobilenetv2/
train.py
Line44
if args_opt.platform =="CPU":
args_opt.dataset_sink_mode = False
Line91
model.train(epoch_size, dataset, callbacks=cb)
model.train(epoch_size, dataset, callbacks=cb,dataset_sink_mode=args_opt.dataset_sink_mode)
结果
OK!
在老师的指导下,处理完显性错误,训练时停滞几分钟并输出killed,走到这一步基本就没思路了。后来安装了mindspore-cpu:r1.0.0,重新开始,处理完显性错误,跟之前是一样的,训练时停滞几分钟并输出killed。这时,我意识到自己挖了一个大坑......老师也是建议可以做CPU增量训练......
直到后来检查batch_size值过大,改为15,之后又输出了一个错误。
-
错误信息:
停滞并输出killed
路径
文件
v
原因:
batch_size=150,此值过大
./mobilenetv2/src/
config.py
28
batch_size": 150
batch_size": 15
结果
OK!
-
错误信息:
[WARN]Not registered CPU kernel:op[Tile]
路径
文件
v
原因:
查阅Tile算子,目前其对CPU是不支持的。也就是说Docker跑mindspore-cpu这条路是走不通的,除非去改底层算子。
结果
Failed!
请教大神并查阅Tile算子,认为Docker容器中用CPU这条路是跑不通了,认定方向走CPU增量训练的方式!
[Docker方式下CPU模式增量训练Mobilenetv2]*官方教程
代码:Gitee例仓 ./model_zoo/cv/mobilenetv2
1、下载checkpoint文件
查看目录及文件,其中没有预训练完成的checkpoint文件。用户需要根据不同处理器种类下载CPU/GPU预训练模型或下载Ascend预训练模型到以下目录:./pretrain_checkpoint/
Ps:此处需要下载的是CPU训练适用的预训练模型。
在代码目录中建立路径:
mkdir pretrain_checkpoint
下载预训练完成的文件mobilenetv2_cpu_gpu.ckpt:
wget -P ./pretrain_checkpoint https://download.mindspore.cn/model_zoo/official/lite/mobilenetv2_openimage_lite/mobilenetv2_cpu_gpu.ckpt
2、准备数据
准备ImageFolder格式管理的数据集,运行run_train.sh时加入[dataset_path]参数,运行train.py时加入--dataset_path [dataset_path]参数:
数据集结构如下:
└─ImageFolder
├─train
│ class1Folder
│ class2Folder
│ ......
└─eval
class1Folder
class2Folder
......
因为下载的cifar-10数据集为非文件目录的,需要转换。可以编写python转换程序进行转换。代码及cifar-10数据集在例仓中./mobilenetv2/data/目录中。
3、开始增量训练
python train.py --platform CPU --dataset_path ./data/train/ --pretrain_ckpt ./pretrain_checkpoint/mobilenetv2_cpu_gpu.ckpt --freeze_layer backbone
4、错误处理:
-
错误信息:
ValueError: num_parallel_workers exceeds the boundary between 1 and 2!
路径
文件
v
原因:
并行运算数目超过1
./mobilenetv2/src/
dataset.py
Line61
ds = de.ImageFolderDataset(dataset_path, num_parallel_workers=8, shuffle=True)
ds = de.ImageFolderDataset(dataset_path, num_parallel_workers=1, shuffle=True)
Line86
ds = ds.map(operations=trans, input_columns="image", num_parallel_workers=8)
ds = ds.map(operations=trans, input_columns="image", num_parallel_workers=1)
Line87
ds = ds.map(operations=type_cast_op, input_columns="label", num_parallel_workers=8)
ds = ds.map(operations=type_cast_op, input_columns="label", num_parallel_workers=1)
结果
OK!
-
错误信息:
停滞并输出killed
路径
文件
v
原因:
batch_size=150,此值过大
./mobilenetv2/src/
config.py
Line28
batch_size": 150
batch_size": 15
结果
OK!
-
错误信息:
AttributeError:’EasyDict’ object has no attribute ‘run_distribute’
路径
文件
v
原因:
参数缺少run_distribute项
./mobilenetv2/src/
config.py
Line43
"run_distribute": args.run_distribute,
结果
OK!
终于…...程序输出打印batch信息……
经过漫长的等待,最终在./ckpt_0目录下生成了15个.ckpt文件。
5、测试
python eval.py --platform CPU --dataset_path ./data/test --pretrain_ckpt ./ckpt_0/mobilenetv2_15.ckpt
精度尚可~~~
6、模型转出
python export.py –platform CPU –pretrain_ckpt ./ckpt_0/mobilenetv2_15.ckpt
7、使用convert_lite离线转换工具,生成端侧模型.ms文件
执行bash build.sh -I X86_64 -j4 得到转换所需的conver_lite工具。
使用mindspore lite离线工具convert_lite工具,将生成的.mindir模型转换成 MindSpore Lite端侧使用的.ms模型文件。
一行命令解决问题:./convert_lite --fmk =MINDIR --modelFile=mobilenetv2-10_1562.mindir
[Mslite生成android手机APP]
参考教程链接:https://gitee.com/mindspore/mindspore/tree/master/model_zoo/official/lite/object_detection 基本参考本教程,在此不复赘述!
[手机物体检测APP扫描体验]
通过本堂课的学习,使我们了解了作为端侧APP使能AI的基本流程,对日后的学习和应用大有裨益。部分地方尚需深入学习!
-------------------------------------------------------------End----------------------------------------------------------------------
- 点赞
- 收藏
- 关注作者
评论(0)