YOLO内卷时期该如何选模型?

语言: CN / TW / HK

关注公众号,发现CV技术之美

本篇文章来自知乎,作者:迪迦奥特曼,原地址:http://zhuanlan.zhihu.com/p/566469003

前两天看到了美团微信公众号上的宣传,更新发布了新版YOLOv6,还放出了arxiv论文。更新了之前的N/T/S小模型,也放出了M和L版本的大模型,论文实验表格多达十几个,看打出来是很用心的做了,个人觉得也算对得起这个名字了(官方认不认暂且不说)。

之前本人写了一个YOLO合集的文章《 迪迦奥特曼:从百度飞桨YOLOSeries库看各个YOLO模型  》,对YOLOv6介绍的不多,毕竟那时候YOLOv6还是第一版被全网黑的时候,现在还是先重新来具体具体分析下这个全新版YOLOv6。此外想聊聊关于怎么选YOLO模型去训业务数据集的一些感想。

       01       

YOLOv6模块分析

YOLOv6结构图镇楼:

Backbone:

  • 对于N/T/S版本的小模型,采用EfficientRep,也就是第一版v6的结构;

  • 对于M/L版本的大模型,采用CSPBepBackbone,是借鉴CSP思想这次新加的;

图虽然直观但是不全,具体还是看代码好理解。可以看出两个backbone差别只在于基础模块block用的不同,一个 是RepBlock一个是BepC3,此外还有一个通道划分因子csp_e区别。

  • http://github.com/meituan/YOLOv6/blob/main/yolov6/models/efficientrep.py#L37

  • http://github.com/meituan/YOLOv6/blob/main/yolov6/models/efficientrep.py#L142

核心模块还是RepVGG,今年的yoloe、yolov6、yolov7都相继使用了,只是使用范围幅度不一。

有意思的是v6做了实验对比RepBlock和CSPStackRepBlock,CSP形式确实大大的减少了参数量FLOPs。也难怪要新设计CSPStackRep,v6-M上看原先RepBlock结构参数量计算量简直大到爆炸。CSP形式在小模型上表现不太行,但是v6-M的2/3设置又有点诡异。

Neck:

基于YOLOv5 YOLOX的PAFPN结构也进行了改进:

  • 对于N/T/S版本的小模型,采用RepBlock替换CSPBlock;

  • 对于M/L版本的大模型,采用CSPStackRepBlock进行替换;

同样也是一个是RepBlock一个是BepC3,此外还有一个通道划分因子csp_e区别。

  • http://github.com/meituan/YOLOv6/blob/main/yolov6/models/reppan.py#L23

  • http://github.com/meituan/YOLOv6/blob/main/yolov6/models/reppan.py#L148

Head和loss:

