Yolo系列知识点梳理(Yolov1-v5)
文章目錄
- 1 概述
- 2 Yolo系列模型
- 2.1 基石 - Yolov1
- 2.1.1 Yolov1的網(wǎng)絡(luò)結(jié)構(gòu)
- 2.1.2 Yolov1的feature map
- 2.1.3 Yolov1的訓(xùn)練
- 2.1.4 Yolov1的預(yù)測(cè)
- 2.1.5 Yolov1小結(jié)
- 2.2 Yolo9000 - Yolov2
- 2.2.1 Better
- 2.2.1.1 引入了Batch normalization
- 2.2.1.2 高分辨率的分類(lèi)器
- 2.2.1.3 加入了anchor機(jī)制
- 2.2.1.4 loss的改動(dòng)
- 2.2.1.5 Fine-Grained Features
- 2.2.1.6 多尺度訓(xùn)練
- 2.2.2 Faster
- 2.2.3 Stronger
- 2.3 一小步 - Yolov3
- 2.4 技巧 - Yolov4
- 2.4.1 網(wǎng)絡(luò)結(jié)構(gòu)的改進(jìn)
- 2.4.1.1 backbone中的激活函數(shù)改為Mish
- 2.4.1.2 backbone中的殘差模塊改成了CSP
- 2.4.1.3 detector中的新增了SPP模塊
- 2.4.1.4 detector中特征尺度的變化
- 2.4.2 損失函數(shù)的改進(jìn)
- 2.4.3 nms的改進(jìn)
- 2.4.4 其他
- 2.5 又一小步 - Yolov5
- 2.5.1 網(wǎng)絡(luò)結(jié)構(gòu)的改進(jìn)
- 2.5.1.1 添加了CSP2模塊
- 2.5.2 其他
- 3 結(jié)束語(yǔ)
- 參考資料
1 概述
Yolo系列的模型是大多數(shù)做目標(biāo)檢測(cè)的圖像算法工程師都在使用的,使用時(shí)經(jīng)常也是先用了看看效果再說(shuō),如果效果不錯(cuò),有時(shí)間再回頭來(lái)研究一下模型,有時(shí)甚至就忘了回過(guò)頭來(lái)細(xì)究。這篇文章就是一個(gè)回頭的產(chǎn)物。
Yolo的每一個(gè)系列都令人驚艷,本文綜合了原始論文和網(wǎng)上各家的一些說(shuō)法,把Yolo每個(gè)系列究竟產(chǎn)出了一些什么做一個(gè)系統(tǒng)的梳理,也方便我以后的再回頭。
如果Yolo之后有人繼續(xù)更新下去,本文也會(huì)盡量做到繼續(xù)更新。
文中的圖片都出自參考資料,非本人原創(chuàng)。
2 Yolo系列模型
2.1 基石 - Yolov1
Yolov1是目標(biāo)檢測(cè)中one-stage方法的開(kāi)山之作,它不同于two-stage需要先過(guò)一個(gè)RPN網(wǎng)絡(luò)得到候選區(qū)域的方法,yolo直接在整張圖的feature map上進(jìn)行目標(biāo)的定位和分類(lèi),因此速度也比當(dāng)時(shí)正紅的Fast R-CNN快很多。而且,也正是因?yàn)?strong>yolo看的是全局的信息,yolo把背景誤判成目標(biāo)的錯(cuò)誤率比只看proposals的Fast R-CNN低很多。不過(guò)整體的準(zhǔn)確率,還是Fast R-CNN高。
2.1.1 Yolov1的網(wǎng)絡(luò)結(jié)構(gòu)
Yolov1的網(wǎng)絡(luò)結(jié)構(gòu)如下圖所示,并不復(fù)雜,輸入是448×448×3448\times448\times3448×448×3的圖片,輸出是一個(gè)7×7×307\times7\times307×7×30的feature map。網(wǎng)絡(luò)中共有24個(gè)全卷積和尾部的2個(gè)全連接,其中用到了大量的1×11\times11×1卷積用來(lái)改變通道數(shù),當(dāng)然也有融合通道之間特征的作用。這里最后用的兩層全連接其實(shí)今天看來(lái)有點(diǎn)不解,后面的版本就沒(méi)有用了。這個(gè)網(wǎng)絡(luò)結(jié)構(gòu)就是大名鼎鼎的Darknet。
網(wǎng)絡(luò)的卷積層在ImageNet上用分類(lèi)任務(wù)進(jìn)行了預(yù)訓(xùn)練,使得卷積層可以抽到比較好的圖像特征,但是預(yù)訓(xùn)練時(shí)的輸入圖像為224×224224\times224224×224的,這其實(shí)會(huì)有點(diǎn)問(wèn)題,在訓(xùn)練檢測(cè)模型時(shí),輸入為448×448448\times448448×448,模型需要去適應(yīng)這種分辨率的轉(zhuǎn)換,對(duì)結(jié)果是有影響的,這個(gè)在之后的版本會(huì)優(yōu)化。
2.1.2 Yolov1的feature map
我們?cè)賮?lái)看下Yolov1輸出的7×7×307\times7\times307×7×30的feature map,其中7×77\times77×7是經(jīng)過(guò)層層全卷積和全連接之后下采樣得到的結(jié)果,每個(gè)grid對(duì)應(yīng)著原圖上相應(yīng)位置的一塊區(qū)域,可以理解為將448×448448\times448448×448的輸入長(zhǎng)寬都等分為了7份,共有49個(gè)grids。
每個(gè)grid都對(duì)應(yīng)了一個(gè)長(zhǎng)度為30的向量,準(zhǔn)確來(lái)說(shuō)應(yīng)該是一個(gè)2×5+202\times5+202×5+20的向量,其中2表示2個(gè)預(yù)測(cè)框;5表示每個(gè)預(yù)測(cè)框的[xcenter,ycenter,w,h,confidence][x_{center}, y_{center}, w, h, confidence][xcenter?,ycenter?,w,h,confidence],confidenceconfidenceconfidence指的是這個(gè)預(yù)測(cè)框內(nèi)目標(biāo)的置信度Pr(Object)×IOUpredtruthPr(Object) \times IOU_{pred}^{truth}Pr(Object)×IOUpredtruth?,當(dāng)沒(méi)有物體時(shí),Pr(Object)=0Pr(Object)=0Pr(Object)=0,confidence=0confidence=0confidence=0,當(dāng)有物體時(shí),confidence=IOUpredtruthconfidence=IOU_{pred}^{truth}confidence=IOUpredtruth?;20表示20種目標(biāo)類(lèi)別的置信度,表示為Pr(Classi∣Object)Pr(Class_i|Object)Pr(Classi?∣Object)。
在預(yù)測(cè)時(shí),最終某個(gè)框內(nèi)表示了某個(gè)目標(biāo)的置信度為confidence×Pr(Classi∣Object)confidence \times Pr(Class_i|Object)confidence×Pr(Classi?∣Object)。
寫(xiě)一個(gè)一目了然版的就是某個(gè)grid的30維向量為
[xc1,yc1,w1,h1,confidence1,xc2,yc2,w2,h2,confidence2,cate1,...,cate20][x_{c1}, y_{c1}, w_1, h_1, confidence_1, x_{c2}, y_{c2}, w_2, h_2, confidence_2, cate_1, ..., cate_{20}] [xc1?,yc1?,w1?,h1?,confidence1?,xc2?,yc2?,w2?,h2?,confidence2?,cate1?,...,cate20?]
如果要知道某個(gè)grid第一個(gè)框表示cate1cate_1cate1?這個(gè)目標(biāo)的概率,則為confidence1×cate1confidence_1 \times cate_1confidence1?×cate1?。
仔細(xì)一想,會(huì)發(fā)現(xiàn)每個(gè)grid只能表示一個(gè)物體,confidenceiconfidence_iconfidencei?代表了有沒(méi)有物體和用哪個(gè)預(yù)測(cè)框,cateicate_icatei?表示了這個(gè)物體是哪個(gè)目標(biāo)類(lèi)別。也就是7×77\times77×7的feature map最多只能預(yù)測(cè)出49個(gè)目標(biāo),這對(duì)小目標(biāo)和相鄰多目標(biāo)很不友好。
2.1.3 Yolov1的訓(xùn)練
訓(xùn)練部分只講和loss相關(guān)的內(nèi)容,其他的和Yolo本身關(guān)系不大,都是標(biāo)準(zhǔn)的pipeline。
訓(xùn)練時(shí),我們的label是每張圖片多個(gè)檢測(cè)框坐標(biāo)和對(duì)應(yīng)的物體類(lèi)別。每個(gè)物體都會(huì)落在7×77\times77×7的feature map中的某一個(gè)格子里,落到哪個(gè)格子里,那么那個(gè)格子里就負(fù)責(zé)預(yù)測(cè)這個(gè)物體。而每個(gè)格子又有兩個(gè)框,就取其中和真實(shí)物體的bbox的iou較大的那個(gè)預(yù)測(cè)框作為負(fù)責(zé)這個(gè)物體的預(yù)測(cè)框。這里負(fù)責(zé)的意思就是算loss的時(shí)候拿負(fù)責(zé)的框去算loss。
loss共由五個(gè)部分組成:
(1)中心定位誤差
就是負(fù)責(zé)這個(gè)物體的檢測(cè)框的中心點(diǎn)坐標(biāo)和這個(gè)物體真實(shí)的中心點(diǎn)坐標(biāo)差多少。
L1=∑i=0S2∑j=0BIijobj((xi?x^i)2+(yi?y^i)2)(2-1)L_1 = \sum_{i=0}^{S^2} \sum_{j=0}^{B} \mathbb{I}_{ij}^{obj} ((x_i - \hat{x}_i)^2 + (y_i - \hat{y}_i)^2)\tag{2-1} L1?=i=0∑S2?j=0∑B?Iijobj?((xi??x^i?)2+(yi??y^?i?)2)(2-1)
其中,S2S^2S2表示7×77\times77×7的feature map的格子的集合;BBB表示每個(gè)格子中bbox的集合;Iijobj\mathbb{I}_{ij}^{obj}Iijobj?是一個(gè)指示函數(shù),表示第iii個(gè)格子的第jjj個(gè)框負(fù)責(zé)預(yù)測(cè)真實(shí)物體時(shí)進(jìn)行后面的計(jì)算,否則為0;xix_ixi?和yiy_iyi?是ground truth的中心點(diǎn)坐標(biāo);x^i\hat{x}_ix^i?和y^i\hat{y}_iy^?i?是負(fù)責(zé)這個(gè)物體的預(yù)測(cè)框的中心坐標(biāo)。
(2)寬高誤差
就是負(fù)責(zé)這個(gè)物體的檢測(cè)框的寬高和這個(gè)物體真實(shí)的寬高差多少。
L2=∑i=0S2∑j=0BIijobj((wi?w^i)2+(hi?h^i)2)(2-2)L_2 = \sum_{i=0}^{S^2} \sum_{j=0}^{B} \mathbb{I}_{ij}^{obj} ((\sqrt{w_i} - \sqrt{\hat{w}_i})^2 + (\sqrt{h_i} - \sqrt{\hat{h}_i})^2)\tag{2-2} L2?=i=0∑S2?j=0∑B?Iijobj?((wi???w^i??)2+(hi???h^i??)2)(2-2)
其中,wiw_iwi?和hih_ihi?是ground truth的寬高;w^i\hat{w}_iw^i?和h^i\hat{h}_ih^i?是負(fù)責(zé)這個(gè)物體的預(yù)測(cè)框的寬高。其他符號(hào)和L1L_1L1?中相同。
(3)正樣本confidence誤差
保證負(fù)責(zé)物體的預(yù)測(cè)框的confidence接近1。
L3=∑i=0S2∑j=0BIijobj(Ci?C^i)2(2-3)L_3 = \sum_{i=0}^{S^2} \sum_{j=0}^{B} \mathbb{I}_{ij}^{obj} (C_i - \hat{C}_i)^2\tag{2-3} L3?=i=0∑S2?j=0∑B?Iijobj?(Ci??C^i?)2(2-3)
其中,CiC_iCi?表示這個(gè)格子內(nèi)有物體中心的標(biāo)簽,C^i\hat{C}_iC^i?表示這個(gè)格子內(nèi)有物體中心的置信度。
(4)負(fù)樣本confidence誤差
保證不負(fù)責(zé)物體的預(yù)測(cè)框的confidence接近0。
L4=∑i=0S2∑j=0BIijnoobj(Ci?C^i)2(2-4)L_4 = \sum_{i=0}^{S^2} \sum_{j=0}^{B} \mathbb{I}_{ij}^{noobj} (C_i - \hat{C}_i)^2\tag{2-4} L4?=i=0∑S2?j=0∑B?Iijnoobj?(Ci??C^i?)2(2-4)
其中,Iijnoobj\mathbb{I}_{ij}^{noobj}Iijnoobj?是一個(gè)指示函數(shù),表示第iii個(gè)格子的第jjj個(gè)框不負(fù)責(zé)預(yù)測(cè)真實(shí)物體時(shí)進(jìn)行后面的計(jì)算,否則為0。
(5)類(lèi)別誤差
表示負(fù)責(zé)預(yù)測(cè)的格子內(nèi)的類(lèi)別誤差。
L5=∑i=0S2Iiobj∑c∈classes(pi(c)?p^i(c))2(2-5)L_5 = \sum_{i=0}^{S^2} \mathbb{I}_{i}^{obj} \sum_{c \in classes}(p_i(c) - \hat{p}_i(c))^2\tag{2-5} L5?=i=0∑S2?Iiobj?c∈classes∑?(pi?(c)?p^?i?(c))2(2-5)
其中,Iiobj\mathbb{I}_{i}^{obj}Iiobj?是一個(gè)指示函數(shù),表示第iii個(gè)格子的負(fù)責(zé)預(yù)測(cè)真實(shí)物體時(shí)進(jìn)行后面的計(jì)算,否則為0;pi(c)p_i(c)pi?(c)表示第iii個(gè)格子第ccc個(gè)類(lèi)別的標(biāo)簽;p^i(c)\hat{p}_i(c)p^?i?(c)表示第iii個(gè)格子第ccc個(gè)類(lèi)別的置信度。
綜合,(2?1)?(2?5)(2-1)-(2-5)(2?1)?(2?5)就有
L=λcoordL1+λcoordL2+L3+λnoobjL4+L5(2-6)L = \lambda_{coord}L_1 + \lambda_{coord}L_2 + L_3 + \lambda_{noobj}L_4 + L_5 \tag{2-6} L=λcoord?L1?+λcoord?L2?+L3?+λnoobj?L4?+L5?(2-6)
其中,λcoord\lambda_{coord}λcoord?和λnoobj\lambda_{noobj}λnoobj?是可以用來(lái)調(diào)整的超參數(shù),也就是各個(gè)loss的權(quán)重。不難看出Yolov1把目標(biāo)檢測(cè)看成了一個(gè)回歸問(wèn)題。
2.1.4 Yolov1的預(yù)測(cè)
預(yù)測(cè)部分沒(méi)啥說(shuō)的,就是對(duì)得到的98個(gè)預(yù)測(cè)框進(jìn)行一個(gè)閾值的篩選之后,再做nms。
2.1.5 Yolov1小結(jié)
優(yōu)點(diǎn):
(1)速度快
(2)考慮圖片的全局特征,precision較高
缺點(diǎn):
(1)每個(gè)格子只能預(yù)測(cè)一個(gè)物體,對(duì)密集型的物體檢測(cè)不友好
(2)下采樣次數(shù)多,最終所使用的特征比較粗糙
2.2 Yolo9000 - Yolov2
Yolov2在Yolov1的基礎(chǔ)上有很大的改動(dòng),這一節(jié)就針對(duì)改進(jìn)部分依次說(shuō)明。
2.2.1 Better
2.2.1.1 引入了Batch normalization
BN是一個(gè)非常有用的模塊,其有點(diǎn)如下:
- 加快收斂
- 改善梯度,遠(yuǎn)離飽和區(qū)
- 允許大的學(xué)習(xí)率
- 對(duì)初始化不敏感
- 相當(dāng)于正則化,使得有BN層的輸入都有相近的分布
有了BN之后,就可以不用dropout了,或者說(shuō)不能像原來(lái)一樣用dropout了,這會(huì)導(dǎo)致訓(xùn)練和測(cè)試的方差偏移,可以參看文獻(xiàn)[5]。
2.2.1.2 高分辨率的分類(lèi)器
Yolov1當(dāng)中對(duì)backbone做預(yù)訓(xùn)練的時(shí)候,用的是224×224224\times224224×224的輸入,而yolov1為了高分辨率用的是448×448448\times448448×448的輸入,這樣就導(dǎo)致了模型要去適應(yīng)這個(gè)分辨率的轉(zhuǎn)換。于是,Yolov2干脆直接用448×448448\times448448×448的輸入預(yù)訓(xùn)練backbone了。這樣帶來(lái)了幾乎4%mAP的提升。這種簡(jiǎn)單而高效且不用增加預(yù)測(cè)負(fù)擔(dān)的方法是我們最喜歡的。
2.2.1.3 加入了anchor機(jī)制
在Yolov1中沒(méi)有anchor的概念,所以7×77\times77×7的feature map中預(yù)測(cè)的兩個(gè)預(yù)測(cè)框都是野蠻生長(zhǎng)的,這兩個(gè)預(yù)測(cè)框很有可能就長(zhǎng)的差不多,而且這樣去學(xué)習(xí)不同形狀的物體,對(duì)模型來(lái)說(shuō)是比較困難的。
所以,Yolov2刪去了最后的全連接層,引入了anchor機(jī)制。Yolov2的輸入變成了416×416416 \times 416416×416,feature map大小為13×1313\times1313×13,每個(gè)格子有5個(gè)anchors,每個(gè)anchor的長(zhǎng)寬大小和比例不同,各司其職,負(fù)責(zé)不同形狀的物體。有了anchor之后,模型就不需要直接去預(yù)測(cè)物體框的長(zhǎng)寬了,只需要預(yù)測(cè)偏移量就可以了,這相對(duì)來(lái)說(shuō)降低了難度。
這里提一句,之所以從448×448448 \times 448448×448變成416×416416 \times 416416×416就是為的使得feature map的size是一個(gè)奇數(shù)。這樣的好處是,許多圖片的中心點(diǎn)都是某個(gè)物體的中心,奇數(shù)保證中間是一個(gè)格子,而不是偶數(shù)那樣四個(gè)格子搶占中心點(diǎn)。
圖3 Yolov2的anchor形狀示意圖不過(guò)引入anchor也有不好的地方,本來(lái)不用anchor的時(shí)候,預(yù)測(cè)出來(lái)只有98個(gè)框,現(xiàn)在有845個(gè)框了,從最終結(jié)果來(lái)看,precision略有下降了,不過(guò)recall變高了許多。
圖4 Yolov2的anchor輸出示意圖Yolov1的輸出是一個(gè)7×7×307 \times 7 \times 307×7×30的,Yolov2的輸出是一個(gè)13×13×12513 \times 13 \times 12513×13×125,其中125=(5+20)×5125 = (5 + 20) \times 5125=(5+20)×5。括號(hào)里的555表示xi,yi,wi,hi,confix_i,y_i,w_i,h_i,conf_ixi?,yi?,wi?,hi?,confi?,202020表示每個(gè)類(lèi)別的概率,共20個(gè)類(lèi)別,最后的555表示555個(gè)預(yù)測(cè)框。圖4表示的非常清楚了。
可以看出,同一個(gè)格子里的每個(gè)預(yù)測(cè)框的類(lèi)別是可以不同的,一個(gè)格子可以預(yù)測(cè)5個(gè)物體了。
圖5 Yolov2的anchor聚類(lèi)示意圖那么這5個(gè)anchor的預(yù)錨框是怎么確定的呢?甚至為什么是5個(gè)呢?根據(jù)論文中所述,anchor的形狀是在VOC 2007和COCO數(shù)據(jù)集上聚類(lèi)得到的,聚類(lèi)的類(lèi)別個(gè)數(shù)從1到15都試過(guò),最終在效果和性能的權(quán)衡之下選擇了5個(gè)類(lèi)聚出來(lái)的錨框形狀,示意圖如上圖5所示。
圖6 Yolov2的anchor編碼示意圖說(shuō)了半天,模型究竟是怎么計(jì)算offset的呢?如上圖6所示,yolov2的anchor編碼在二階段的檢測(cè)模型的基礎(chǔ)上做了改進(jìn)。圖6中cxc_xcx?和cyc_ycy?是每個(gè)格子的左上角坐標(biāo),txt_xtx?和tyt_yty?是模型預(yù)測(cè)錨框中心點(diǎn)坐標(biāo)時(shí)的輸出參數(shù),加了σ\sigmaσ就把中心點(diǎn)的偏移量限定在了這個(gè)格子里,這樣不管模型怎么預(yù)測(cè),中心點(diǎn)都飛不出這個(gè)格子。pwp_wpw?和php_hph?是預(yù)錨框的初始寬高,twt_wtw?和tht_hth?是模型預(yù)測(cè)錨框?qū)捀叩妮敵鰠?shù),這里就沒(méi)有限制最終錨框的形狀。bxb_xbx?,byb_yby?,bwb_wbw?,bhb_hbh?是最終的預(yù)測(cè)框的中心點(diǎn)坐標(biāo)和寬高。我把圖中的公式抄一份下來(lái)就是(2?7)(2-7)(2?7)。
bx=σ(tx)+cxby=σ(ty)+cybw=pwetwbh=pheth(2-7)\begin{aligned} b_x &= \sigma (t_x) + c_x \\ b_y &= \sigma (t_y) + c_y \\ b_w &= p_w e^{t_w} \\ b_h &= p_h e^{t_h} \\ \end{aligned} \tag{2-7} bx?by?bw?bh??=σ(tx?)+cx?=σ(ty?)+cy?=pw?etw?=ph?eth??(2-7)
除此之外,還有一個(gè)東西叫做tot_oto?,tot_oto?是用來(lái)給出有物體的置信度的。
Pr(object)IOU(b,object)=σ(to)(2-8)P_r(object)IOU(b, object) = \sigma(t_o) \tag{2-8} Pr?(object)IOU(b,object)=σ(to?)(2-8)
2.2.1.4 loss的改動(dòng)
Yolov2的loss我直接拿子豪兄做的圖了,這個(gè)也是網(wǎng)友們根據(jù)源碼整理出來(lái)的,論文中并沒(méi)有說(shuō)這件事。
前面的三個(gè)求和就是指的下面的所有操作都是對(duì)每個(gè)格子每個(gè)預(yù)測(cè)框分別做的;IMaxIOU<Thresh\mathbb{I}_{MaxIOU<Thresh}IMaxIOU<Thresh?表示845個(gè)框分別和所有的ground truth求IOU,如果最大的IOU也小于閾值Thresh的話(huà),就認(rèn)為這個(gè)框是背景,其輸出的置信度bijkob_{ijk}^obijko?要越小越好;It<12800\mathbb{I}_{t<12800}It<12800?表示前12800次迭代,也就是模型訓(xùn)練的早期時(shí)候,這里讓模型的預(yù)測(cè)錨框接近預(yù)錨框,有點(diǎn)先重置一下的意思,不讓初始的錨框太橫七豎八;Iktruth\mathbb{I}_k^{truth}Iktruth?表示對(duì)負(fù)責(zé)預(yù)測(cè)ground truth的錨框進(jìn)行的loss計(jì)算。所有的Loss也都是回歸運(yùn)算。
2.2.1.5 Fine-Grained Features
增加了細(xì)粒度的特征,方法就是把淺層的26×26×51226 \times 26 \times 51226×26×512這層的輸出分成四份之后concat到原來(lái)的特征上。26×26×51226 \times 26 \times 51226×26×512分成四份并concat就變成了13×13×204813 \times 13 \times 204813×13×2048,這個(gè)和13×13×102413 \times 13 \times 102413×13×1024的特征concat到一起變成了13×13×307213 \times 13 \times 307213×13×3072。
四分的方式有點(diǎn)空洞卷積的意思,如下圖9所示。
2.2.1.6 多尺度訓(xùn)練
Yolov2每10個(gè)batches就會(huì)換一下輸入的尺度,使得模型泛化于不同尺度的輸入,這得益于adaptive pooling層。高分辨率的輸入速度慢,但是對(duì)小目標(biāo)的檢測(cè)效果要好很多,低分辨率的輸入速度快。
2.2.2 Faster
這部分沒(méi)啥說(shuō)的,就是把backbone給換成了Darknet-19,都是卷積層和pooling層,更加輕量了。
2.2.3 Stronger
這部分是作者對(duì)超多分類(lèi)的一次嘗試,但估計(jì)效果沒(méi)有那么好,只是一個(gè)設(shè)想。
用來(lái)訓(xùn)練檢測(cè)模型的數(shù)據(jù)集coco有80個(gè)類(lèi)別,10萬(wàn)的圖片,但用來(lái)分類(lèi)的數(shù)據(jù)集imagenet有22k個(gè)類(lèi)別,140萬(wàn)的數(shù)據(jù)。作者想要把imagenet的數(shù)據(jù)和類(lèi)別拿來(lái)用,于是就相處了層級(jí)分類(lèi)這個(gè)辦法,如下圖11所示。
imagenet中的每個(gè)類(lèi)別并不是完全兩兩互斥的,它們之間是有層級(jí)關(guān)系的,所以作者借助wordnet把類(lèi)別進(jìn)行了分層,同一層的類(lèi)別分別進(jìn)行softmax,這樣就做到了多層級(jí)的分類(lèi)。檢測(cè)模型的類(lèi)別都是包含在這些類(lèi)別之中的,再將其應(yīng)用到檢測(cè)模型即可。
這只是一個(gè)設(shè)想,了解一下即可。
2.3 一小步 - Yolov3
Yolov3相對(duì)于Yolov2沒(méi)有太多大的改進(jìn),用作者的話(huà)說(shuō)就是"I managed to make some improvements to YOLO. But, honestly, nothing like super interesting, just a bunch of small changes that make it better."
作者對(duì)backbone的網(wǎng)絡(luò)結(jié)構(gòu)進(jìn)行了改進(jìn),將Darknet19結(jié)合Resnet,變成了Darknet53。作者把殘差塊輕量化了一下,如下圖12所示。
除此之外,還增加了多尺度訓(xùn)練機(jī)制,增加了多尺度訓(xùn)練的網(wǎng)絡(luò)結(jié)構(gòu)示意圖如下圖13所示。輸出三個(gè)尺寸的feature map,分別是13×1313 \times 1313×13,26×2626 \times 2626×26和52×5252 \times 5252×52。大尺寸的feature map是小尺寸的feature map上采樣并結(jié)合淺層特征得到的。
每個(gè)尺寸的feature map各司其職,13×1313 \times 1313×13負(fù)責(zé)大目標(biāo)物體,26×2626 \times 2626×26負(fù)責(zé)中目標(biāo)物體和52×5252 \times 5252×52負(fù)責(zé)小目標(biāo)物體。原因很簡(jiǎn)單,越深層的信息越抽象,越淺層的越粗糙,淺層還保留著小物體的信息,深層就不一定還在了。
從圖13中可以看到feautre map的輸出channel變成了256,這個(gè)是因?yàn)閅olov3的anchor變成了9個(gè),每個(gè)尺度的feature map有3個(gè),然后類(lèi)別變成了80類(lèi),所以每個(gè)尺度的feature map有256=3×(4+1+80)256=3 \times (4+1+80)256=3×(4+1+80)。
Yolov3就這些重要的改進(jìn)。
2.4 技巧 - Yolov4
Yolov4可以說(shuō)是目標(biāo)檢測(cè)各種小技巧的大總結(jié),它將技巧分為了bag of freebies(BoF)和bag of specials(BoS)兩種,BoF指的是只增加訓(xùn)練的成本而不增加推理的成本的技巧,通常是前后處理;BoS指的是只增加一點(diǎn)推理成本卻可以顯著提高模型效果的技巧,通常是結(jié)構(gòu)上的變化。
不同的BoF和BoS面對(duì)不同的問(wèn)題和數(shù)據(jù)集有不同的效果,根據(jù)需求選擇即可。
BoF和BoS都有一大堆,要在這里全講完太費(fèi)時(shí)間,也與這篇文章的目的相悖。這里只講一些重要的,且最終的Yolov4用上的技巧。下圖15是Yolov4真正用到的一些改進(jìn)。
這里不會(huì)把上面的所有改進(jìn)都講了,只挑一些重要的講。
2.4.1 網(wǎng)絡(luò)結(jié)構(gòu)的改進(jìn)
2.4.1.1 backbone中的激活函數(shù)改為Mish
Yolov3中的卷積快都是CBL的結(jié)構(gòu),Yolov4改成了CBM,也就是把激活函數(shù)給改成了Mish,其示意圖如下圖16所示。
Leaky Relu激活函數(shù)是(aaa是很小的常數(shù))
f(x)={ax,ifx<0x,otherwise(2-9)f(x) = \begin{cases} ax, &if \ x<0 \\ x, &otherwise \end{cases} \tag{2-9} f(x)={ax,x,?if?x<0otherwise?(2-9)
Mish激活函數(shù)就是
f(x)=x?tanh(log(1+ex))(2-10)f(x) = x \cdot tanh(log(1+e^x)) \tag{2-10} f(x)=x?tanh(log(1+ex))(2-10)
這里順便來(lái)說(shuō)說(shuō)常用的激活函數(shù)的優(yōu)缺點(diǎn)。
sigmoid兩端很容易飽和,會(huì)造成梯度消失的問(wèn)題,中間梯度很大,會(huì)造成梯度爆炸問(wèn)題。用sigmoid做激活函數(shù),神經(jīng)網(wǎng)絡(luò)不太好訓(xùn)練。但是sigmoid的非線性表達(dá)能力很強(qiáng),因?yàn)樗还茉趺锤唠A求導(dǎo)仍舊是非線性的。
tanh和sigmoid很像,不過(guò)它是以0為中心。
relu的問(wèn)題是,它的負(fù)半軸沒(méi)梯度了,正半軸求個(gè)導(dǎo)是常數(shù),非線性表達(dá)能力很弱。但是它快。所以用relu的網(wǎng)絡(luò)一般網(wǎng)絡(luò)層數(shù)很深,以此來(lái)彌補(bǔ)relu非線性能力表達(dá)弱的缺陷。
leaky relu負(fù)半軸做了優(yōu)化,但還是非線性表達(dá)能力弱。
mish結(jié)合了relu和tanh的優(yōu)點(diǎn)。它無(wú)上限,這樣可以保證沒(méi)有飽和區(qū)域,不會(huì)梯度消失。有下限,能夠保證具有一定的正則能力。同時(shí)非線性表達(dá)能力也不錯(cuò)。
2.4.1.2 backbone中的殘差模塊改成了CSP
Yolov3中的殘差模塊如下圖17所示,resX中的X表示的是有X個(gè)Res unit。
Yolov4則是將殘差模塊替換為了CSP模塊,如下圖18所示,其中的CSPX中的X表示有X個(gè)Res unit。
可以看出CSPX效仿殘差塊,額外加了一路,并且這一路中多了一個(gè)CBM,最后的add也變成了concat。相當(dāng)于一堆殘差的外面再殘差了一遍。這里加個(gè)CBM直觀上是為了改變特征的shape,使其可以順利concat。除此之外,資料[8]中的猜想是,這是為了平衡上下兩路的信息,相當(dāng)于加了個(gè)電阻。每個(gè)這個(gè)電阻,就是個(gè)短路的狀態(tài),信息都從下面走了,有了這個(gè)電阻,就可以盡可能平衡上下路的信息。這只是個(gè)猜想。
2.4.1.3 detector中的新增了SPP模塊
SPP的作用是增大感受野。它很簡(jiǎn)單,就是一堆MaxPooling,每個(gè)MaxPooling的kernel size大小不同,就有不同感受野的結(jié)果,最后再全都concat起來(lái)即可,其示意圖如下圖19所示。
SPP之所以不放在backbone是因?yàn)檫@會(huì)造成大量的信息丟失,而放在detector里卻起到了降維的作用。
2.4.1.4 detector中特征尺度的變化
Yolov4還讀detector中的尺度特征做了很大的修改,如下圖20和圖21分別是yolov3和yolov4的網(wǎng)絡(luò)結(jié)構(gòu)圖。
不難看出Yolov3是19×1919 \times 1919×19 -> 38×3838 \times 3838×38 -> 76×7676 \times 7676×76的,而Yolov4是反過(guò)來(lái)的,這主要是為了增加特征融合性,也就是feature map中融合了更多層的信息。特別是19×1919 \times 1919×19這個(gè)feature map,融合的特征最多了,也就是對(duì)大目標(biāo)的檢測(cè)效果更好了。應(yīng)該說(shuō)不管大小目標(biāo),總體都有提升。
2.4.2 損失函數(shù)的改進(jìn)
(1)變?yōu)閟moth_L1
之前Yolo的損失函數(shù)當(dāng)中有大量的L2損失,在Yolov4中改成了smooth L1。smooth L1結(jié)合了L1和L2損失的優(yōu)點(diǎn)。先來(lái)看下L1和L2損失的公式
L1=1n∑i=1n∣f(xi?yi)∣L2=1n∑i=1n(f(xi)?yi)2(2-11)L1 = \frac{1}{n} \sum_{i=1}^{n} |f(x_i - y_i)| \\ L2 = \frac{1}{n} \sum_{i=1}^{n} (f(x_i) - y_i)^2 \tag{2-11} L1=n1?i=1∑n?∣f(xi??yi?)∣L2=n1?i=1∑n?(f(xi?)?yi?)2(2-11)
L1的優(yōu)點(diǎn)是倒數(shù)很穩(wěn)定,但是是一個(gè)階段函數(shù),在(0,0)(0,0)(0,0)處是一個(gè)折線。L2的優(yōu)點(diǎn)是在(0,0)(0,0)(0,0)處是可導(dǎo)的,但是離(0,0)(0,0)(0,0)越遠(yuǎn),導(dǎo)數(shù)越大,會(huì)產(chǎn)生爆炸。所以就有了結(jié)合L1和L2的smooth L1出現(xiàn)
smoothL1={0.5x2if∣x∣<1∣x∣?0.5otherwise(2-12)smooth\ L1 = \begin{cases} 0.5x^2 & if\ |x| < 1 \\ |x| - 0.5 & otherwise \end{cases}\tag{2-12} smooth?L1={0.5x2∣x∣?0.5?if?∣x∣<1otherwise?(2-12)
(2)iou loss改進(jìn)
這里主要參考了文獻(xiàn)[10]
在Yolov3中的IOU loss就直接是(1?IOU)2(1-IOU)^2(1?IOU)2。這里的iou就是交集比上并集,如下圖22所示。
圖22 iou示意圖這里的IOU的計(jì)算方法優(yōu)點(diǎn)缺點(diǎn),且看下圖23。缺點(diǎn)一就是左圖所示,當(dāng)預(yù)測(cè)框與真實(shí)框完全沒(méi)有交疊時(shí),不管預(yù)測(cè)框離真實(shí)框多遠(yuǎn),IOU都是一樣的,但其實(shí)離真實(shí)框近的比離真實(shí)框遠(yuǎn)的要好一些。缺點(diǎn)二就是中圖和右圖所示,當(dāng)交集和并集一致時(shí),不同方向的預(yù)測(cè)框得到的iou是一樣的,但其實(shí)右圖比中圖要好一點(diǎn),因?yàn)橹袌D的中心點(diǎn)對(duì)齊需要預(yù)測(cè)框的水平和垂直都發(fā)生比較大的變化,而右圖只需要水平平移即可。
為了解決上述的兩個(gè)缺點(diǎn),有了GIOU,如圖24所示。
GIOU的公式為
GIOU=IOU?差集/最小外接矩形(2-13)GIOU = IOU - 差集/最小外接矩形 \tag{2-13} GIOU=IOU?差集/最小外接矩形(2-13)
最小外接矩形和差集的意思就是圖24中的左圖和中圖,不難看初,剛才提到的兩個(gè)缺點(diǎn)在這里已經(jīng)解決了。不過(guò)還有一個(gè)問(wèn)題,如圖25所示。
當(dāng)預(yù)測(cè)框在真實(shí)框內(nèi)部的時(shí)候,不管預(yù)測(cè)框在那個(gè)位置,GIOU都是一樣的,但是圖25的中圖顯然是優(yōu)于左圖和右圖的,因?yàn)橹袌D的水平和垂直方向的坐標(biāo)已經(jīng)對(duì)齊了,只需要改變長(zhǎng)寬即可。
這個(gè)時(shí)候,就又出現(xiàn)了一種DIOU,如圖26所示。
DIOU的公式為
DIOU=IOU?(Distance_2)/(Distance_C)(2-14)DIOU = IOU - (Distance\_2) / (Distance\_C) \tag{2-14} DIOU=IOU?(Distance_2)/(Distance_C)(2-14)
其中,Distance_CDistance\_CDistance_C是最小外接矩形的對(duì)角線距離,Distance_2Distance\_2Distance_2是預(yù)測(cè)框和真實(shí)框中心點(diǎn)的歐氏距離。
這樣一來(lái)就解決了圖25的缺點(diǎn)。但是,別急,還有一個(gè)缺點(diǎn)。DIOU沒(méi)有考慮長(zhǎng)寬比。
圖27中當(dāng)預(yù)測(cè)中心點(diǎn)距離真實(shí)中心點(diǎn)一樣時(shí),預(yù)測(cè)框的長(zhǎng)寬比與真實(shí)框接近的,顯然是更優(yōu)的。于是,就有了終極版的CIOU。
CIOU的公式為
CIOU=IOU?Distance_22Distance_C2?v21?IOU+v(2-15)CIOU = IOU - \frac{Distance\_2^2}{Distance\_C^2} - \frac{v^2}{1 - IOU + v} \tag{2-15} CIOU=IOU?Distance_C2Distance_22??1?IOU+vv2?(2-15)
其中,vvv是長(zhǎng)寬比的一致性參數(shù),定義為
v=4π(arctanwgthgt?arctanwpredhpred)2(2-16)v = \frac{4}{\pi}(arctan\frac{w_{gt}}{h_{gt}} - arctan\frac{w_{pred}}{h_{pred}})^2 \tag{2-16} v=π4?(arctanhgt?wgt???arctanhpred?wpred??)2(2-16)
至此,iou經(jīng)歷了這么多版本,最終確定為CIOU。
2.4.3 nms的改進(jìn)
在訓(xùn)練的時(shí)候用的是CIOU,但是在做nms的時(shí)候,用了diou-nms。用diou-nms可以把一些重疊度很高的框,但表示不同物體的給保留下來(lái)。至于為什么不用CIOU,我覺(jué)得是沒(méi)有必要,且會(huì)增加計(jì)算復(fù)雜度。我不太同意文獻(xiàn)[10]中說(shuō)的CIOU在做nms時(shí)沒(méi)有真實(shí)框,vvv沒(méi)法計(jì)算的說(shuō)法,兩個(gè)框做對(duì)比,把置信度高的當(dāng)成真實(shí)框即可。
2.4.4 其他
其他比較重要的可能就是cutout,mosaic之類(lèi)的數(shù)據(jù)增強(qiáng)的方法了,這個(gè)這里就不細(xì)講了。
2.5 又一小步 - Yolov5
Yolov5和Yolov4差不多可以說(shuō)沒(méi)有做太多的改進(jìn),不過(guò)工程上更友好了一些,使用起來(lái)也更加方便。
2.5.1 網(wǎng)絡(luò)結(jié)構(gòu)的改進(jìn)
2.5.1.1 添加了CSP2模塊
下圖28時(shí)Yolov5的網(wǎng)絡(luò)結(jié)構(gòu)圖,和Yolov4幾乎時(shí)一摸一樣,做了一點(diǎn)點(diǎn)改進(jìn)。
(1)把CBM換回了CBL,可能是為了提升速度。
(2)設(shè)計(jì)了CSP2模塊,如圖28的左下角所示,就是把之前CSP中的殘差塊改成了CBL。
(3)添加了Focus模塊。這個(gè)其實(shí)就是Yolov2中的pass through。
2.5.2 其他
還有就是一些零零碎碎的東西,這里簡(jiǎn)單列幾個(gè)比較有用的吧。
(1)添加了訓(xùn)練前自動(dòng)計(jì)算最佳預(yù)錨框的模塊。
(2)自適應(yīng)圖片縮放,就是padding的時(shí)候,去掉一些沒(méi)用的黑邊。
3 結(jié)束語(yǔ)
這里根據(jù)網(wǎng)上各家的資料總結(jié)了很多,其中也有一些自己的理解,對(duì)我自身了解Yolo有很大的幫助,也希望給看到這篇博客的人有一些幫助。
參考資料
[1] You Only Look Once: Unified, Real-Time Object Detection
[2] 【子豪兄】YOLOV1目標(biāo)檢測(cè),看我就夠了
[3] YOLO9000: Better, Faster, Stronger
[4] 【精讀AI論文】YOLO V2目標(biāo)檢測(cè)算法
[5] Understanding the Disharmony between Dropout and Batch Normalization by Variance Shift
[6] YOLOv3: An Incremental Improvement
[7] YOLO系列算法之YOLOv3算法精講
[8] 2021最新人工智能深度學(xué)習(xí)YOLOv4與YOLOv5教程
[9] YOLOv4: Optimal Speed and Accuracy of Object Detection
[10] 深入淺出Yolo系列之Yolov3&Yolov4&Yolov5&Yolox核心基礎(chǔ)知識(shí)完整講解
[11] 深入淺出Yolo系列之Yolov5核心基礎(chǔ)知識(shí)完整講解
總結(jié)
以上是生活随笔為你收集整理的Yolo系列知识点梳理(Yolov1-v5)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 一、node.js搭建最简单的服务器
- 下一篇: skywalking 安装_SkyWal