失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > PPYOLO垃圾检测+地平线旭日X3派部署(下)

PPYOLO垃圾检测+地平线旭日X3派部署(下)

时间:2019-03-27 01:43:12

相关推荐

PPYOLO垃圾检测+地平线旭日X3派部署(下)

请点击此处查看本环境基本用法.

Please click here for more detailed instructions.

1. 简介

在上一个教程中,我们介绍了如何利用百度PaddlePaddle中的PPYOLO模型训练垃圾检测模型,并导出了ppyolo.onnx模型。但仅利用onnx模型无法直接部署到地平线旭日X3派上,我们将拆分为模型转换和上版部署两个部分。

整体流程图:

1. 模型转换

1.1 地平线AI芯片工具链环境搭建

参考地平线AI工具链官方教程:

https://developer.horizon.ai/api/v1/fileData/documents_pi/ai_toolchain_develop/horizon_ai_toolchain_user_guide/chapter_2_prerequisites.html

1.2 模型转换

在上一篇教程中,我们获得了paddlepaddle 转换后得到的onnx模型,需要转化地平线交叉编译模型(.bin)。接下来利用地平线AI芯片工具链进行模型转换检测,确认是否所有运算均在BPU上运行。在

地平线AI芯片工具链docker中执行命令:

hb_mapper checker --model-type onnx --march bernoulli2 --model ppyolo.onnx

验证后打印log日志如下:

可以看到所有算子均支持在BPU下运行,下一步进行模型转换。