新版使用的是像TDDO Head那样的形式,使用ATSS assign作为warmup,后期使用TAL assign,相比第一版几乎就YOLOX的head算好的了。然而之前瞄到了 [yoloseries](http://github.com/nemonameless/PaddleDetection_YOLOSeries) 库里的paddle yolov6的复现,简直和PPYOLOE head是一模一样,包括assign过程和loss过程甚至还有各种命名。怀疑yoloseries作者就是复制PPYOLOE head过来再改成v6 head的哈哈哈。

本来看v6原版代码的时候就感觉很像yoloe,不过v6 head区别在于没有用到PPYOLOE里的ESEAttn注意力,分类回归v6也有公用stem,而PPYOLOE里是分离的stem。估计各家为什么这么设计也是实验证明过的吧,都有自己的道理。此外v6 head还有distill的部分loss,算是自己的特色trick刷点来看还是很有用的。

  • 原版v6 head:http://github.com/meituan/YOLOv6/blob/main/yolov6/models/effidehead.py

  • 库里的v6 head的实现,包括loss:http://github.com/nemonameless/PaddleDetection_YOLOSeries/blob/release/2.5/ppdet/modeling/heads/effide_head.pyyoloseries

  • PaddleDetection的ppyoloe head的实现,包括loss:http://github.com/PaddlePaddle/PaddleDetection/blob/develop/ppdet/modeling/heads/ppyoloe_head.py

  • 原版v6 head loss:http://github.com/meituan/YOLOv6/blob/main/yolov6/models/loss.py

       02       

YOLOv6总体设计

看总体设计还是看代码配置文件。但其实v6的配置很不统一,包括之前v7也是不统一,都像是每个模型单独调优。看到yoloseries库的作者的总结:

  • YOLOv6 n t s 模型使用EfficientRep和RepPAN,YOLOv6 m l 模型使用CSPBepBackbone和CSPRepPAN,Params(M)和FLOPs(G)均为训练时所测;

  • YOLOv6 m l 模型训练默认使用蒸馏自监督辅助训练,且使用dfl_loss和设置reg_max=16,其余n t s 模型则未使用;

  • YOLOv6 l 模型原文默认激活函数为silu,其余n t s m模型则默认为relu;

  • YOLOv6 n t 模型原文训练默认会使用到siou loss,其余s m l模型则默认使用到giou loss;

此外还有优化器一些参数的不同吧太琐碎了。以前用习惯了yolov5 yolox的配置,大模型和小模型差别就改个width depth参数,yoloe也是这样,就很方便和统一。虽然有实验证明大模型小模型用哪个好,但是这样的设置每个模型单独调优就只为了争0.几的mAP也位面太麻烦了,而且只是COCO数据集的mAP,模型原模原样重训两遍0.3以内的mAP波动都还算正常的。

自监督蒸馏是一个v6的特色,涨点很多如下表,之前yolov7的1280 P6大尺度模型也使用了辅助头蒸馏,是个不错的trick。总的来看,自监督至少有1.0+ mAP的增益。

指标分析:

精度上看,v6确实足够高了,但这其中也包含一些猫腻。比如L版本默认换成了silu,不和N/T/S/M的relu统一了,虽然单列了一个L-relu,估计是速度够快了为了再加强些精度再训的silu版本,乍一看Model Zoo还以为所有模型都是silu只是L单独训了一个relu的。。速度上看relu真的测速度会更快的多!在第一版发布的时候早有大佬说过,论文中也证明了。

此外还有很多表格对比实验验证,这也是各个模型配置文件不统一的主要原因。小模型可能siou更适合,tiny第一版是depth=0.25 width=0.50,现在改成了depth=0.33 width=0.375正常配置,掉了点精度换的了参数量更小速度更快。

此外大模型M和L的自监督蒸馏提了不少点,其中M的depth是0.6而不是常用的0.67,而最诡异的是调个通道划分因子csp_e就能涨0.8之多。最后没有像v7 v5那样有大模型X版本和1280尺度有点遗憾,可能参数量flops过大,精度性价比不高了。

根据上述表格,本人抽空整理了下的最常用的S和L版本的几个YOLO模型的数据,按发布时间顺序,供大家参考:

注意:速度由于各个YOLO的平台环境不同,甚至版本和框架不同都会有影响,实际还是得自己实测,也要注意几次测波动不同也是正常的。

怎么选模型:

今年堪称YOLO内卷元年,先是yolov5 yolox yoloe神仙打架,各大用户用的正欢,一看美团v6出来了哇新yolo马上就换v6,再一看v7出来了立马再换v7,再一看v6又更新了精度更高再重新换v6,很多时候就是在来回折腾,数据量少重训一遍还好,数据量大简直就像扛着炸药包折返跑,训完了新的精度搞不好还低了。

所以在这样的内卷期,作为普通用户我们应该怎么选择模型呢?个人发表一点拙见。首先需要明确自己项目的要求和标准,精度和速度一般是最重要的两个指标,另外还有模型参数量、计算量等等,注意这些还都必须在自己项目的设备上为前提。

1.首先是精度, 一看各家YOLO首页的折线图就知道了,都是恨不得自己一条最高全面压住所有对手,当然这也是各家的主要卖点。这个复现也是最有保证的。但是我想说的是,虽然各家都会刷权威的COCO精度,但真到业务数据集上的时候,效果哪个高就不一定了,尤其是COCO精度差距在1.0以内的模型,其实选哪个都行,再说也不能纯看mAP,还有ap50 ap75 recall等指标呢。

训业务数据要高精度,最重要是一点是加载超强的pretrain权重!!!这个恐怕还是很多新手不知道的。COCO预训练可以极快收敛并达到比imagenet-pretrain训更高的精度,一个超强pretrain顶过绝大多数小修小改的tricks。之前yoloe也更新了一版yoloe plus也叫yoloe+,放出了objects 365预训练,这个简直是超级外挂,全量coco只训80epoch刷的超高,我用了之后自己数据集相比加载原先coco预训练涨了5个点mAP!还是缩短一半训练epoch的情况下。

之后还要训一个20万张图的数据集,比coco量级还大的时候coco预训练就不够用了,训300epoch甚至80epoch都和蜗牛一样慢,而obj365预训练正好派上用场估计训30epoch就行。此外自监督半监督等策略,确实是可以提精度,作为大厂自己PR还是可以的,但是就用户使用而言可能会有点鸡肋麻烦,有点耗时耗资源。

2.其次是第二卖点速度 ,这个不像精度很快就能跑复现证明的,鉴于各大YOLO发布的测速环境也不同,还是得自己实测过才知道。另外各大YOLO发布的速度只是去NMS去预处理的纯模型速度,真正使用还是需要加上NMS和预处理的,NMS的参数对速度影响极大,尤其是score threshold还有top k keep k。

score threshold一般为了拉高recall都会设置0.001 0.01之类的,这种范围的低分框其实没什么用,NMS阶段会极大的浪费时间。但是调成0.1 0.2速度就飙升了,不过代价是掉一些mAP。而调top k keep k也会影响速度,尤其top k,但是都对mAP影响较小,具体可以自己实践。总之实际应用需要自己实践不能只看论文速度,并且是算上NMS的耗时的,而NMS耗时又是自己可控的。

3.然后是计算量参数量 ,这个一般不会着重考虑,但也不能太离谱毕竟有些设备还是有限制,堆模块改成原版两倍3倍级别换来一点点mAP的提升是AI竞赛常用的套路,而且一般会牺牲些速度,意义不大。另外还有些特殊模块,比如ConvNeXt 参数量极大但是FLOPs很小,会掉速度,可以刷点但也意义不大。csp形式的设计极大的降低了参数量FLOPs,也许以后新模块都可以设计个csp_xxx去使用哈哈

总之,YOLO内卷时期要保持平常心,针对自己的需求,选准适合自己的模型。

相关引用链接:

  • YOLOv6论文:http://arxiv.org/abs/2209.02976

  • YOLOv6代码:http://github.com/meituan/YOLOv6

  • YOLOSeries代码:http://github.com/nemonameless/PaddleDetection_YOLOSeries

  • PPYOLOE论文:http://arxiv.org/abs/2203.16250

  • PaddleDetection代码:http://github.com/PaddlePaddle/PaddleDetection

END

欢迎加入「目标检测 交流群:point_down:备注: OD

「其他文章」