飞桨模型在地平线开发板部署

大家好,我是海盗旗,资深CV工程师(ctrl c + ctrl v),第一次使用国产框架与国产AI芯片(地平线旭日X3)之间实现了全链路开发。

本次教程,使用飞桨高阶API训练mobilenet模型,三分钟即可搭建一个网络,进行训练。

部署使用地平线的天工开物工具链,模型快速转化上板,极短的时间内可演示demo。

欢迎大家一起使用国产化平台进行AI开发与部署!

onnx模型是paddle模型与开发板推理部署之间的桥梁,模型的转化是其中非常重要的一环。

本次教程主要讲述流程串通,直接使用飞浆的高阶api训练模型,可以节省大量的开发时间

  • 一、模型训练:

飞桨高阶api对基础aoi进行了封装,模型调用与数据预处理几行代码就可以搞定,真的是灰常方便,建议大家多多使用。

本次教程使用mobilenetv2进行分类,数据预处理的时候,模型标签是从1-102,但是深度学习标签都是从0开始,建议百度的工程师修改一下此处的标签。

本次教程使用mobilenetv2进行分类,数据预处理的时候,模型标签是从1-102,但是深度学习标签都是从0开始。

修改的方法需要把标签数直接减去1,这样标签数据对齐到0-101,可以直接训练,否则会报错,标签索引超出!

#只要20行代码,深度学习模型带回家,高阶api,用起来吧import paddle from paddle.vision.datasets import Flowersfrom paddle.vision.models import MobileNetV2,mobilenet_v2from paddle.vision.transforms import ToTensor,Compose, Resize, ColorJitterprint('===============================start train')transform = Compose([Resize(size=[228,228]),ToTensor()])#预处理train_dataset = Flowers(mode='train',transform=transform)#标签转换为0-101,不改的话,下面的标签需要改成103train_dataset.labels = train_dataset.labels-1 #花有102种类别#创建模型mobilenetv2 = MobileNetV2(num_classes=102)# paddle.summary(mobilenetv2,(1,3,228,228)) 测试模型model = paddle.Model(mobilenetv2)#模型封装model.prepare(paddle.optimizer.Adam(parameters=model.parameters()),              paddle.nn.CrossEntropyLoss(),              paddle.metric.Accuracy())model.fit(train_dataset,          epochs=200,          batch_size=128,          save_dir='Model/cpu',          save_freq=1,          verbose=1)print('===============================finish train')
  • 二、paddle模型转化为onnx模型

使用百度的paddle2onnx工具进行转化

!pip insyall paddle2onnx

!pip install onnx

安装好之后,按照官方示例,加载模型,然后使用paddle.onnx.export接口进行转化,现在流行动态图,我们直接使用动态图操作方式,让静态图静静的躺在历史的尘埃里吧!!!

###注意###

模型输入需要设定batch为1,地平线开发板写死了入口,指定输入为4D,且batch只能为1,因此转化的时候需要设置如下形式:

input_spec = paddle.static.InputSpec(shape=[1, 3, 224, 224], dtype=‘float32’, name=‘image’)

import paddle import paddle2onnximport onnxfrom paddle.vision.models import MobileNetV2print(onnx.__version__,paddle.__version__,paddle2onnx.__version__)# 实例化模型mobilenetv2 = MobileNetV2(num_classes=102)#封装并加载模型model = paddle.Model(mobilenetv2)model.load(path='./save_model/0')#把模型从封装的Model中剥离出来net = model.network# 将模型设置为推理状态net.eval()# 定义输入数据input_spec = paddle.static.InputSpec(shape=[1, 3, 224, 224], dtype='float32', name='image')# ONNX模型导出# enable_onnx_checker设置为True,表示使用官方ONNX工具包来check模型的正确性,需要安装ONNX(pip install onnx)paddle.onnx.export(net, 'mobilenet_v2', input_spec=[input_spec], opset_version=10, enable_onnx_checker=True)
  • 三、onnx模型校验

成功得到onnx模型之后,我们需要把onnx模型转化为板端部署文件

地平线提供了天工开物工具链,可以有效的对onnx模型进行验证并转化

部署第一步,使用工具链对onnx模型进行校验,校验不通过的模型目前无法上板部署,需要调整算子或提交地平线开发人员进行算子支持升级!!

工具链可在地平线生态社区获取,大家可以自行搜索!

  • 四、onnx模型转化为板端推理文件

使用地平线的开发工具天公开物,简单来说就是地平线开发板的开发套件

完成onnx模型->地平线开发板模型,转化得到的bin文件很小,只有2.4M,小了一半以上

  • #五、部署与测试

    1.构建应用:# parallel_process_num的设置,参考您的cpu配置,如果不设置这个环境变量,默认为单进程cd samples/04_detection/01_yolov2/runtime_armsh 01_build.sh2.数据预处理# parallel_process_num的设置,参考您的cpu配置,如果不设置这个环境变量,默认为单进程export PARALLEL_PROCESS_NUM=${parallel_process_num}sh 02_preprocess.sh处理好的图像将会用于后续的评测eval3.将构建好的应用传到开发板sh 03_scp_to_board.sh ${board_ip}执行这个命令,会将构建好的应用,通过scp,传输到开发板的 /userdata/samples/mobilenet 目录下。若要执行单张图片的infer, 则可通过下面的代码操作远程登录开发板进行执行ssh root@${board_ip}cd /userdata/samples/yolov2sh dev_board_01_infer.sh4.执行评测sh 04_eval.sh ${board_ip}该脚本会将图片传输至板上进行运行和评测, 此过程将持续很久.5.执行性能测试sh 05_perf.sh ${board_ip}同时该操作也可从开发板上单独完成, 则可通过下面的代码操作远程登录开发板进行执行ssh root@${board_ip}cd /userdata/samples/yolov2sh dev_board_03_perf.sh————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————最终结果:性能测试,10张图像仅用了24.01ms,速度经得起检验,精度损失极少,I0101 10:41:40.973683 1899 simple_example.cc:172] Whole process statistics:count:10, duration:34.01ms, min:3.342ms, max:3.823ms, average:3.35562ms, fps:294.031/s, Infer stage statistics:count:10, duration:33.869ms, min:3.33ms, max:3.794ms, average:3.34312ms, fps:295.255/s, Post process stage statistics:count:10, duration:0.125ms, min:0.01ms, max:0.027ms, average:0.011ms, fps:80000/s