閱讀本文之前,請先閱讀前兩代YOLO文章
目標(biāo)檢測YOLO系列——YOLO v1
目標(biāo)檢測YOLO系列——YOLO v2
YOLO v3作為YOLO系列目前最新的算法,對之前的算法既有保留又有改進。
- 從yolo v1開始,yolo算法就是通過劃分單元格來做檢測,只是劃分的數(shù)量不一樣。
- 采用"leaky ReLU"作為激活函數(shù)。
- 端到端進行訓(xùn)練。一個loss function搞定訓(xùn)練,只需關(guān)注輸入端和輸出端。
- 從yolo v2開始,yolo就用batch normalization作為正則化、加速收斂和避免過擬合的方法,把BN層和leaky relu層接到每一層卷積層之后。
- 多尺度訓(xùn)練。在速度和準(zhǔn)確率之間tradeoff。想速度快點,可以犧牲準(zhǔn)確率;想準(zhǔn)確率高點兒,可以犧牲一點速度
yolo每一代的提升很大一部分決定于backbone網(wǎng)絡(luò)的提升,從v2的darknet-19到v3的darknet-53。yolo_v3還提供替換backbone——tiny darknet。要想性能牛叉,backbone可以用Darknet-53,要想輕量高速,可以用tiny-darknet。
網(wǎng)絡(luò)結(jié)構(gòu)
yolo系列里面,作者只在v1的論文里給出了結(jié)構(gòu)圖,而v2和v3的論文里都沒有結(jié)構(gòu)圖,此處附上一個我看見的一個博客上v3的圖,覺得很好,此處收藏一下。
DBL: 如圖左下角所示,也就是代碼中的Darknetconv2d_BN_Leaky,是yolo_v3的基本組件。就是Conv+BN+Leaky relu。對于v3來說,BN和leaky relu已經(jīng)是和卷積層不可分離的部分了(最后一層卷積除外),共同構(gòu)成了最小組件。
resn:n代表數(shù)字,有res1,res2, … ,res8等等,表示這個res_block里含有多少個res_unit。這是yolo_v3的大組件,yolo_v3開始借鑒了ResNet的殘差結(jié)構(gòu),使用這種結(jié)構(gòu)可以讓網(wǎng)絡(luò)結(jié)構(gòu)更深(從v2的darknet-19上升到v3的darknet-53,前者沒有殘差結(jié)構(gòu))。對于res_block的解釋,可以在圖的右下角直觀看到,其基本組件也是DBL。
concat:張量拼接。將darknet中間層和后面的某一層的上采樣進行拼接。拼接的操作和殘差層add的操作是不一樣的,拼接會擴充張量的維度,而add只是直接相加不會導(dǎo)致張量維度的改變。
Backbone
整個v3結(jié)構(gòu)里面,是沒有池化層和全連接層的。前向傳播過程中,張量的尺寸變換是通過改變卷積核的步長來實現(xiàn)的,比如stride=(2, 2),這就等于將圖像邊長縮小了一半(即面積縮小到原來的1/4)。在yolo_v2中,要經(jīng)歷5次縮小,會將特征圖縮小到原輸入尺寸的,即1/32。輸入為
,則輸出
。

yolo_v3也和v2一樣,backbone都會將輸出特征圖縮小到輸入的。所以,通常都要求輸入圖片是32的倍數(shù)。yolo_v2中對于前向過程中張量尺寸變換,都是通過最大池化來進行,一共有5次。而v3是通過卷積核增大步長來進行,也是5次。(darknet-53最后面有一個全局平均池化,在yolo-v3里面沒有這一層,所以張量維度變化只考慮前面那5次)。這也是416x416輸入得到13x13輸出的原因。darknet-19(yolo v2)是不存在殘差結(jié)構(gòu)(resblock,從resnet上借鑒過來)的,和VGG是同類型的backbone(屬于上一代CNN結(jié)構(gòu)),而darknet-53是可以和resnet-152正面剛的backbone。darknet-53與resnet-152具有相似的性能,速度提高2倍。darknet-53也可以實現(xiàn)每秒最高的測量浮點運算。這意味著網(wǎng)絡(luò)結(jié)構(gòu)可以更好地利用GPU,從而使其評估效率更高,速度更快。這主要是因為ResNets的層數(shù)太多,效率不高。
多尺度特征進行對象檢測

