yolov5模型转换(二) onnx转ncnn

首先按顺序讲下转换的步骤过程,若遇到问题可以看看最后的【可能遇到的问题】有没有你的问题呢。
已经转好了onnx,完成了二分之一,接下来就一起转nccn吧。

1. ncnn环境搭建

# 准备基础环境
sudo apt install build-essential libopencv-dev cmake

# 编译安装protobuf依赖库
git clone https://github.com/protocolbuffers/protobuf.git  # 安装源文件
cd protobuf
git submodule update --init --recursive  # clone子模块的依赖
./autogen.sh  # 执行自动生成的shell脚本
./configure  # 配置文件shell脚本
make  # 编译
make install  # 编译安装
sudo ldconfig  # 刷新

编译安装好后,可以查看下 protobuf 的版本
在这里插入图片描述

2. 编译ncnn,目的是生成onnx转ncnn的命令行工具

依次执行

git clone https://github.com/Tencent/ncnn.git
cd ncnn
mkdir build
cd build
cmake ..
make
make install

3. onnx转换为ncnn

使用onnx2ncnn工具进行转换,进入 ncnn/build/tools/onnx 路径下再输入./onnx2ncnn 命令。
其中 model.onnx 是需要转为ncnn的简化后的 onnx 模型,model.param 和 model.bin 即为转为 ncnn 后输出的两个文件,注意这两个文件的顺序不能写反了!

cd tools/onnx
./onnx2ncnn /home/jiao/yolov5/yolov5s-best.onnx /home/jiao/yolov5/yolov5s-best.param /home/jiao/yolov5/yolov5s-best.bin

如果不报错就成功了,最后生成 .param 和 .bin 两个文件。
但可惜有错啊,这是focus模块转换的报错
在这里插入图片描述
那该怎么办呢?用netron工具打开param,找到对应focus的部分
在这里插入图片描述nihui大神说"把这堆骚操作用个自定义op YoloV5Focus代替掉,修改param"

4. 实现focus模块

在这里插入图片描述这是我原来的 yolov5s-best.param,红色是需要修改的地方,修改后的param见下。原来有223,删掉 Split、Crop、Concat 层,新增YoloV5Focus层后,10个op换成了1个op,一共减少9行,将开头的 layer count 减去9,改写为214。
在这里插入图片描述修改后的结构:
在这里插入图片描述

5. 动态尺寸推理

最后 Reshape 层把输出grid数写死了,根据 ncnn Reshape 参数含义,把写死的数量改为 -1 便可以自适应
在这里插入图片描述在这里插入图片描述

替换后用 ncnnoptimize 过一遍模型,顺便转为 fp16 存储减小模型体积。ncnnoptimize 工具会自动将无用的 MemoryData 删除,并且自动将最终的 blob count 设置为合适的数量,所以前面步骤中不需要自己改 blob count。
进入 ncnn/build/tools 路径下再输入./ncnnoptimize 命令

./ncnnoptimize /home/jiao/yolov5/yolov5s-best.param /home/jiao/yolov5/yolov5s-best.bin /home/jiao/yolov5/yolov5s-best-opt.param /home/jiao/yolov5/yolov5s-best-opt.bin 0

在这里插入图片描述

6. 实现这个自定义op YoloV5Focus

后续操作,nihui大神已经将ncnn实现代码和转好的模型上传到https://github.com/nihui/ncnn-android-yolov5了!

针对 focus 这样,没有权重,也无所谓参数加载的 op,继承 ncnn::Layer 实现 forward 就可以用,注意要用 DEFINE_LAYER_CREATOR 宏定义 YoloV5Focus_layer_creator,这块代码在 app/src/main/jni/yolov5ncnn_jni.cpp 中。

【可能遇到的问题】

1. git clone 下载的太慢!

在git clone的地址,例如上面 git clone https://github.com/protocolbuffers/protobuf.git,改为git clone https://github.com.cnpmjs.org/protocolbuffers/protobuf.git,即在github.com后加上.cnpmjs.org,然后就可以愉快的下载了
【注】:使用镜像站,该方法仅对git clone有用,对git push无效,并且无法登陆账号,私人项目无法进行Clone。

2. git submodule update --init --recursive 也慢怎么办?

对于含有子模块,在主体部分下载完后,主体文件夹中有个隐藏文件称为:.gitmodules,找到用vim或直接用文本编辑器打开,把子项目中的url地址同样加上.cnpmjs.org后缀,然后再利用git submodule sync更新子项目对应的url,最后再git submodule update --init --recursive,即可正常网速 clone 完所有子项目。
【注】:当使用 git clone 下来的工程中带有 submodule 时,初始的时候,submodule的内容并不会自动下载下来的,所以需要执行 git submodule update --init --recursive命令,即可将子模块内容下载下来,整个工程才不会缺少相应的文件。
在这里插入图片描述

3. sudo ldconfig出错

显示不是符号链接
在这里插入图片描述
先查看具体报错信息

sudo ldconfig -v

在这里插入图片描述
解决方法:对于提示的错,手动建立软连接

sudo ln -sf /usr/local/cuda-11.0/targets/x86_64-linux/lib/libcudnn_cnn_infer.so.8.0.5 /usr/local/cuda-11.0/targets/x86_64-linux/lib/libcudnn_cnn_infer.so.8
# 其他以此类推
sudo ln -sf /usr/local/cuda-11.0/targets/x86_64-linux/lib/libcudnn_cnn_train.so.8.0.5 /usr/local/cuda-11.0/targets/x86_64-linux/lib/libcudnn_cnn_train.so.8

sudo ln -sf /usr/local/cuda-11.0/targets/x86_64-linux/lib/libcudnn_adv_infer.so.8.0.5 /usr/local/cuda-11.0/targets/x86_64-linux/lib/libcudnn_adv_infer.so.8

sudo ln -sf /usr/local/cuda-11.0/targets/x86_64-linux/lib/libcudnn_adv_train.so.8.0.5 /usr/local/cuda-11.0/targets/x86_64-linux/lib/libcudnn_adv_train.so.8

sudo ln -sf /usr/local/cuda-11.0/targets/x86_64-linux/lib/libcudnn_ops_infer.so.8.0.5 /usr/local/cuda-11.0/targets/x86_64-linux/lib/libcudnn_ops_infer.so.8

sudo ln -sf /usr/local/cuda-11.0/targets/x86_64-linux/lib/libcudnn_ops_train.so.8.0.5 /usr/local/cuda-11.0/targets/x86_64-linux/lib/libcudnn_ops_train.so.8

建立好后就没有错误提示啦!

参考博客:

  1. 详细记录u版YOLOv5目标检测ncnn实现
  2. 指尖上的YOLOv5
  3. yolov5部署2——onnx->ncnn
  • 6
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值