YOLOv5(v7.0)网络修改实践三:把单分支anchor-based、head改为yolov8的anchor-free、双分支解耦合head(yolox的DecoupleHead)

[本文及相关博客仅是个人学习记录,欢迎有兴趣的同学一起交流成长]

先附上我成功实践标题的工作的训练界面(实话实说,比前两次的实践复杂多了):

1、说明:

接上我之前的博客的工作:YOLOv5(v7.0)网络修改实践二:把单分支head改为YOLOX的双分支解耦合head(DecoupleHead)

在上一篇博客我成功实践了把yolov5的单分支检测头结构改为了yolox的解耦合双分支检测头结构,只是结构。初衷是训练一下个人的算法复现集成能力,于是选了宣称比yolov5更加成功的yolox的网络进行复现到常用的yolov5框架中。先是换backbone,再是换双分支head,此次是把anchor-free替换到yolov5中。

基于复现的难度,在实现双分支解耦合head后,我发现要把anchor-free集成进来还有些复杂,因为我还不够熟悉锚框模块怎么去替换,而且他是自带的目标信息编解码方式和损失函数计算,直接集成到v5框架,会导致没法正常训练,于是重新思考复现办法。考虑到目前提出的yolov8也是采用anchor-free算法,而且在yolov5的工作上有一定的延续性,可以进行参考修改,不需要做太多的基础工作。于是目标就转到了在实现了双分支解耦合检测头的基础上集成yolov8的anchor-free算法到yolov5。

可能会有疑惑有现成的yolov8可以用,而且框架那么先进,直接用yolov8不是更好吗?这也确是一方面。但是我主要还是想尝试下这项工作,而且yolov8框架集成度高,有现成的ultralytics库可以调用,非常方便。但是也正由于这个库的存在,导致一些算法调试工作更加复杂,而且v8用着没有v5舒服,加之之前已经在v5上做了一些工作,为了方便对比之前的工作加深自己的理解,所以还是在v5上进行了。

2、遇到的一些困难

本文的工作做下来,有些地方是耗时多的,暂且总结一下遇到的困难或者说是可以避免的问题。
1、把anchor-based替换成anchor-free,这个是检测头head那块,要去掉锚框操作使用anchor-free的编解码方式,需要保证数据流通正常
2、训练阶段发现yolov8的数据加载进行了升级,yolov5不方便训练,于是我用了v8的数据集加载方式,其实大同小异,这项工作可以避免
3、训练过程中的参数,v8用了更多的参数,而且使用了不同的损失函数,要添加并正常训练
4、验证阶段的模型精度评价,这块有点复杂,我用的v5的数据加载函数,中间变量做了变换,但是预测输出和nms后处理要注意,有的要进行替换,涉及到anchor-free的解码

3、训练过程的具体工作

1、结构上:
yolo.py定义的DetectYOLO8Head:
YOLOv5(v7.0)网络修改实践三:把单分支anchor-based、head改为yolov8的anchor-free、双分支解耦合head(yolox的DecoupleHead)_第1张图片
在DetectionModel类构建检测头DetectYHOLO8Head还要去掉多个尺度的锚框生成
YOLOv5(v7.0)网络修改实践三:把单分支anchor-based、head改为yolov8的anchor-free、双分支解耦合head(yolox的DecoupleHead)_第2张图片
在common.py加上DFL类定义:
YOLOv5(v7.0)网络修改实践三:把单分支anchor-based、head改为yolov8的anchor-free、双分支解耦合head(yolox的DecoupleHead)_第3张图片
2、训练流程:
参数补充上,我加了一个参数标志,新加了anchor-free检测头需要的参数
YOLOv5(v7.0)网络修改实践三:把单分支anchor-based、head改为yolov8的anchor-free、双分支解耦合head(yolox的DecoupleHead)_第4张图片
数据加载上,我用的v8的函数加载,因为在后面训练时发现数据加载方式不一样,无法正常训练,其实也可以不用这样,自己再包装一下也可以达到v8的形式,我这是复杂化了,所以我验证阶段就不用v8的形式了
YOLOv5(v7.0)网络修改实践三:把单分支anchor-based、head改为yolov8的anchor-free、双分支解耦合head(yolox的DecoupleHead)_第5张图片
数据训练:
YOLOv5(v7.0)网络修改实践三:把单分支anchor-based、head改为yolov8的anchor-free、双分支解耦合head(yolox的DecoupleHead)_第6张图片
损失函数和其他参数:
YOLOv5(v7.0)网络修改实践三:把单分支anchor-based、head改为yolov8的anchor-free、双分支解耦合head(yolox的DecoupleHead)_第7张图片

4、验证阶段的具体工作:

训练完一个epoch后会验证模型的精度,这时会调用val.py的run函数进行验证并输出精度指标
YOLOv5(v7.0)网络修改实践三:把单分支anchor-based、head改为yolov8的anchor-free、双分支解耦合head(yolox的DecoupleHead)_第8张图片
在val.py的代码:
主要是数据加载方式,部分数据转换,后处理nms等
YOLOv5(v7.0)网络修改实践三:把单分支anchor-based、head改为yolov8的anchor-free、双分支解耦合head(yolox的DecoupleHead)_第9张图片
可以看见,这里我用的是v5的数据集加载方式,所以中间做了变换方便数据处理衔接上,另一个是后处理nms,这个必须要替换,因为preds的维度在anchor-based和anchor-free对位置的解码方式完全不一样的,所以要替换。
正常训练图:
YOLOv5(v7.0)网络修改实践三:把单分支anchor-based、head改为yolov8的anchor-free、双分支解耦合head(yolox的DecoupleHead)_第10张图片

到这里基本上就是涉及的主要工作,不够熟悉的话就要花多一点的时间,相关的具体细节的完善我就不添加了,如果不熟悉基础函数的调用添加,那就是很大的工作量。因为时间有限,稍显仓促,就没有直接贴代码了。

5、总结

很有意义的工作,实现之后发现自己的理解又加深了,对代码也更熟悉了!共勉!

你可能感兴趣的:(yolov5,yolov8,anchor-free,decoupled,head,目标检测)