目录
YOLOv5s-v3.1模型转换
因为U版YOLO的作者用pytorch实现,yolov5的模型是torch格式的pt。要使用ncnn部署YOLOv5需要将模型进行转换,大概步骤是pt2onnx,onnx2ncnn。
因为只有yolovs-v3.1版本正常测试通过了,固仅针对此进行记录。高版本的yolov5初试未成功,未细加研究,之后有时间再进行深入研究。。。。
模型的转换主要参考:详细记录u版YOLOv5目标检测ncnn实现 - 知乎
第一步:pt2onnx
准备一个已经训练好了的yolov5s-v3.1.pt模型,pt2onnx我就用的YOLOv5-v3.1版本源码中的export.py进行的转换
生成yolov5s-v3.1.onnx,并用onnxsim简化一下生成yolov5s-v3.1-sim.onnx
$ python models/export.py --weights yolov5s-v3.1.pt --img 640 --batch 1
$ python -m onnxsim yolov5s-v3.1.onnx yolov5s-v3.1-sim.onnx
这一步还比较顺利~
第二步:onnx2ncnn
去编译好的ncnn的目录下找到onnx2ncnn.exe进行转换
$ onnx2ncnn yolov5s-v3.1-sim.onnx yolov5s-v3.1-sim.param yolov5s-v3.1-sim.bin
转换为 ncnn 模型,会输出很多 Unsupported slice step,这是focus模块转换的报错
focus模块要手工修复下,用netron工具打开param,找到对应focus的部分
把这堆crop用自定义op YoloV5Focus代替掉,修改yolov5s-v3.1-sim.param
详细参考大神:详细记录u版YOLOv5目标检测ncnn实现 - 知乎
修改完用 ncnnoptimize 过一遍模型,顺便转为 fp16 存储减小模型体积。ncnnoptimize也在ncnn编译完成的目录下ncnnoptimize.exe
$ ncnnoptimize yolov5s.param yolov5s.bin yolov5s-opt.param yolov5s-opt.bin 65536
u版yolov5 是支持动态尺寸推理的
- 静态尺寸:按长边缩放到 640xH 或 Wx640,padding 到 640x640 再检测,如果 H/W 比较小,会在 padding 上浪费大量运算
- 动态尺寸:按长边缩放到 640xH 或 Wx640,padding 到 640xH2 或 W2x640 再检测,其中 H2/W2 是 H/W 向上取32倍数,计算量少,速度更快
ncnn天然支持动态尺寸输入,无需reshape或重新初始化,给多少就算多少
问题出在最后 Reshape 层把输出grid数写死了,根据 ncnn Reshape 参数含义,把写死的数量改为 -1 便可以自适应,如下
至此ncnn的模型已准备好了。
ncnn实现代码见ncnn的github,大神已经写好~可以拿来主义了~见examples/yolov5.cpp,可直接进行测试,github连接:https://github.com/Tencent/ncnn/tree/master/examples
下一篇记录建立一个cnn yolov5 的vs2019测试工程进行测试~