树莓派上部署ncnn,运行yolov5_lite算法
1、下载yolov5_lite源码:
giithub地址源码:yolov5_lite https://github.com/ppogg/YOLOv5-Lite
本实验使用的是这个镜像https://blog.csdn.net/qq_45756736/article/details/137525959?spm=1001.2014.3001.5501
下载好镜像之后,一定要先改交换区的大小,不然后面会卡到你怀疑人生,推荐看这个博客https://blog.csdn.net/qq_45756736/article/details/137543073?spm=1001.2014.3001.5501
进行本实验前需要更换国内源,换源博客大家可以看看https://blog.csdn.net/qq_45756736/article/details/138291635?spm=1001.2014.3001.5501
安装运行环境,训练模型等,这里就不再赘述。
2、:pt权重文件转换为onnx文件
(1)将创建weights文件夹,并将自己的权重文件放在下方

(2)运行export.py文件,将权重文件换为自己的

遇到这个bug,请参考这个
BUG:
解决方法:
接下来一定要注意!打开common.py的333行修改成这样,才能避免出现Unsupported slice step!的错误

运行成功是这样的
这里面有警报,不用担心!
在生成ncnn文件的时候就有两个办法了
生成ncnn文件【方法一】首先我们介绍简单的方法
打开这个网站 https://convertmodel.com/,这个网站打开得需要点mo法,打开的网站是这样的

然后把自己转换好的onnx文件加载进去,这时候需要根据自己是否要转换为fp16的文件了,树莓派4算力还是有点不太行的,所以需要牺牲一些精度换取运行速度的,正常成功是这样的

不成功的下面会报Unsupported slice step!的错误,下面是按照nihui大佬的方式改的,不过我没有成功😭
- nihui大佬改Unsupported slice step!错误的方法
将下面生成的param和bin文件都下载下来。把生成的param文件用pycharm打开
将红色框中的内容删掉,加一行Yolov5…的内容,最后写的images /model.0/Concat_output_0是根据下面Convolution 那行内容确定的,至于为什么改成176,是因为之前的181行删掉了6行,又补充了一行,所以181-6+1=176.具体原因请参考nihui大佬的博客 https://zhuanlan.zhihu.com/p/275989233,简要理解参考这位大佬的博客 https://blog.csdn.net/roujian0985/article/details/122145235

改完的param文件长这样

然后保存就可以了
生成ncnn文件【方法二】第二个方法,我不太推荐有点麻烦。
安装onnx-simplifier对onnx进行简化,中间可能需要安装别的库,切记将这些库都安装在运行yolo的那个环境中
pip3 install onnx-simplifier python -m onnxsim best.onnx best-sim.onnx
需要用Anaconda pronpt换到放权重的文件夹运行

树莓派安装ncnn框架
在树莓派上下载ncnn框架,切记切记切记!一点要下载20210525版本的ncnn
具体操作如下
在树莓派终端输入以下代码,下载ncnn框架
安装依赖
sudo apt-get install -y gfortran sudo apt-get install -y libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev libhdf5-serial-dev protobuf-compiler sudo apt-get install --no-install-recommends libboost-all-dev sudo apt-get install -y libgflags-dev libgoogle-glog-dev liblmdb-dev libatlas-base-dev
编译ncnn
git clone https://gitee.com/Tencent/ncnn.git cd ncnn mkdir build cd build cmake .. make -j4 make install
安装和编译都比较慢,请耐心等待,安装和编译之后的ncnn文件夹如下

运行yolov5_lite:
用刚才【方法一】转换的,将param文件和bin文件传进来,并放在ncnn/build文件夹下

修改best-sim.param文件,将reshape中的0=x改成0=-1,按照官方文档的教程是将permute上面的reshape进行更改,permute后面的三组数字记录下来。

在ncnn/examples文件夹下面创建yolov5_lite.cpp文件,并在文件夹中复制下面代码
#include "layer.h" #include "net.h" #if defined(USE_NCNN_SIMPLEOCV) #include "simpleocv.h" #else #include #include #include #endif #include #include #include #include #include #include #include using namespace std; using namespace cv; using namespace std::chrono; // 0 : FP16 // 1 : INT8 #define USE_INT8 0 // 0 : Image // 1 : Camera #define USE_CAMERA 0 struct Object { cv::Rect_ rect; int label; float prob; }; static inline float intersection_area(const Object& a, const Object& b) { cv::Rect_ inter = a.rect & b.rect; return inter.area(); } static void qsort_descent_inplace(std::vector
修改此代码
要是需要用摄像头检测的修改第30行代码,将0改为1

将270、271行代码注释掉,并在273、274行将自己的param和bin文件路径加载进去

修改322、340,359行代码,将里面的output改为与param文件中permute中的数字一 一对应



然后打开pycahrm,由于anchors是官方训练的,可以不用修改,但是自己训练自己数据集一定要修改anchors,修改anchors,修改anchors,然后与之一一对应




接着修改成自己训练的类

修改CMakeLists.txt
打开ncnn/examples/CMakeLists.txt文件加入自己刚才新建的yolov5_lite文件,可以把不需要加载的模型注释掉
注意一定要和自己建的文件名一致

完成后使用cmake进行编译
cd ncnn/build cmake .. make
使用【方法二】的得先进行param和bin文件的简化和转成fp16,然后放在ncnn/build文件下,这也是大多数博主使用的方法,后续操作跟上面是一样的,不过这个步骤尽量用树莓派进行,不然会爆出来很多奇奇怪怪的错误,经过我测试,我感觉使用不管哪种方法最后的运行结果都是一样的。
【方法二】ncnn 模型转换,生成param和bin文件
cd ~/ncnn/build/tools ./onnx2ncnn ./best-sim.onnx ./best-sim.param ./best-sim.bin 转化成fp16 ./ncnnoptimize ./best-sim.param ./best-sim.bin ./best-sim-fp16.param ./best-sim-fp16.bin 65536 其中65536 是设置模型转为f16开关
运行yolov5_lite:
本博客是用摄像头做实时检测的,需要检测图片或者视频的可以参考其他博文
cd /home/pi/ncnn/build/examples ./yolov5_lite
学习小结:
我看大多数博主跑完之后的帧率大概在3~5帧,但是我的在0.6帧左右,有一个问题就是,大多数博主导出的param文件里面都是数字,我的里面全是字母,这个原因我找了好久也没找到,应该是我的导出的方法可能有问题。总体感觉ncnn是比不用推导的运行快一点(也可能是我的心里作用),但是要用树莓派做到实时还是有点困难,本博客是用于个人学习。做这个做了好久,中间踩了各种各样的坑,也缺少跟人讨论的机会,可以的话,大家可以私信我一起讨论。