*发布者(Publisher)**:Huawei
应用领域(Application Domain):Image Classification
版本(Version):0.1
修改时间(Modified):2021.09.14
大小(Size):141.32 MB (air)/28.69 MB (ckpt)/75.44 MB (om)
框架(Framework):MindSpore_1.1.0
模型格式(Model Format):air/ckpt/om
精度(Precision):Mixed/FP16
处理器(Processor):昇腾910/昇腾310
应用级别(Categories):Released
概述
简述
SSD将边界框的输出空间离散为一组默认框,每个特征地图位置的纵横比和比例不同。在预测时,网络为每个默认框中每个对象类别生成分数,并对该框进行调整,以更好地匹配对象形状。此外,该网络结合了来自不同分辨率的多个特征图的预测,从而自然地处理不同尺寸的物体。
- 参考论文:Wei Liu, Dragomir Anguelov, Dumitru Erhan, Christian Szegedy, Scott Reed, Cheng-Yang Fu, Alexander C. Berg.European Conference on Computer Vision (ECCV), 2016 (In press).
- 参考实现:model_zoo/research/cv/ssd_resnet50 · MindSpore/mindspore - 码云 - 开源中国 (gitee.com)
通过Git获取对应commit_id的代码方法如下:
git clone {repository_url} # 克隆仓库的代码
cd {repository_name} # 切换到模型的代码仓目录
git checkout {branch} # 切换到对应分支
git reset --hard {commit_id} # 代码设置到对应的commit_id
cd {code_path} # 切换到模型代码所在路径,若仓库下只有该模型,则无需切换
准备工作
推理环境准备
-
硬件环境、开发环境和运行环境准备请参见《CANN 软件安装指南》。
-
宿主机上需要安装Docker并登录Ascend Hub中心获取镜像。
当前模型支持的镜像列表如下表所示。
表 1 镜像列表
镜像名称 镜像版本 配套CANN版本 ARM/x86架构:infer-modelzoo 21.0.2 5.0.2
源码介绍
/home/HwHiAiUser/ssdResnet50_for_mindspore_{version}_code #代码示例中不体现具体版本号,用{version}代替
├── infer # MindX高性能预训练模型新增
│ ├── convert # 转换om模型命令,AIPP
│ │ ├──aipp.cfg
│ │ └──convert_om.sh
│ ├── mxbase # 基于mxbase推理
│ │ ├── C++
│ │ │ ├──CMakeLists.txt
│ │ │ ├──ResNet50.cpp
│ │ │ ├──run.sh
│ │ │ ├──ResNet50Base.cpp
│ │ │ └──SSDResNet50.h
│ │ └── models
│ │ └── coco.names
│ └── sdk # 基于sdk.run包推理;
│ │ ├── conf
│ │ │ ├──coco.names
│ │ │ ├──sdk_infer_env.rc
│ │ │ ├──ssd_mobilenet_v1_fpn_ms_on_coco_postprocess.cfg
│ │ │ └──ssd-resnet50.pipeline
│ │ ├── perf # 精度验证脚本
│ │ │ ├──generate_map_report.py
│ │ │ └──run_map_test.sh
│ │ ├── infer_by_sdk.py
│ │ └── run.sh
推理
准备容器环境
-
下载源码包。单击“下载模型脚本”和“下载模型”,下载所需软件包。
-
下载模型脚本:下载训练和推理的脚本文件。
-
下载模型:下载模型文件。
-
-
将源码上传至推理服务器任意目录并解压(如:“/home/HwHiAiUser“)。
-
下载MindX SDK开发套件(mxVersion)。
-
配套版本:2.0.1
-
编译镜像。
docker build -t infer_image **–build-arg FROM_IMAGE_NAME=**base_image:tag --build-arg SDK_PKG=sdk_pkg .
表 1 参数说明
参数 说明 infer_image 推理镜像名称,根据实际写入。 base_image 基础镜像,可从Ascend Hub上下载。 tag 镜像tag,请根据实际配置,如:21.0.1。 sdk_pkg 下载的mxManufacture包名称,如Ascend-mindxsdk-mxmanufacture_{version}_linux-{arch}.run。 说明:
不要遗漏命令结尾的“.“。 -
准备数据。
由于后续推理均在容器中进行,因此需要把用于推理的图片、数据集、模型文件、代码等均放在同一数据路径中,后续示例将以 “/home/test” 为例。
/home/test ├── coco2017 # 用于精度测试的数据集 │ └── annotations │ └── val2017 ├── SSDResnet50_MindSpore_{version}_code # 训练代码 ├── SSDResnet50_MindSpore_{version}_code.zip # 模型训练代码包 ├── SSDResnet50_MindSpore_{version}_model.zip # 下载的相关模型文件,其中包含了AIR文件 └── SSDResnet50.air # 用于模型转换的AIR文件
-
启动容器。
bash docker_start_infer.sh infer_image data_path
表 2 参数说明
参数
说明
infer_image
推理镜像名称,根据实际写入。
data_path
数据路径。如:“/home/HwHiAiUser”。
模型转换
-
模型转换的相关文件在SSDResnet50_MindSpore_{version}_code/infer/convert目录下。
-
准备AIPP配置文件。
AIPP需要配置aipp.cfg文件,在ATC转换的过程中插入AIPP算子,即可与DVPP处理后的数据无缝对接,AIPP参数配置请参见《CANN 开发辅助工具指南 (推理)》中“ATC工具使用指南”。
aipp.config
aipp_op {
aipp_mode: static
input_format : RGB888_U8
csc_switch : false
rbuv_swap_switch : true
mean_chn_0 : 124
mean_chn_1 : 117
mean_chn_2 : 104
var_reci_chn_0 : 0.0171247538316637
var_reci_chn_1 : 0.0175070028011204
var_reci_chn_2 : 0.0174291938997821
} -
执行以下命令,进行模型的转换。
输出om模型供后续推理使用。
dos2unix convert_om.sh(根据实际情况可选) bash convert_om.sh air_path om_path aipp_cfg_path
解释说明: 如果遇到类似这样的报错 convert_om.sh: line 2: $'\r': command not found 原因是诸如Linux和Windows之类的不同操作系统具有互不兼容的不同文本文件格式导致的报错,需要额外执行 dos2unix convert_om.sh 目的是为了对格式进行转换。后面遇到类似的问题同理。
参数说明: * air_path:转换脚本AIR文件路径。 * om_path:生成的OM文件名,转换脚本会在此基础上添加.om后缀。 * aipp_cfg_path:AIPP配置文件路径。
mxBase推理
-
运行推理
cd /home/test/ssd_resnet50/infer/mxbase/C++/ dos2unix run.sh(根据实际可选) bash run.sh
-
(可选)修改配置文件。
可根据实际情况修改,配置文件位于 “mxbase/C++/ResNet50_main.cpp” 中,可修改参数如下。
若使用迁移学习生成的模型进行推理,请修改CLASS_NUM为迁移学习训练任务数据集的类别数量。如:修改CLASS_NUM=10。... namespace { const uint32_t CLASS_NUM = 81; } ...
-
观察结果。
屏幕会打印推理结果,包括类别、置信度和检测框。推理结果示例如下所示。
... I0914 13:01:01.801380 237801 MxStreamManager.cpp:383] Creates stream(detection) successfully. I0914 13:01:01.801421 237801 MxStreamManager.cpp:433] Creates streams successfully. I0914 13:01:01.961447 237801 main.cpp:130] Results:{"MxpiObject":[{"classVec":[{"classId":1,"className":"person","confidence":0.77915155899999999,"headerVec":[]}],"x0":163.613495,"x1":471.30764799999997,"y0":122.42448400000001,"y1":628.58148200000005},{"classVec":[{"classId":1,"className":"person","confidence":0.43741989100000001,"headerVec":[]}],"x0":0,"x1":52.373420699999997,"y0":188.82562300000001,"y1":542.87927200000001} ...
MindX SDK推理
-
(可选)修改配置文件。
配置文件ssd_mobilenet_v1_fpn_ms_on_coco_postprocess.cfg内容如下。
CLASS_NUM=81
SCORE_THRESH=0.1
IOU_THRESH=0.6
CHECK_MODEL=true
-
进入“./infer/sdk/conf/”目录。
根据实际情况修改ssd-resnet50.pipeline文件中图片规格、模型路径、配置文件路径和标签路径。更多介绍请参见《mxVerison 用户指南》中“基础开发”章节。
ssd-resnet50.pipeline
{
"detection": {
"stream_config": {
"deviceId": "0"
},
"appsrc0": {
"props": {
"blocksize": "409600"
},
"factory": "appsrc",
"next": "mxpi_imagedecoder0"
},
"mxpi_imagedecoder0": {
"props": {
"handleMethod": "opencv"
},
"factory": "mxpi_imagedecoder",
"next": "mxpi_imageresize0"
},
"mxpi_imageresize0": {
"props": {
"parentName": "mxpi_imagedecoder0",
"handleMethod": "opencv",
"resizeHeight": "640",
"resizeWidth": "640",
"resizeType": "Resizer_Stretch"
},
"factory": "mxpi_imageresize",
"next": "mxpi_tensorinfer0"
},
"mxpi_tensorinfer0": {
"props": {
"waitingTime": "3000",
"dataSource": "mxpi_imageresize0",
"modelPath": "/home/test/ssd_resnet50/ssd_resnet50.om"
},
"factory": "mxpi_tensorinfer",
"next": "mxpi_objectpostprocessor0"
},
"mxpi_objectpostprocessor0": {
"props": {
"dataSource": "mxpi_tensorinfer0",
"postProcessConfigPath": "/home/test/ssd_resnet50/infer/sdk/conf/ssd_mobilenet_v1_fpn_ms_on_coco_postprocess.cfg",
"labelPath": "/home/test/ssd_resnet50/infer/sdk/conf/coco.names",
"postProcessLibPath": "/home/test/ssd_resnet50/infer/sdk/conf/libSsdMobilenetFpn_MindsporePost.so"
},
"factory": "mxpi_objectpostprocessor",
"next": "mxpi_dataserialize0"
},
"mxpi_dataserialize0": {
"props": {
"outputDataKeys": "mxpi_objectpostprocessor0"
},
"factory": "mxpi_dataserialize",
"next": "appsink0"
},
"appsink0": {
"factory": "appsink"
}
}
}
参数说明:
- resizeHeight:模型高度,请根据模型的实际尺寸输入。
- resizeWidth:模型宽度,请根据模型的实际尺寸输入。
- modelPath:模型路径,请根据模型实际路径修改。
- postProcessLibPath:模型后处理路径,请根据模型后处理生成出来的实际路径修改。
- labelPath:标签文件路径,请根据标签文件的实际路径修改。
-
运行推理服务。
请参见《mxVersion用户指南》中的“使用命令行方式开发 > 样例介绍 > Python运行步骤”章节。
a. 可以自行准备jpg格式的图片或者图片文件夹用于推理。
b. 进入“/home/test/ssd_resnet/infer/sdk”目录,执行推理命令。
dos2unix run.sh (根据实际可选)
bash run.sh --pipeline_path pipeline_path --stream_name stream_name --img_path img_path --res_path res_path
参数说明:
- pipeline_path:pipeline路径。
- stream_name:业务流名称。
- img_path:图片路径
- res_path: 文件输出路径
运行结果如下所示。
...
I0915 12:40:26.508781 32568 ModelInferenceProcessor.cpp:33] Begin to ModelInferenceProcessor init
I0915 12:40:26.962060 32568 ModelInferenceProcessor.cpp:77] End to ModelInferenceProcessor init
I0915 12:40:26.962270 32568 SsdMobilenetFpn_MindsporePost.cpp:99] Start to Init SsdMobilenetFpn_MindsporePost.
I0915 12:40:26.962281 32568 ObjectPostProcessBase.cpp:65] Start to init ObjectPostProcessBase.
I0915 12:40:26.962286 32568 PostProcessBase.cpp:78] Start to LoadConfigDataAndLabelMap in PostProcessBase.
I0915 12:40:26.975507 32568 ResNet50Base.cpp:165] image shape, size=640,480.
I0915 12:40:26.977247 32568 ResNet50Base.cpp:103] image size after crop640 640
I0915 12:40:27.045590 32568 ResNet50Base.cpp:188] Inference success, ret=0.
I0915 12:40:27.045634 32568 SsdMobilenetFpn_MindsporePost.cpp:240] Start to Process SsdMobilenetFpn_MindsporePost.
I0915 12:40:27.063215 32568 SsdMobilenetFpn_MindsporePost.cpp:186] SsdMobilenetFpn_MindsporePost start to write results.
I0915 12:40:27.063282 32568 PostProcessBase.cpp:134] GetBuffer with index(0) points to address:0x55e62f03da00
I0915 12:40:27.063302 32568 PostProcessBase.cpp:134] GetBuffer with index(0) points to address:0x7f6c6b031010
I0915 12:40:27.112032 32568 SsdMobilenetFpn_MindsporePost.cpp:224] SsdMobilenetFpn_MindsporePost write results successed.
I0915 12:40:27.112078 32568 SsdMobilenetFpn_MindsporePost.cpp:250] End to Process SsdMobilenetFpn_MindsporePost.
I0915 12:40:27.112087 32568 ResNet50Base.cpp:218] BBox[0]:[x0=51.5515, y0=30.3666, x1=204.198, y1=166.661], confidence=0.620606, classId=63, className=tv
I0915 12:40:27.371014 32568 DeviceManager.cpp:90] DestroyDevices begin
I0915 12:40:27.371062 32568 DeviceManager.cpp:92] destory device:0
I0915 12:40:28.128180 32568 DeviceManager.cpp:98] aclrtDestroyContext successfully!
I0915 12:40:28.792654 32568 DeviceManager.cpp:106] DestroyDevices successfully
...
- 执行精度测试。
cd /home/test/ssd_resnet50/infer/sdk/perf/
dos2unix run_map_test.sh (根据实际可选)
bash run_map_test.sh annotations_json det_result_json output_path_name
精度测试脚本generate_map_report.py参数说明:
- annotations_json:数据集标注文件路径。
- det_result_json:执行推理测试生成的结果文件。
- output_path_name:精度文件路径。
iii. 查看推理精度结果。
Average Precision (AP) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.321
Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=100 ] = 0.475
Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=100 ] = 0.350
Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.108
Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.342
Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.457
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 1 ] = 0.309
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 10 ] = 0.479
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.503
Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.197
Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.551
Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.687
在ModelArts上应用
创建OBS桶
需要创建OBS桶并上传文件(包括数据集、脚本和模型),并在该桶中新建文件夹夹存放训练日志目录、训练生成的ckpt和air模型。
-
创建桶。
点击“创建桶”,“存储类别”类别选择“标准存储”,“桶ACL”选择“私有”,“多AZ”选择“开启”。
-
创建文件夹存放数据。
在桶中创建文件夹存放数据。
目录结构:
/桶/ ├── code # 存放训练脚本目录 ├── dataset # 存放训练数据集和模型权重文件目录 │ └── coco # 存放数据集 ├── logs # 存放训练日志目录 └── output # 训练生成ckpt和air模型目录
创建训练作业
描述要点(key):指导用户在ModelArts上创建训练作业,提供训练参数配置说明
-
登录ModelArts。
利用提供的华为云账号和密码登录华为云官网,在服务列表中选择ModelArts。
-
创建训练作业。
a. 在创建训练作业之前,需要先创建训练算法。
-
输入训练算法的名称。
-
选择“自定义脚本”,创建方式如下所示。
-
输入、输出数据配置如下。
b. 点击“创建训练作业”,输入训练作业的名称,选择算法。训练输入为训练数据集,训练输出为output文件夹用来保存ckpt文件、air文件、训练日志保存文件。
表 1 参数说明
参数名称 说明 AI引擎 Ascend-Powered-Engine,mindspore_1.3.0-cann_5.0.2 代码目录 算法代码存储的OBS路径。上传训练脚本,如:/obs桶/mindspore-dataset/code/ 启动文件 启动文件:启动训练的python脚本,如:/obs桶/mindspore-dataset/code/start.py须知:需要把modelArts/目录下的start.py启动脚本拷贝到根目录下。 输入数据配置 代码路径参数:data_dir 输出数据配置 代码路径参数:train_url c. 点击提交,待训练结束后,查看训练任务日志。
-
查看训练任务日志
在ModelArts的训练作业列表中选择对应的训练作业名称,界面右侧为训练任务日志。
冻结模型
-
训练生成ckpt。
通过创建训练作业进行训练得到ckpt文件。
-
将ckpt导出成air。
在ModelArts上完成训练后得到对应air模型。