当前位置:   article > 正文

yolov8使用ncnn部署_yolov8 ncnn

yolov8 ncnn

前言:

几个小时前,我整理了一个新版(v7.0) YOLOv5NCNN 部署教程:

详细记录u版YOLOv5目标检测ncnn实现(第三版) - 知乎

常言道用新不用旧,我顺便把 YOLOv8NCNN 部署放出来吧!(把自己观念持续贯彻!)

本文将基于当前时间最新的 YOLOv8 进行模型转换和模型推理部署。

背景知识:

YOLO 系列在短短的两年多升级了不知道多少代了,但是最火的还是 YOLOv5,同属于这个公司的 YOLOv8 想必也是精品,ultralytics 公司野心很大,发布 YOLOv8 的同时也想一统 YOLO,我们需要持续观望一波!

版本号 v8.0.38

commit id: d99e04daa1290c226a3fae825401361b17ce164c

0x1 缘由

YOLOv8 相对于 YOLOv5 在主干上改动较小,最大的改动就是检测头了,变成了基于 DFLanchor free 模型, 这部分变化较大的就是框解码了,我总结了下面 3 点:

  1. DFL 模块 Reshape+Transpose+Softmax+Conv+Reshape 这套组合是真折腾
  2. 解码已经是 ltrb 格式还要转回 xywh 比较麻烦。
  3. 没有置信度预测分支了,需要自己做 argmax

本文同样,重新组织后处理代码,然后实现 NCNN 推理 YOLOv8

0x2 pytorch测试和导出torchscript

首先是下载当前时间最新的 YOLOv8 ,当前时间是 : 2023-02-15 16:00

  1. git clone https://github.com/ultralytics/ultralytics.git # clone
  2. cd ultralytics
  3. git checkout d99e04daa1290c226a3fae825401361b17ce164c # switch to commit id
  4. pip install -r requirements.txt # install
  5. pip install -e . # install ultralytics as package

YOLOv8 开始支持命令行启动任务了,对于搞 YOLOv5 的人转过来调试还是不太舒服。

老样子,用默认的配置和预训练模型推理一张图片:

yolo predict model=yolov8s.pt source=ultralytics/assets/bus.jpg show=True

接下来动源码,ultralytics/nn/modules.py 中的 398-411 行注释掉,换成下面的内容:

  1. # def forward(self, x):
  2. # shape = x[0].shape # BCHW
  3. # for i in range(self.nl):
  4. # x[i] = torch.cat((self.cv2[i](x[i]), self.cv3[i](x[i])), 1)
  5. # if self.training:
  6. # return x
  7. # elif self.dynamic or self.shape != shape:
  8. # self.anchors, self.strides = (x.transpose(0, 1) for x in make_anchors(x, self.stride, 0.5))
  9. # self.shape = shape
  10. #
  11. # box, cls = torch.cat([xi.view(shape[0], self.no, -1) for xi in x], 2).split((self.reg_max * 4, self.nc), 1)
  12. # dbox = dist2bbox(self.dfl(box), self.anchors.unsqueeze(0), xywh=True, dim=1) * self.strides
  13. # y = torch.cat((dbox, cls.sigmoid()), 1)
  14. # return y if self.export else (y, x)
  15. def forward(self, x):
  16. z = [] # inference output
  17. for i in range(self.nl):
  18. boxes = self.cv2[i](x[i]).permute(0, 2, 3, 1)
  19. scores = self.cv3[i](x[i]).sigmoid().permute(0, 2, 3, 1)
  20. feat = torch.cat((boxes, scores), -1)
  21. z.append(feat)
  22. return tuple(z)

导出 torchscript:

yolo export model=yolov8s.pt format=torchscript

会在当前工作目录下生成 yolov8s.torchscript

Netron 看一眼清爽的后处理长什么样:

会有三个上述的结构,这是我们修改的 forward 中的内容,把分类预测分支的 sigmoid 弄到了模型,然后 permute + cat

0x3 转换

下载编译好的 pnnx 工具包:PNNX

指定 inputshape 并且额外指定 inputshape2 转换成支持动态 shape 输入的模型:

./pnnx yolov8s.torchscript inputshape=[1,3,640,640] inputshape2=[1,3,320,320] 

转换日志:

转换主要产物:

看一眼 yolov8s.ncnn.param

in0 对应输入,尺寸是 3*640*640 或者动态输入的尺寸。

out0 对应输出,尺寸是 80*80*144 或者动态输出的尺寸。

out1 对应输出,尺寸是 40*40*144 或者动态输出的尺寸。

out2 对应输出,尺寸是 20*20*144 或者动态输出的尺寸。

注意,本文用pnnx转换后的模型,尾巴上有sigmoid层和permute层。

0x4 u版YOLOv8后处理

pytorch的后处理在ultralytics/nn/modules.py Detect类 forward函数,也就是我们注释掉的部分,对着它改写成 cpp。

本文最后的输出形状:

C = 80 或 40 或 20

H = 80 或 40 或 20

W = 144 = 64+80

64 对应了 DFL 中的 reg_max=16, 最终回归的 bbox 格式是 ltrb

ncnn实现代码和转好的模型已上传到github:

GitHub - triple-Mu/ncnn-examples: Learning ncnn with some examples

使用方式:

  1. git clone https://github.com/triple-Mu/ncnn-examples.git
  2. cd ncnn-examples/yolov8
  3. mkdir build
  4. cmake .. && make -j$(nproc)
  5. mv triplemu-yolov8 .. && cd ..
  6. ./triplemu-yolov8 ../bus.jpg

0x5 动态尺寸推理

与其他的教程相同,本文也支持动态输入尺寸,更多的探索请查看源码 src/triplemu-yolov8.cpp

0x6 总结

允许在不修改内容前提下转载本文!!

欢迎大家通过 triple-Mu 联系我哈~

顺便宣传一下我的 YOLOv8-TensorRT 部署仓库:

GitHub - triple-Mu/YOLOv8-TensorRT: YOLOv8 using TensorRT accelerate !

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号