YOLO2曾采用passthrough結(jié)構(gòu)來檢測細(xì)粒度特征,在YOLO3更進一步采用了3個不同尺度的特征圖來進行對象檢測。結(jié)合上圖看,卷積網(wǎng)絡(luò)在79層后,經(jīng)過下方幾個黃色的卷積層得到一種尺度的檢測結(jié)果。相比輸入圖像,這里用于檢測的特征圖有32倍的下采樣。比如輸入是416x416的話,這里的特征圖就是13x13了。由于下采樣倍數(shù)高,這里特征圖的感受野比較大,因此適合檢測圖像中尺寸比較大的對象。
為了實現(xiàn)細(xì)粒度的檢測,第79層的特征圖又開始作上采樣(從79層往右開始上采樣卷積),然后與第61層特征圖融合(Concatenation),這樣得到第91層較細(xì)粒度的特征圖,同樣經(jīng)過幾個卷積層后得到相對輸入圖像16倍下采樣的特征圖。它具有中等尺度的感受野,適合檢測中等尺度的對象。
最后,第91層特征圖再次上采樣,并與第36層特征圖融合(Concatenation),最后得到相對輸入圖像8倍下采樣的特征圖。它的感受野最小,適合檢測小尺寸的對象。
9種尺度的先驗框
隨著輸出的特征圖的數(shù)量和尺度的變化,先驗框的尺寸也需要相應(yīng)的調(diào)整。YOLO2已經(jīng)開始采用K-means聚類得到先驗框的尺寸,YOLO3延續(xù)了這種方法,為每種下采樣尺度設(shè)定3種先驗框,總共聚類出9種尺寸的先驗框。在COCO數(shù)據(jù)集這9個先驗框是:(10x13),(16x30),(33x23),(30x61),(62x45),(59x119),(116x90),(156x198),(373x326)。
分配上,在最小的13x13特征圖上(有最大的感受野)應(yīng)用較大的先驗框(116x90),(156x198),(373x326),適合檢測較大的對象。中等的26*26特征圖上(中等感受野)應(yīng)用中等的先驗框(30x61),(62x45),(59x119),適合檢測中等大小的對象。較大的52x52特征圖上(較小的感受野)應(yīng)用較小的先驗框(10x13),(16x30),(33x23),適合檢測較小的對象。
輸入映射到輸出

不考慮神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)細(xì)節(jié)的話,總的來說,對于一個輸入圖像,YOLO3將其映射到3個尺度的輸出張量,代表圖像各個位置存在各種對象的概率。
我們看一下YOLO3共進行了多少個預(yù)測。對于一個416x416的輸入圖像,在每個尺度的特征圖的每個網(wǎng)格設(shè)置3個先驗框,總共有 13x13x3 + 26x26x3 + 52x52x3 = 10647 個預(yù)測。每一個預(yù)測是一個(4+1+80)=85維向量,這個85維向量包含邊框坐標(biāo)(4個數(shù)值),邊框置信度(1個數(shù)值),對象類別的概率(對于COCO數(shù)據(jù)集,有80種對象)。
對比一下,YOLO2采用13x13x5 = 845個預(yù)測,YOLO3的嘗試預(yù)測邊框數(shù)量增加了10多倍,而且是在不同分辨率上進行,所以mAP以及對小物體的檢測效果有一定的提升。
對象分類softmax改成logistic
預(yù)測對象類別時不使用softmax,改成使用logistic的輸出進行預(yù)測。這樣能夠支持多標(biāo)簽對象(比如一個人有Woman 和 Person兩個標(biāo)簽)。
[參考鏈接]
http://www.itdecent.cn/p/d13ae1055302
https://zhuanlan.zhihu.com/p/34945787
https://blog.csdn.net/leviopku/article/details/82660381