yolov5 6.0版本->onnx->ncnn +安卓部署 附加ncnn环境配置 保姆级详细教程
Posted xrh_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了yolov5 6.0版本->onnx->ncnn +安卓部署 附加ncnn环境配置 保姆级详细教程相关的知识,希望对你有一定的参考价值。
目标检测:yolov5 6.0版本 ncnn环境安装 至 +安卓部署 一条龙教程
文章目录
背景
题主在模型部署时踩坑颇多,也看到yolov5 部署的参考资料不多,故本小萌新将自己踩坑的过程记录下来,也方便大家参考。yolov5->pt->onnx->ncnn float16位量化
一、准备阶段
1.参考文章
1.YoloV5官方github
YoloV5官方TFLite, ONNX, CoreML, TensorRT 的Export实现
2.nihui(ncnn作者)写的文章,感谢nihui大佬赏饭吃
ncnn github地址
ncnn-android-yolov5 github地址
详细记录u版YOLOv5目标检测ncnn实现
详细记录u版YOLOv5目标检测ncnn实现(PNNX版)
3.我踩坑时的参考文章
windows下最新yolov5转ncnn教程
YOLOv5转NCNN过程
yolov5 转onnx转ncnn
基本都是21年的文章,有些步骤现在其实不用了,大家可以参考参考
4.Linux下ncnn部署流程 –可参考
ncnn编译部署(Linux)
#2.流程
1.准备训练好的模型,建议先用官方的yolov5.pt模型自己整流程走一遍,再替换为自己的模型结构。Yolov5官方pt模型链接(链接为6.1版本)
2.pt模型->onnx
3.Windows下ncnn环境配置教程详解
4.onnx->ncnn
5.ncnn的安卓部署
二、pt模型->onnx
github上下载yolov5工程,按照 yolov5 README 指引,调用detect.py看下模型有没有问题。准备就绪后调用export.py进行模型转换
我使用的是yolov5-6.1工程,将yolov5s.pt复制到文件目录下
python export.py --weights yolov5s.pt --include onnx --img 640 --train --simplify
6.1版本已经集成好了,很方便
添加–include 是指定导出类型为 torchscript/onnx ,读者按需转换即可。
添加–train 是为了去除后处理,即不直接输出一个分类结果output,而将3个特征图的作为输出。
添加–simplify 是为了简化模型,不需要像其他帖子一样单独进行onnxsim简化,省事。
如果是修改自己的模型 记得 --data xxx.yaml
最后得到文件
yolov5s.onnx
三、Windows下ncnn环境配置教程详解
最初我是学习nihui写的pnnx版yolo部署,失败了
后面再尝试onnx的过程中,发现很多参考资料和教程都没有加入ncnn环境部署部分。大多都直接讲 ncnn-android-yolov5 的安卓部署。
实际上对萌新来说(起码我是),跟着B站教程和资料时进行不下去了,这是因为它们分享onnx模型转ncnn模型经验的时候断档了,忽略了ncnn配置环节。
1.参考
文章:ncnn环境配置
这参考文章对我帮助不小,感谢作者。在这里我搬过来,侵删
准备项:VS、 cmake、 protobuf
讲道理,这3个的版本应该没关系,我觉得可以用最新版 [狗头]
2.VS安装
我用的是19版,19和22在这项目上应该差别不大。
下载地址: https://visualstudio.microsoft.com/zh-hans/vs/
下载VS后安装下面3个工作负荷
已经有VS的读者补充工具负荷即可:工具->获取工具和功能
3.cmake安装
我本身有cmake 所以当时是跳过的,此处是参考其他文章
cmake-3.16下载地址: 提取码: zme6
cmake需要变更环境变量
将解压后cmake-3.16.5-win64-x64文件夹点开进入bin将该路径添加至环境变量,
如路径为:D:\\software\\cmake-3.16.5-win64-x64\\bin
4.protobuf安装
protobuf-3.4.0下载地址: 提取码: hd3z
下载后解压,然后打开vs2019的x64命令提示
或
跳转到刚解压的protobuf的根目录,然后创建build-vs2019的文件并进行cmake操作
注:protobuf-root-dir为protobuf的下载位置
> cd <protobuf-root-dir>
> mkdir build-vs2019
> cd build-vs2019
> cmake -G"NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%cd%/install -Dprotobuf_BUILD_TESTS=OFF -Dprotobuf_MSVC_STATIC_RUNTIME=OFF ../cmake
> nmake
> nmake install
成功后会在 .\\protobuf\\build-vs2019 下生成若干文件
5.ncnn编译
github上直接下载项目,并解压
ncnn github地址
接下来我们使用vs2019的x64命令,与protobuf的安装类似,我们按下述代码操作,
> cd <ncnn-root-dir>
> mkdir -p build-vs2019
> cd build-vs2019
> cmake -G"NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%cd%/install -DProtobuf_INCLUDE_DIR=<protobuf-root-dir>/build-vs2019/install/include -DProtobuf_LIBRARIES=<protobuf-root-dir>/build-vs2019/install/lib/libprotobuf.lib -DProtobuf_PROTOC_EXECUTABLE=<protobuf-root-dir>/build-vs2019/install/bin/protoc.exe -DNCNN_VULKAN=OFF ..
> nmake
> nmake install
注: ncnn-root-dir 为你的ncnn下载位置,而第四条命令cmake 里面所有(3个)的 protobuf-root-dir 都换成读者自己的protobuf路径 ,注意是绝对路径。
成功后会在 .\\nuxnn\\build-vs2019 下生成若干文件
其中tools文件夹是我们最常用到的,里面的工具基本都集成好了
install中也包含有常用的lib、bin、include等库
四、onnx->ncnn
第二章 我们得到了 yolov5s.onnx
第三章配置好了 ncnn环境
这章我们进行模型转换
1.ncnn转换
下一步是还是用到vs2019的x64命令行,cd到 .\\ncnn\\build-vs2019\\tools\\onnx
会有onnx2ncnn.exe 应用程序,我们将yolov5s.onnx复制到目录下,然后输入
.\\onnx2ncnn yolov5s.onnx yolov5s.param yolov5s.bin
此时我们 完成ncnn 转换,得到yolov5s.param和yolov5s.bin。
题主所用的模型为6.0版本前的yolov5s.pt模型,而ncnn不支持focus结构,因此需要手工修复下focus模块。
但6.0版后官方去掉了focus,建议大家检查下是否使用6.0版本的的pt模型,Yolov5官方pt模型链接(链接为6.1版本)
使用6.0版本以上的读者即可跳转至第五章,6.0版本以下的读者我们继续处理focus结构的报错问题:
同时报错很多 Unsupported slice step,这是focus模块转换的报错
Unsupported slice step !
Unsupported slice step !
Unsupported slice step !
Unsupported slice step !
Unsupported slice step !
Unsupported slice step !
Unsupported slice step !
Unsupported slice step !
如果报下面的错误的话 ,是不是你没模型导出时没–simpliffy呢?
Unsupported slice step !
Unsupported slice step !
... ....
Unsupported slice step !
Unsupported slice step !
Shape not supported yet
2.param解释
7767517 # 文件头 魔数
75 83 # 层数量 输入输出blob数量
# 下面有75行
Input data 0 1 data 0=227 1=227 2=3
Convolution conv1 1 1 data conv1 0=64 1=3 2=1 3=2 4=0 5=1 6=1728
ReLU relu_conv1 1 1 conv1 conv1_relu_conv1 0=0.000000
Pooling pool1 1 1 conv1_relu_conv1 pool1 0=0 1=3 2=2 3=0 4=0
Convolution fire2/squeeze1x1 1 1 pool1 fire2/squeeze1x1 0=16 1=1 2=1 3=1 4=0 5=1 6=1024
...
层类型 层名字 输入blob数量 输出blob数量 输入blob名字 输出blob名字 参数字典
参数字典,每一层的意义不一样:
数据输入层 Input data 0 1 data 0=227 1=227 2=3 图像宽度×图像高度×通道数量
卷积层 Convolution ... 0=64 1=3 2=1 3=2 4=0 5=1 6=1728
0输出通道数 num_output() ; 1卷积核尺寸 kernel_size(); 2空洞卷积参数 dilation(); 3卷积步长 stride();
4卷积填充pad_size(); 5卷积偏置有无bias_term(); 6卷积核参数数量 weight_blob.data_size();
C_OUT * C_in * W_h * W_w = 64*3*3*3 = 1728
池化层 Pooling 0=0 1=3 2=2 3=0 4=0
0池化方式:最大值、均值、随机 1池化核大小 kernel_size(); 2池化核步长 stride();
3池化核填充 pad(); 4是否为全局池化 global_pooling();
激活层 ReLU 0=0.000000 下限阈值 negative_slope();
ReLU6 0=0.000000 1=6.000000 上下限
综合示例:
0=1 1=2.5 -23303=2,2.0,3.0
数组关键字 : -23300
-(-23303) - 23300 = 3 表示该参数在参数数组中的index
后面的第一个参数表示数组元素数量,2表示包含两个元素
3.实现focus模块
ncnn转换后我们得到yolov5s.param和yolov5s.bin
以记事本方式打开yolov5s.param
修改Split到Concat这10层,使用ncnn定义的YoloV5Focus层来替换这10层。
YoloV5Focus层的输入层顺接上一层的输出(橙色框),输出层顺接下一层的输入(蓝色框)。
param 开头第二行,layer_count 要对应修改,但 blob_count 只需确保大于等于实际数量即可。1层替换了10层,因此改为 185-10+1=176
一定要记得改这个,这里卡了我好久,当时很纳闷为什么App总是闪退。
然后,拖动到最后输出层,更改reshape的参数,将检测框修改为动态检测框。
OK,我们保存yolov5s.param后, 此时的yolov5s.param和yolov5s.bin已经可以正常使用了.
得到的bin和param根据自己需求部署到Linux/win/android/ios,如果需要部署到安卓端继续看
五、ncnn的安卓部署
nihui的教程已经写得很明白了,我们按步骤操作就好了。nihui YYDS!
ncnn-android-yolov5 github地址
此外建议大家使用Netron查看我们的模型
OK进入正题,假设读者已经安装好Android Studio,部署好了也用了nihui大佬的工程,测试能用没问题。我们下一步是将自己的模型替换到app上。
1.模型替换
将第四章生成的bin和param放到
工程的所在目录下如 F:\\ncnn-android-yolov5\\app\\src\\main\\assets
cpp处修改param和bin的名称,与你的自己的相对应
用Netron查看模型结构,然后修改input(1处)和output(3处)
更改模型类别
最后如果你使用的是自己训练的模型,需要修改cpp下方的static const char* class_names[] ,更改为自己模型的类别。
最后可以对模型进行量化,精度不会下降多少,内存缩小了一半
cd 到ncnn的目录中 用命令器运行,与onnx转化ncnn的步骤相似
ncnnoptimize yolov5s.param yolov5s.bin yolov5s-opt.param yolov5s-opt.bin 65536
Done,Enjoy it boy!
以上是关于yolov5 6.0版本->onnx->ncnn +安卓部署 附加ncnn环境配置 保姆级详细教程的主要内容,如果未能解决你的问题,请参考以下文章