文章目录[隐藏]
- 前言
- 项目目录
- 基础编译
- 转化前的准备
- 如果上述过程没问题,那就基本完成 80% 了
- 1 训练自己的YOLO5模型,这里建议YOLO5s,因为上述源码基于 YOLO5 s 如果需要其他的模型,自己需要写对应的C++代码,另外最大原因是 YOLO5s 的效率高,对移动端友好。训练YOLO5 参看进入
- 2 训练好的 pt 转 bin 和 param
- 以上步骤之后,需要使用 ncnn 文件夹下的 ncnnoptimize进行再次整合优化,后面的 65536 也可以替换为 1 已在将模型转为FP16 单精度计算,节省运算时间,为0时,为FP32 双精度计算
- 将生成的 bin 和 param 文件复制到 asserts 文件夹 后,不要着急编译为 APK
- 里面需要调整的参数有:
前言
本文旨在记录本人将YOLO5训练好的模型转化为安卓 APP 的经历,使用的项目源码为,点击进入,下面开始分步骤进行讲解。
项目目录
项目的src文件夹下包含下面的文件夹,其中:
1 asserts 里面存放的是 YOLO5s.bin和YOLO5s.param,
2 java 中存放的是 java 源代码
3 jni c存储的是 YOLO5s的C++版本
4 res存放的android所需要的配置文件
使用 Android studio 直接在该文件的根目录打开就行
基础编译
该项目首页展示了如何进行代码的编译,可以参见官网进入,这里把自己的调试经验记录下。
1 首先在NCNN下载编译所需的ncnn包,下载页面为点击进入,下载箭头指向的文件
下载解压 之后存放在 jni 文件中,主要原因是在于项目源码中包含了此选项,如果下载上面页面中的 ncnn-android 其实也能编译,不过要替换这里的画横线部分
2 进行编译运行成为 APK文件(这个可以自行百度过程,也可按照下方操作)
如果您第一次生成APK可能需要配置下这里的账号和密码,存在一个指定文件夹中
按照以下选择,点击 finish 按钮即可
最终会在 src 同根目录生成 release 文件夹,里面存放的就是 APK文件
通过 QQ(不能通过微信,微信会自动在APK后缀加.1导致文件损坏) 传到手机,安装就行,下面这个是从官网截的图片,大概界面就是这样,很简洁2,不过功能自己可以再多完善
讲到这里,大家会发现,以上都是基于官方的 源码编译的结果,如果自己训练好的模型,怎么才能转化为 上述文件夹中的 bin 和 param 呢。怎样进行配置自定义的APP?这个网站上有些专栏介绍的有,这里我结合自己的经验进行详细记录。
转化前的准备
如果上述过程没问题,那就基本完成 80% 了
1 训练自己的YOLO5模型,这里建议YOLO5s,因为上述源码基于 YOLO5 s 如果需要其他的模型,自己需要写对应的C++代码,另外最大原因是 YOLO5s 的效率高,对移动端友好。训练YOLO5 参看进入
2 训练好的 pt 转 bin 和 param
2.1 先将 pt 转 onnx
这个是在 yolo5中的 models文件夹下的 export .py,最好将这个export.py 复制到根目录,不然会报 models 未定义的异常,然后在根目录直接使用下面的命令执行,这个 ONNX是 Open Neural Network Exchange(开放神经网络交换)格式,是一个用于表示深度学习模型的标准,可使模型在不同框架之间进行转移,所以这个是模型转化的第一步,将 pt 转为一种万能格式。
python export.py --weights ./runs/exp0/weights/best.pt --img 640 --batch 1
一般此步骤不会出错,当然我用的是 yolo5-2.0 版本,新版本没有尝试,不过大概率也是没问题。
这里是将模型进行简化,需要安装 onnxsim 的,安装命令:
pip install onnx-simplifier
然后使用该命令,简化刚才的 onnx ,其实有点类似模型压缩
python -m onnxsim best.onnx best-sim.onnx
2.2 onnx2ncnn
在编译安装好的目录中,找到 onnx2ncnn 文件,这个是个可执行的文件,然后将自己的 pt 复制到该文件夹,主要是操作方便,也可不复制,直接使用路径访问。
然后使用命令
./onnx2ncnn best-sim.onnx best.param best.bin
如果没有报错,那么你就转化成功了,但由于 YOLO5中的 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 !
这需要您打开生成的 param 文件,按照下面的策略进行编辑,将圈出来的部分替换为下面的图片,其中 201- 192这个其实目前我还不是很理解,可能和 java 源码中对应的,我后来看看,转为那个 YoloV5Focus是在 java 中有对应的操作,其实该步骤的含义是将 Focus 模块转化为一个简单的模块。
原Focus结构(图像由 param 文件 用 Netron 可视化得到 ):
转化后的结构
如果不满足以上的 YoloV5Focus 转化,自己可以在 github 找实现代码点击进入
以上步骤之后,需要使用 ncnn 文件夹下的 ncnnoptimize进行再次整合优化,后面的 65536 也可以替换为 1 已在将模型转为FP16 单精度计算,节省运算时间,为0时,为FP32 双精度计算
./ncnnoptimize best.param best.bin best-opt.param best-opt.bin 65536
将生成的 bin 和 param 文件复制到 asserts 文件夹 后,不要着急编译为 APK
里面需要调整的参数有:
jni/yolov5ncnn_jni.cpp中的 anchor参数需要调整为和自己网路训练anchor 配置一致,这里我是用了4个anchor 共 8个 w 和 h
jni/yolov5ncnn_jni.cpp中的 blob 名字
这个名字是用来提取输出结果的,对应的是 param 文件的 画圈部分的id 值
种类名需要替换为自己的
static const char* class_names[] ={"name_1","name_2","name_3",...}
YOLO v5 的后处理
pytorch的后处理在 yolov5/models/yolo.py Detect类 forward函数,对着改写成 cpp, 写在 jni 下的 cpp文件即可,也可以自定义
U版yolov5 是支持动态尺寸推理的
静态尺寸:按长边缩放到 640xH 或 Wx640,padding 到 640x640 再检测,如果 H/W 比较小,会在 padding 上浪费大量运算
动态尺寸:按长边缩放到 640xH 或 Wx640,padding 到 640xH2 或 W2x640 再检测,其中 H2/W2 是 H/W 向上取32倍数,计算量少,速度更快
ncnn天然支持动态尺寸输入,无需reshape或重新初始化,给多少就算多少
如果出现对于小图像的检测有问题,可以将param的reshape 变为 -1,后处理部分也不可写死 sqrt(num_grid),要根据图片宽高和 stride 自适应
然后这就可以进行编译APK了,祝顺利!
本文参考进入
版权声明:本文为CSDN博主「qq_29750461」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_29750461/article/details/114818608
暂无评论