yolov4的全面详解
一. 前言?
作者AlexeyAB大神!? YOLOv4? 擁有43.5%mAP+65FPS? ,達到了精度速度最優平衡,
作者團隊:Alexey Bochkovskiy&中國臺灣中央研究院
論文鏈接:
https://arxiv.org/pdf/2004.10934.pdf
代碼鏈接:
GitHub - AlexeyAB/darknet: YOLOv4 / Scaled-YOLOv4 / YOLO - Neural Networks for Object Detection (Windows and Linux version of Darknet )
————————————————
在講YOLOv4之前,先介紹一下兩個包:Bag of Freebies(免費包)和Bag-of-Specials(特贈包)
Bag of Freebies:指的是那些不增加模型復雜度,也不增加推理的計算量的訓練方法技巧,來提高模型的準確度
Bag-of-Specials:指的是那些增加少許模型復雜度或計算量的訓練技巧,但可以顯著提高模型的準確度
YOLOv4主要的貢獻:
? ?①構建了一個簡單且高效的目標檢測模型,該算法降低了訓練門檻,這使得普通人員都可以使用 1080Ti 或 2080 Ti GPU 來訓練一個超快,準確的(super fast and accurate)目標檢測器。
? ?②驗證了最先進的 Bag-of-Freebies 和 Bag-of-Specials 方法在訓練期間的影響
? ? ? ? ? ??BoF指的是
? ? ? ? ? ? ? ? ? ? ? ? 1)數據增強:圖像幾何變換(隨機縮放,裁剪,旋轉),Cutmix,Mosaic等
? ? ? ? ? ? ? ? ? ? ? ? 2)網絡正則化:Dropout,Dropblock等
? ? ? ? ? ? ? ? ? ? ? ? 3) 損失函數的設計:邊界框回歸的損失函數的改進?CIOU? ? ? ? ? ? ? ?
????????????BoS指的是
? ? ? ? ? ? ? ? ? ? ? ?1)增大模型感受野:SPP、ASPP等
? ? ? ? ? ? ? ? ? ? ? ?2)引入注意力機制:SE、SAM
? ? ? ? ? ? ? ? ? ? ? ?3)特征集成:PAN,BiFPN ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? ? ?4)激活函數改進:Swish、Mish
? ? ? ? ? ? ? ? ? ? ? 5)后處理方法改進:soft NMS、DIoU NMS
? ?③修改了最先進的方法,并且使其更為有效,適合單GPU訓練。包括 CBN,PAN, SAM等,從而使得 YOLO-v4 能夠在一塊 GPU 上就可以訓練起來。
二.yolov4的創新點
? ? ? 輸入端的創新點:訓練時對輸入端的改進,主要包括Mosaic數據增強、cmBN、SAT自對抗訓練
? ? ?BackBone主干網絡:各種方法技巧結合起來,包括:CSPDarknet53、Mish激活函數、Dropblock
? ? ??Neck:目標檢測網絡在BackBone和最后的輸出層之間往往會插入一些層,比如Yolov4中的SPP模塊、FPN+PAN結構
? ? ??Prediction:輸出層的錨框機制和Yolov3相同,主要改進的是訓練時的回歸框位置損失函數CIOU_Loss,以及預測框篩選的nms變為DIOU_nms
? 2.1輸入端創新
? ? ? ??Yolov4對訓練時的輸入端進行改進,使得訓練時在單張GPU上跑的結果也蠻好的。比如數據增強Mosaic、cmBN、SAT自對抗訓練。
? ?2.1.1數據增強
Yolov4中使用的Mosaic是參考2019年底提出的CutMix數據增強的方式,但CutMix只使用了兩張圖片進行拼接,而Mosaic數據增強則采用了4張圖片,隨機縮放、隨機裁剪、隨機排布的方式進行拼接。
?
為什么要進行Mosaic數據增強呢?
在平時項目訓練時,小目標的AP一般比中目標和大目標低很多。而Coco數據集中也包含大量的小目標,但比較麻煩的是小目標的分布并不均勻。Coco數據集中小目標占比達到41.4%,數量比中目標和大目標都要多。但在所有的訓練集圖片中,只有52.3%的圖片有小目標,而中目標和大目標的分布相對來說更加均勻一些。
針對這種狀況,Yolov4的作者采用了Mosaic數據增強的方式。
主要有2個優點:
? 2.1.2?cmBN?
深度學習中的BN_CBN_CMBN
BN:
反向傳播時經過該層的梯度是要乘以該層的參數的,即前向有:
?最后的?就是xi? 歸一化(BN)后的值,歸一化后所有值滿足均值為0方差為1
接著又進行了scale加上shift操作(y=scale*x+shift),每個神經元增加了兩個參數scale和shift參數,這兩個參數是通過訓練學習到的,意思是通過scale和shift把這個值從標準正態分布左移或者右移一點并長胖一點或者變瘦一點,每個實例挪動的程度不一樣,這樣等價于非線性函數的值從正中心周圍的線性區往非線性區移動。
在測試中使用BN:
在訓練中使用BN是要計算均值和方差的,而這兩個統計量是隨著樣本不同而變化的。如果在測試中依然遵循這樣的方式,那么無疑同一個樣本在不同的batch中預測會得到不一樣的概率值,這顯然是不對的。
在測試中,BN根據訓練過程中計算的均值和方差,使用滑動平均去記錄這些值。在測試的時候統一使用記錄下來的滑動平均值,這一點可以從源碼中看出來。所以在TensorFlow或者Pytorch中,BN的代碼分別有is_training 和 self.training字段,就是為了區別使用行為的。
舉個例子。(這里方差=標準差的平方)
在訓練過程的第t次迭代中,我們得到了均值u和方差。那么u和將使用如下方式保存下來。
初始化=1,=0,初始化=[0,0] ,方差=[1,1]? ,他們的的個數是與特征圖的channel深度相同的
?
CBN:
batch比較小時候,BN在batch維度統計不準確,導致準確率下降。在無法擴大batch訓練的前提下,CBN通過收集最近幾次迭代信息來更新當前迭代時刻的均值和方差,這樣就變向實現了擴大batch目的。我們知道在當前迭代時刻,參數已經更新了N次,存儲的前幾個迭代的參數肯定無法直接和當前迭代次數進行合并計算,也就是由于網絡權重的變化,不同迭代產生的網絡激活無法相互比較。故需要找到一種解決辦法。一種可行的方法就是利用當前和先前迭代的均值和方差。
然而t-次輪的統計值?和?對應的網絡權重是,當前輪的網絡權重是。因此,直接利用多次迭代的統計值進行估計,會使估計的統計量不準確,導致性能的明顯的下降。
對于某一層L,假設當前迭代時刻為t,則t-時刻中的統計量和,在第t時刻的參數,對于t-時刻的統計值,可以在處展開,為權重參數
?
CMBN:
CmBN的做法和前面兩個都不一樣,其把大batch內部的4個mini batch當做一個整體,對外隔離,主要改變在于BN層的統計量計算方面,具體流程是:假設當前是第t次迭代時刻,也是mini-batch的起點,
(1) 在第t時刻開始進行梯度累加操作
(2) 在第t時刻開始進行BN統計量匯合操作,這個就是和CBN的區別,CBN在第t時刻,也會考慮前3個時刻的統計量進行匯合,而CmBN操作不會,其僅僅在mini batch內部進行匯合操作
(3) 就是正常的應用BN,對輸入進行變換輸出即可
(4) 在mini batch的最后一個時刻,進行參數更新和可學習參數更新
可以明顯發現CmBN是CBN的簡化版本,其唯一差別就是在計算第t時刻的BN統計量時候,CBN會考慮前一個mini batch內部的統計量,而CmBN版本,所有計算都是在mini batch內部。有人認為這種做法是為了減少內存消耗,提高訓練速度,既然大家都是近似,差距應該不大,而且本身yolo訓練時候,batch也不會特別小,不至于是1-2,所以CmBN的做法應該是為了yolov4專門設計的,屬于實踐性改進。
Cmbn的過程:
?2.2?BackBone創新
Backbone:采用的主干網絡為 CSPDarknet53,CSPDarknet53是在Yolov3主干網絡Darknet53的基礎上,借鑒2019年CSPNet的經驗,產生的Backbone結構,其中包含了5個CSP模塊
每個CSP模塊前面的卷積核的大小都是3*3,stride=2,因此可以起到下采樣的作用。
因為Backbone有5個CSP模塊,輸入圖像是608*608,所以特征圖變化的規律是:608->304->152->76->38->19? ?經過5次CSP模塊后得到19*19大小的特征圖。而且作者只在Backbone中采用了Mish激活函數,網絡后面仍然采用Leaky_relu激活函數。? ? ? ? ? ?YOLOv3的主干網絡采用的是darknet53,yolov4的Backbone:采用的主干網絡為 CSPDarknet53
YOLOv4的作者是根據參考2019年的CSPNet的做法而改進的darknet53網絡
CSPNet論文地址:https://arxiv.org/pdf/1911.11929.pdf
CSPNet全稱是Cross Stage Paritial Network,主要從網絡結構設計的角度解決推理中從計算量很大的問題。
CSPNet的作者認為推理計算過高的問題是由于網絡優化中的梯度信息重復導致的。
這是因為類似于DenseNet的網絡一樣,更新權重的值反向傳播,會造成重復計算梯度
因此采用CSP模塊先將基礎層的特征映射劃分為兩部分,然后通過跨階段層次結構將它們合并,在減少了計算量的同時可以保證準確率。
Mish激活函數
Mish激活函數是2019年下半年提出的激活函數
論文地址:https://arxiv.org/abs/1908.08681
和Leaky_relu激活函數的圖形對比如下:
從圖中可以看出該激活函數,在負值時并不是完全截斷,而允許比較小的負梯度流入從而保證了信息的流動(因為梯度為負值時,作為relu激活函數,大多數神經元沒有更新)
mish激活函數無邊界,這讓他避免了飽和(有下界,無上界)且每一點連續平滑且非單調性,從而使得梯度下降更好。
Dropblock
Yolov4中使用的Dropblock,其實和常見網絡中的Dropout功能類似,也是緩解過擬合的一種正則化方式。
Dropblock在2018年提出,論文地址:https://arxiv.org/pdf/1810.12890.pdf
傳統的Dropout很簡單,一句話就可以說的清:隨機刪除減少神經元的數量,使網絡變得更簡單。
dropout主要作用在全連接層,而dropblock可以作用在任何卷積層之上
而Dropblock和Dropout相似,比如下圖:
中間Dropout的方式會隨機的刪減丟棄一些信息,但Dropblock的研究者認為,卷積層對于這種隨機丟棄并不敏感,因為卷積層通常是三層連用:卷積+激活+池化層,池化層本身就是對相鄰單元起作用。而且即使隨機丟棄,卷積層仍然可以從相鄰的激活單元學習到相同的信息。
因此,在全連接層上效果很好的Dropout在卷積層上效果并不好。
所以右圖Dropblock的研究者則干脆整個局部區域進行刪減丟棄。
這種方式其實是借鑒2017年的cutout數據增強的方式,cutout是將輸入圖像的部分區域清零,而Dropblock則是將Cutout應用到每一個特征圖。而且并不是用固定的歸零比率,而是在訓練時以一個小的比率開始,隨著訓練過程線性的增加這個比率。
在特征圖上一塊一塊的進行歸0操作,去促使網絡去學習更加魯棒的特征
為了保證Dropblock后的特征圖與原先特征圖大小一致,需要和dropout一樣,進行rescale操作
Dropblock的研究者與Cutout進行對比驗證時,發現有幾個特點:
優點一:Dropblock的效果優于Cutout
優點二:Cutout只能作用于輸入層,而Dropblock則是將Cutout應用到網絡中的每一個特征圖上
優點三:Dropblock可以定制各種組合,在訓練的不同階段可以修改刪減的概率,從空間層面和時間層面,和Cutout相比都有更精細的改進。
Yolov4中直接采用了更優的Dropblock,對網絡的正則化過程進行了全面的升級改進。
?2.3 Neck創新
在目標檢測領域,為了更好的提取融合特征,通常在Backbone和輸出層,會插入一些層,這個部分稱為Neck。相當于目標檢測網絡的頸部,也是非常關鍵的。
Yolov4的Neck結構主要采用了SPP模塊、FPN+PAN的方式
作者在SPP模塊中,使用k={1*1,5*5,9*9,13*13}的最大池化的方式,再將不同尺度的特征圖進行Concat操作。spp模塊是YOLOv4中在YOLOv3的基礎上加了的模塊,而PAN則也是YOLOv4的創新模塊。
YOLOv3中的neck只有自頂向下的FPN,對特征圖進行特征融合,而YOLOv4中則是FPN+PAN的方式對特征進一步的融合
下面是YOLOv3的neck中的FPN
如圖所示,FPN是自頂向下的,將高層的特征信息通過上采樣的方式進行傳遞融合,得到進行預測的特征圖。
而YOLOv4中的neck如下:
?FPN+PAN借鑒的是18年CVPR的PANet,當時主要應用于圖像分割領域,但Alexey將其拆分應用到Yolov4中,進一步提高特征提取的能力
?原本的PANet網絡的PAN結構中,兩個特征圖結合是采用shortcut操作,而Yolov4中則采用concat(route)操作,特征圖融合后的尺寸發生了變化
?2.4 檢測頭的loss創新
? ? ? 損失函數=box位置損失+類別損失+置信度損失
YOLO V4用CIOU損失代替了YOLOv3的box位置損失,取代了預測框和真實框的中心點坐標以及寬高信息設定MSE(均方誤差)損失函數或者BCE損失函數,其他部分損失沒改變
三.yolov4流程詳解
?3.1網絡結構圖
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?圖1 網絡結構
3.2 YOLOv4的方法
Yolo-v4:主要由三部分組成: Backbone,Neck和Head
3.2.1 Backbone
采用的主干網絡為 CSPDarknet53,CSPDarknet53是在Yolov3主干網絡Darknet53的基礎上,借鑒2019年CSPNet的經驗,產生的Backbone結構,其中包含了1個CBM和5個CSP模塊
骨干部分圖如下:
? ?①CBM:
? ? ? ?Yolov4網絡結構中的最小組件,由Conv+Bn+Mish激活函數三者組成。
② CSP模塊:
借鑒了CSPNet網絡結構,由CBM組件和X個Res unint模塊Concate組成。
第一個CSP模塊:由CBM組件和1個Res unint模塊Concate組成。
????????將CBM組件處理后的特征圖608*608*32的F_conv2傳入第一個CSP1模塊進行處理(其中只有1個殘差單元)
?第二個CSP模塊:由CBM組件和2個Res unint模塊Concate組成。
將第一個csp模塊處理后的304*304*64特征圖,傳入到第二個CSP模塊處理
????????同理經過下采樣后變成了152*152*128的特征圖,然后分別經過兩個1*1*64的s=1的卷積后得到兩個分支,其中一個分支的特征塊進入殘差模塊進行處理后,再與另一個分支進行拼接,最后第二個csp模塊的最后輸出是152*152*128 ? (殘差模塊中的卷積層:1*1*64和3*3*64)
?第三個CSP模塊:由8個Res unint模塊和CBM組件Concate組成。
????????將第二個csp模塊處理后的152*152*128的特征圖,傳入到第三個個CSP模塊處理
同理也是經過同樣的操作,最后第三個csp模塊的最后輸出是76*76*256 ? (殘差模塊中的卷積層:1*1*128和3*3*128),這個模塊后又分為兩個分支,一個分支繼續進行csp模塊處理,另一個分支直接進入到neck處理
第四個CSP模塊:由8個Res unint模塊和CBM組件Concate組成。
???????將第三個csp模塊的一個分支76*76*256的特征圖,傳入到第四個CSP模塊處理
?同理也是經過同樣的操作,最后第四個csp模塊的最后輸出是38*38*512 ? (殘差模塊中的卷積層:1*1*256和3*3*256),這個模塊后又分為兩個分支,一個分支繼續進行csp模塊處理,另一個分支直接進入到neck處理
第五個CSP模塊:由4個Res unint模塊和CBM組件Concate組成。
????????將第四個csp模塊的一個分支38*38*512的特征圖,傳入到第五個CSP模塊處理
同理也是經過同樣的操作,最后第五個csp模塊的最后輸出是19*19*1024 ?(殘差模塊中的卷積層:1*1*512和3*3*512),這個模塊輸出結果直接進入到neck處理
3.2.2?Neck:
特征增強模塊,主要由CBL組件,SPP模塊和FPN+PAN的方式組成
①?CBL組件:
由Conv+Bn+Leaky_relu激活函數三者組成?
將第五個csp4模塊的輸出結果19*19*1024的特征圖,傳入到CBL組件中處理
spp前后三個CBL組件是對稱的,它們的卷積分別是1*1*512,3*3*1024和1*1*512,步長都是1?
②SPP模塊:
采用1×1,5×5,9×9,13×13的最大池化的方式,進行多尺度融合
spp模塊采用的1×1 ,5×5 padding=5 // 2,9×9 padding=9 // 2,13×13 padding=13 // 2的最大池化的方式,進行多尺度融合,從前面三個CBL組件輸出的結果:19*19*512的特征圖,將之送入spp模塊中,最后的結果為19*19*2048,再經過三個CBL組件的卷積后得到19*19*512的特征圖?
③?FPN+PAN的結構:
PAN是借鑒圖像分割領域PANet的創新點
這樣結合操作,FPN層自頂向下傳達強語義特征,而PAN則自底向上傳達強定位特征,兩兩聯手,從不同的主干層對不同的檢測層進行參數聚合,加速了不同尺度特征的融合,進一步提高特征提取的能力。
3.2.3 Head:
?YoloHead利用獲得到的特征進行預測,是一個解碼的過程
? ?在特征利用部分,YoloV4提取多尺度特征進行目標檢測,一共提取三個特征層,分別位于中間層,中下層,底層,三個特征層的shape分別為(19,19,255),(38,38,255),(76,76,255) 在Yolov3的設計中,每個特征圖的每個格子中,都配置3個不同的先驗框,所以最后三個特征圖,這里暫且reshape為19 × 19 × 3 × 85、38 × 38 × 3 × 85、76 × 76 × 3 × 85,這樣更容易理解,在代碼中也是reshape成這樣之后更容易操作。 三張特征圖就是整個Yolo輸出的檢測結果,檢測框位置(4維)、檢測置信度(1維)、類別(80維)都在其中,加起來正好是85維。特征圖最后的維度85,代表的就是這些信息,而特征圖其他維度N × N × 3,N × N代表了檢測框的參考位置信息,3是3個不同尺度的先驗框。
①先驗框(anchor box) ? ?
? ? YOLO3采用了K-means聚類得到先驗框的尺寸,YOLO4延續了這種方法,為每種下采樣尺度設定3種先驗框,總共聚類出9種尺寸的先驗框。在COCO數據集中(原始圖片全部resize為608 × 608),九個框分別是 [[12, 16], [19, 36], [40, 28], [36, 75], [76, 55], [72, 146], [142, 110], [192, 243], [459, 401]],順序為w × h。 將前三個先驗框分配給76*76*255的特征圖,中間三個框分配給38*38*255的特征圖,最后三個框分配給19*19*255的特征圖
②解碼檢測框 ?
? ?有了先驗框與輸出特征圖后,就可以解碼檢測框 x,y,w,h。 ? ? 例如:(19,19,3,85),分別對應著19*19個網格,每個網格3種anchors,85=(x,y,w,h,confident),此時box的x,y是相對于網格的偏移量,所以還需要經過一些列的處理,處理方式見下圖:
?注意:σ(tx),σ(ty)是基于bbox框中心點左上角格點坐標的偏移量
③置信度解碼 ? ?
? ? 物體的檢測置信度,置信度在輸出85維中占固定一位,由sigmoid函數解碼即可,解碼之后數值區間在[0,1]中。
④類別解碼
? ?COCO數據集有80個類別,所以類別數在85維輸出中占了80維,每一維獨立代表一個類別的置信度。使用sigmoid激活函數替代了Yolov2中的softmax,取消了類別之間的互斥,可以使網絡更加靈活。
?⑤篩選預測框 ? ? ?
? ? 三個特征圖一共可以解碼出 19 × 19 × 3 + 38 × 38× 3 + 76 × 76 × 3 = 22743個box以及相應的類別、置信度。 首先,設置一個置信度閾值,篩選掉低于閾值的box,再經過DIOU_NMS(非極大值抑制)后,就可以輸出整個網絡的預測結果了。
DIOU_NMS的處理步驟如下: ?
1.遍歷圖片中所有識別出目標的類,對每個類的所有框進行單獨分析 ?
2.再將所有的狗的預測框按分數從大到小排序,如下圖;
?3.下一步,設狗類概率最大的框為target,依次比較它和其他非0框進行(IOU-DIOU)計算,如果計算結果大于設定的DIoU閾值(這里是ε=0.5),就將該框的狗的概率置為0,如下target和第二個框的(IOU-DIOU)明顯大于閾值0.5,所以舍去第二個框,把這個框的狗類概率設為0,如下圖;
?4.繼續掃描到第三個框,它與最大概率框的(IOU-DIOU)小于0.5,需要保留,繼續掃描后面的框,直到所有框都與最大概率框比較完畢為止。此時保留了不少框。 ? ?
5.接下來,以次大概率的框bb15(因為一開始排序過,它在順序上也一定是保留框中最靠近上一輪的基礎框的)為基礎,將它后面的其它框于之比較,如下圖:
? ?如果bb15框(次大概率的框)和bb7框的(IOU-DIOU)大于0.5,則可以剔除第4個框:把這個框的狗類概率設置為0?
?6. 假設在經歷了所有的掃描之后,對Dog類別只留下了兩個框,如下:
? ? 因為對計算機來說,圖片可能出現兩只Dog,保留概率不為0的框是安全的。不過代碼后續設置了一定的閾值(比如0.3)來刪除掉概率太低的框,這里的藍色框在最后并沒有保留,因為它在最后會因為閾值不夠而被剔除。?
7.上面描述了對Dog種類進行的框選擇。接下來,我們還要對其它79種類別分別進行上面的操作
8.?最后進行縱向跨類的比較(為什么?因為上面就算保留了最大概率的Dog框,但該框可能在Cat的類別也為概率最大且比Dog的概率更大,那么我們最終要判斷該框為Cat而不是Dog)。判定流程和法則如下:
最后保留的預測框就是最終呈現的預測框?
⑥Yolo-v4:損失函數?
?損失函數=box位置損失+類別損失+置信度損失
YOLO V4用CIOU損失代替了YOLOv3的box位置損失,取代了預測框和真實框的中心點坐標以及寬高信息設定MSE(均方誤差)損失函數或者BCE損失函數,其他部分損失沒改變
具體詳解參考:目標檢測中的IoU、GIoU、DIoU與CIoU_Runist blog-CSDN博客
? ? ? ? ? ? ? 深入淺出Yolo系列之Yolov3&Yolov4&Yolov5&Yolox核心基礎知識完整講解 - 知乎
則:
位置損失
目標檢測的一項重要任務就是確定目標的位置,即(x, y, h, w),所以損失值的計算中包含位置損失CIOU損失 (考慮了長和寬的比值)
置信度損失
置信度損失分為兩個部分,有目標的置信度損失,無目標的置信度損失
置信度損失:采用二元交叉熵損失
有目標的置信度損失:
?無目標的置信度損失:
?所以綜上19*19*255的特征圖的損失Loss1
Yolov4 總Loss為三個特征圖Loss之和:
?參考鏈接:YOLO V4 — 網絡結構和損失函數解析(超級詳細!) - 知乎
最后:
與 SOTA 方法的比較:
參考鏈接:深入淺出Yolo系列之Yolov3&Yolov4&Yolov5&Yolox核心基礎知識完整講解 - 知乎
參考鏈接:YOLOv4 之CBN速讀(Cross Iteration Batch Normalization) - 知乎
參考鏈接:?想讀懂YOLOV4,你需要先了解下列技術(二) - 知乎
參考鏈接:?【論文解讀】Yolo三部曲解讀——Yolov3 - 知乎
參考鏈接:YOLO v3代碼解讀3 - 知乎
參考鏈接:深度學習論文翻譯解析(二十):YOLOv4: Optimal Speed and Accuracy of Object Detection - 戰爭熱誠 - 博客園
參考鏈接:BiFPN_申小隆的博客-CSDN博客_bifpn
總結
以上是生活随笔為你收集整理的yolov4的全面详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 解决:RuntimeError: CUD
- 下一篇: HTTP请求消息数据格式分析以及requ