-10-08 15:48:34,726 file: hb_mapper.py func: hb_mapper line No: 73 Start hb_mapper....-10-08 15:48:34,726 file: hb_mapper.py func: hb_mapper line No: 74 log will be stored in /mnt/trash_det/ppyolo/hb_mapper_checker.log-10-08 15:48:34,727 file: hb_mapper.py func: hb_mapper line No: 75 hbdk version 3.31.1-10-08 15:48:34,727 file: hb_mapper.py func: hb_mapper line No: 76 horizon_nn version 0.13.9-10-08 15:48:34,727 file: hb_mapper.py func: hb_mapper line No: 77 hb_mapper version 1.8.7-10-08 15:48:34,768 file: helper.py func: helper line No: 124 Model input names: ['image']-10-08 15:48:34,770 file: hb_mapper_checker.py func: hb_mapper_checker line No: 104 Model type: onnx-10-08 15:48:34,770 file: hb_mapper_checker.py func: hb_mapper_checker line No: 105 march: bernoulli2-10-08 15:48:34,770 file: hb_mapper_checker.py func: hb_mapper_checker line No: 110 input names []-10-08 15:48:34,770 file: hb_mapper_checker.py func: hb_mapper_checker line No: 111 input shapes {}-10-08 15:48:34,770 file: hb_mapper_checker.py func: hb_mapper_checker line No: 117 Begin model checking....-10-08 15:48:34,770 file: build.py func: build line No: 36 [Sat Oct 8 15:48:34 ] Start to Horizon NN Model Convert.-10-08 15:48:34,771 file: dict_parser.py func: dict_parser line No: 28 The input parameter is not specified, convert with default parameters.-10-08 15:48:34,771 file: dict_parser.py func: dict_parser line No: 518 Parsing the hbdk parameter:{'hbdk_pass_through_params': '--O0'}-10-08 15:48:34,771 file: build.py func: build line No: 144 HorizonNN version: 0.13.9-10-08 15:48:34,771 file: build.py func: build line No: 148 HBDK version: 3.31.1-10-08 15:48:34,771 file: build.py func: build line No: 36 [Sat Oct 8 15:48:34 ] Start to parse the onnx model.-10-08 15:48:34,810 file: onnx_parser.py func: onnx_parser line No: 191 Input ONNX model infomation:ONNX IR version:6Opset version: 11Producer: PaddlePaddleDomain: noneInput name:image, [1, 3, 416, 416]Output name: ..._1.tmp_0, [1, 13, 13, 18]Output name: ..._3.tmp_0, [1, 26, 26, 18]-10-08 15:48:35,109 file: build.py func: build line No: 39 [Sat Oct 8 15:48:35 ] End to parse the onnx model.-10-08 15:48:35,111 file: build.py func: build line No: 280 Model input names: ['image']-10-08 15:48:35,158 file: build.py func: build line No: 542 Saving the original float model: ./.hb_check/original_float_model.onnx.-10-08 15:48:35,158 file: build.py func: build line No: 36 [Sat Oct 8 15:48:35 ] Start to optimize the model.-10-08 15:48:36,842 file: build.py func: build line No: 39 [Sat Oct 8 15:48:36 ] End to optimize the model.-10-08 15:48:36,881 file: build.py func: build line No: 558 Saving the optimized model: ./.hb_check/optimized_float_model.onnx.-10-08 15:48:36,881 file: build.py func: build line No: 36 [Sat Oct 8 15:48:36 ] Start to calibrate the model.-10-08 15:48:36,885 file: calibration_data_set.py func: calibration_data_set line No: 67 There are 1 samples in the calibration data set.-10-08 15:48:37,889 file: max_calibrater.py func: max_calibrater line No: 68 Run calibration model with max method.-10-08 15:48:38,853 file: build.py func: build line No: 39 [Sat Oct 8 15:48:38 ] End to calibrate the model.-10-08 15:48:38,853 file: build.py func: build line No: 36 [Sat Oct 8 15:48:38 ] Start to quantize the model.-10-08 15:48:41,097 file: build.py func: build line No: 39 [Sat Oct 8 15:48:41 ] End to quantize the model.-10-08 15:48:41,590 file: build.py func: build line No: 572 Saving the quantized model: ./.hb_check/quantized_model.onnx.-10-08 15:48:43,095 file: build.py func: build line No: 36 [Sat Oct 8 15:48:43 ] Start to compile the model with march bernoulli2.-10-08 15:48:43,767 file: hybrid_build.py func: hybrid_build line No: 123 Compile submodel: paddle-onnx_subgraph_0-10-08 15:48:44,808 file: hbdk_cc.py func: hbdk_cc line No: 95 hbdk-cc parameters:['--O0', '--input-layout', 'NHWC', '--output-layout', 'NHWC']-10-08 15:48:44,809 file: hbdk_cc.py func: hbdk_cc line No: 96 hbdk-cc command used:hbdk-cc -f hbir -m /tmp/tmph6o754nd/paddle-onnx_subgraph_0.bin -o /tmp/tmph6o754nd/paddle-onnx_subgraph_0.hbm --march bernoulli2 --progressbar --O0 --input-layout NHWC --output-layout NHWC-10-08 15:48:45,451 file: build.py func: build line No: 39 [Sat Oct 8 15:48:45 ] End to compile the model with march bernoulli2.-10-08 15:48:45,452 file: node_info.py func: node_info line No: 54 The converted model node information:========================================================Node ON Subgraph Type ---------------------------------------------------------Conv_0 BPU id(0)HzSQuantizedConv Conv_1 BPU id(0)HzSQuantizedConv Conv_2 BPU id(0)HzSQuantizedConv MaxPool_0BPU id(0)HzQuantizedMaxPool Conv_3 BPU id(0)HzSQuantizedConv Conv_4 BPU id(0)HzSQuantizedConv Conv_5 BPU id(0)HzSQuantizedConv Conv_6 BPU id(0)HzSQuantizedConv Conv_7 BPU id(0)HzSQuantizedConv Conv_8 BPU id(0)HzSQuantizedConv Conv_9 BPU id(0)HzSQuantizedConv AveragePool_0 BPU id(0)HzSQuantizedConv Conv_10 BPU id(0)HzSQuantizedConv Conv_11 BPU id(0)HzSQuantizedConv Conv_12 BPU id(0)HzSQuantizedConv Conv_13 BPU id(0)HzSQuantizedConv Conv_14 BPU id(0)HzSQuantizedConv AveragePool_1 BPU id(0)HzSQuantizedConv Conv_15 BPU id(0)HzSQuantizedConv Conv_16 BPU id(0)HzSQuantizedConv Conv_17 BPU id(0)HzSQuantizedConv Conv_18 BPU id(0)HzSQuantizedConv Conv_19 BPU id(0)HzSQuantizedConv AveragePool_2 BPU id(0)HzSQuantizedConv Conv_20 BPU id(0)HzSQuantizedConv Conv_21 BPU id(0)HzSQuantizedConv Conv_22 BPU id(0)HzSQuantizedConv Conv_23 BPU id(0)HzSQuantizedConv LeakyRelu_0 BPU id(0)HzLeakyReluConv_24 BPU id(0)HzSQuantizedConv LeakyRelu_1 BPU id(0)HzLeakyReluConv_25 BPU id(0)HzSQuantizedConv LeakyRelu_2 BPU id(0)HzLeakyReluResize_0 BPU id(0)HzQuantizedResizeUpsample Concat_0 BPU id(0)Concat Conv_26 BPU id(0)HzSQuantizedConv LeakyRelu_3 BPU id(0)HzLeakyReluConv_27 BPU id(0)HzSQuantizedConv LeakyRelu_4 BPU id(0)HzLeakyReluConv_28 BPU id(0)HzSQuantizedConv Conv_29 BPU id(0)HzSQuantizedConv-10-08 15:48:45,452 file: build.py func: build line No: 39 [Sat Oct 8 15:48:45 ] End to Horizon NN Model Convert.-10-08 15:48:45,456 file: onnx2horizonrt.py func: onnx2horizonrt line No: 3854 ONNX model output num : 2-10-08 15:48:45,473 file: hb_mapper_checker.py func: hb_mapper_checker line No: 141 End model checking....

