YOLO內卷時期該如何選模型?

語言: CN / TW / HK

關注公眾號,發現CV技術之美

本篇文章來自知乎,作者:迪迦奧特曼,原地址:https://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區別。

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

  • https://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區別。

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

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

Head和loss:

新版使用的是像TDDO Head那樣的形式,使用ATSS assign作為warmup,後期使用TAL assign,相比第一版幾乎就YOLOX的head算好的了。然而之前瞄到了 [yoloseries](https://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:https://github.com/meituan/YOLOv6/blob/main/yolov6/models/effidehead.py

  • 庫裡的v6 head的實現,包括loss:https://github.com/nemonameless/PaddleDetection_YOLOSeries/blob/release/2.5/ppdet/modeling/heads/effide_head.pyyoloseries

  • PaddleDetection的ppyoloe head的實現,包括loss:https://github.com/PaddlePaddle/PaddleDetection/blob/develop/ppdet/modeling/heads/ppyoloe_head.py

  • 原版v6 head loss:https://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論文:https://arxiv.org/abs/2209.02976

  • YOLOv6程式碼:https://github.com/meituan/YOLOv6

  • YOLOSeries程式碼:https://github.com/nemonameless/PaddleDetection_YOLOSeries

  • PPYOLOE論文:https://arxiv.org/abs/2203.16250

  • PaddleDetection程式碼:https://github.com/PaddlePaddle/PaddleDetection

END

歡迎加入「目標檢測 交流群:point_down:備註: OD

「其他文章」