1.3 模型转换

首先设置工具链转换的配置文件config.yaml

# 模型转化相关的参数model_parameters:# onnx浮点网络数据模型文件onnx_model: 'ppyolo.onnx'# 适用BPU架构march: "bernoulli2"# 指定模型转换过程中是否输出各层的中间结果,如果为True,则输出所有层的中间输出结果,layer_out_dump: False# 日志文件的输出控制参数,# debug输出模型转换的详细信息# info只输出关键信息# warn输出警告和错误级别以上的信息log_level: 'debug'# 模型转换输出的结果的存放目录working_dir: 'model_output'# 模型转换输出的用于上板执行的模型文件的名称前缀output_model_file_prefix: 'ppyolo_trashdet_416x416_nv12'# 模型输入相关参数, 若输入多个节点, 则应使用';'进行分隔, 使用默认缺省设置则写Noneinput_parameters:# (可不填) 模型输入的节点名称, 此名称应与模型文件中的名称一致, 否则会报错, 不填则会使用模型文件中的节点名称input_name: "image"# 网络实际执行时,输入给网络的数据格式,包括 nv12/rgb/bgr/yuv444/gray/featuremap,# 如果输入的数据为yuv444, 模型训练用的是bgr(NCHW),则hb_mapper将自动插入YUV到BGR(NCHW)转化操作input_type_rt: 'nv12'# 转换后混合异构模型需要适配的输入数据排布,可设置为:NHWC/NCHW# 若input_type_rt配置为nv12,则此处参数不需要配置input_layout_rt: 'NHWC'# 网络训练时输入的数据格式,可选的值为rgb/bgr/gray/featuremap/yuv444input_type_train: 'rgb'# 网络训练时输入的数据排布, 可选值为 NHWC/NCHWinput_layout_train: 'NCHW'# 模型网络的输入大小, 以'x'分隔, 不填则会使用模型文件中的网络输入大小,否则会覆盖模型文件中输入大小input_shape: '1x3x416x416'# 网络输入的预处理方法,主要有以下几种:# no_preprocess 不做任何操作# data_mean 减去通道均值mean_value# data_scale 对图像像素乘以data_scale系数# data_mean_and_scale 减去通道均值后再乘以scale系数norm_type: 'data_mean_and_scale'# 图像减去的均值, 如果是通道均值,value之间必须用空格分隔mean_value: 123.68 116.28 103.53# 图像预处理缩放比例,如果是通道缩放比例,value之间必须用空格分隔scale_value: 0.0171 0.0175 0.0174calibration_parameters:# 模型量化的参考图像的存放目录,图片格式支持JPEG、BMP等格式,输入的图片# 应该是使用的典型场景,一般是从测试集中选择20~100张图片,另外输入# 的图片要覆盖典型场景,不要是偏僻场景,如过曝光、饱和、模糊、纯黑、纯白等图片# 若有多个输入节点, 则应使用';'进行分隔cal_data_dir: './images_f32'# 如果输入的图片文件尺寸和模型训练的尺寸不一致时,并且preprocess_on为true,# 则将采用默认预处理方法(skimage resize),# 将输入图片缩放或者裁减到指定尺寸,否则,需要用户提前把图片处理为训练时的尺寸preprocess_on: True# 模型量化的算法类型,支持kl、max、default、load,通常采用default即可满足要求, 若为QAT导出的模型, 则应选择loadcalibration_type: 'kl'# 编译器相关参数compiler_parameters:# 编译策略,支持bandwidth和latency两种优化模式;# bandwidth以优化ddr的访问带宽为目标;# latency以优化推理时间为目标compile_mode: 'latency'# 设置debug为True将打开编译器的debug模式,能够输出性能仿真的相关信息,如帧率、DDR带宽占用等debug: False# 编译模型指定核数,不指定默认编译单核模型, 若编译双核模型,将下边注释打开即可core_num: 2# 优化等级可选范围为O0~O3# O0不做任何优化, 编译速度最快,优化程度最低,# O1-O3随着优化等级提高,预期编译后的模型的执行速度会更快,但是所需编译时间也会变长。# 推荐用O2做最快验证optimize_level: 'O2'

在docker中执行模型转换命令:

hb_mapper makertbin --config config.yaml --model-type onnx

得到4个模型:

ppyolo_trashdet_416x416_nv12_original_float_model.onnxppyolo_trashdet_416x416_nv12_optimized_float_model.onnxppyolo_trashdet_416x416_nv12_quantized_model.onnxppyolo_416x416.bin

2.上板部署

代码仓库:https://c-gitlab.horizon.ai/HHP/box/hobot_perception/mono2d_trash_detection

2.1 TROS环境搭建

1)通过apt安装TROS快速体验(适用本教程)

https://developer.horizon.ai/api/v1/fileData/TogetherROS/quick_start/install_tros.html

2)如需进行二次开发,编译安装方法

https://developer.horizon.ai/api/v1/fileData/TogetherROS/quick_start/cross_compile.html

2.2 设置配置文件

ppyoloworkconfig.json配置文件说明

{"model_file":模型文件的路径 "model_name":模型名称 "dnn_Parser":设置选择内置的后处理算法,示例采用的解析方法同yolov3,采用"yolov3" "model_output_count":模型输出branch个数 "class_num": 检测类别数 "cls_names_list": 检测类别具体标签 "strides": 每个输出branch步长 "anchors_table": 预设anchors比例 "score_threshold": 置信度阈值 "nms_threshold": NMS后处理IOU阈值 "nms_top_k": NMS后处理选取的框个数 }

2.3 实时运行

在地平线旭日X3派上运行:

# 复制配置文件cp -r /opt/tros/lib/mono2d_trash_detection/config/ . # 设置mipi摄像头export CAM_TYPE=mipi# 运行dnn_node_example节点ros2 launch dnn_node_example hobot_dnn_node_example.launch.py \ config_file:=config/ppyoloworkconfig.json \msg_pub_topic_name:=ai_msg_mono2d_trash_detection \image_width:=1920 \image_height:=1080

实时运行效果如下,当前部署可以达到30FPS(实时):

实时演示视频:

终端日志打印:

2.4 本地回灌

在地平线旭日X3派终端上运行:

# 复制配置文件cp -r /opt/tros/lib/mono2d_trash_detection/config/ . # 运行dnn_node_example节点ros2 launch dnn_node_example hobot_dnn_node_example_feedback.launch.py \config_file:=config/ppyoloworkconfig.json \image:=config/trashDet0028.jpg

回灌图片保存到本地效果如下:

终端日志打印:

3. 总结

至此,基于百度PaddlePaddle框架训练 + 地平线旭日X3派部署的教程到此介绍完毕,后续用户可借助地平线机器人开发平台,利用AI检测结果,开发更多有趣好玩的机器人项目。

参考连接:https://developer.horizon.ai/api/v1/fileData/TogetherROS/index.html

此文章为搬运

原项目链接

如果觉得《PPYOLO垃圾检测+地平线旭日X3派部署(下)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。