關(guān)于YOLOv3的一些細(xì)節(jié)

本文是我對YOLO算法的細(xì)節(jié)理解總結(jié),本文的閱讀前提是已讀過YOLO相關(guān)論文,文中不會談及YOLO的發(fā)展過程,不會與其他對象檢測算法進行對比,也不會介紹YOLO9000相關(guān)的內(nèi)容,只總結(jié)YOLOv3算法的具體流程和實現(xiàn)細(xì)節(jié)。所以,下文中所有提到的YOLO,如非特別說明,均指YOLOv3。
如果需要了解更多對象檢測算法,可以參考以下部分相關(guān)論文:
R-CNN
Fast R-CNN
Faster R-CNN
SSD
YOLOv1
YOLOv2
YOLOv3
RetinaNet
最新關(guān)于對象檢測的綜述文獻(xiàn)可以參考這篇論文:
Deep Learning for Generic Object Detection: A Survey

1.概述

在YOLO算法發(fā)表之前,大部分表現(xiàn)比較好的對象檢測(Object Detection)算法都是以R-CNN為代表兩階段算法,這樣的算法存在一個很明顯的問題,那就是速度太慢,對于實時性要求很高的應(yīng)用場景是不適用的。YOLO算法的作者沒有走優(yōu)化算法第一階段或者第二階段的老路子,而是直接提出一步完成預(yù)測,而且是在一個CNN網(wǎng)絡(luò)模型中完成圖片中所有位置對象的box和類別預(yù)測,推理速度大大提升,完全可以滿足實時對象檢測。

YOLO算法創(chuàng)新性地提出了將輸入圖片進行N*N的柵格化(每個小單元叫g(shù)rid cell),然后將圖片中某個對象的位置的預(yù)測任務(wù)交與該對象中心位置所在的grid cell的bouding box。簡單理解的話,可以認(rèn)為這也是一種很粗糙的區(qū)域推薦(region proposal),在訓(xùn)練的時候,我們通過grid cell的方式告訴模型,圖片中對象A應(yīng)該是由中心落在特定grid cell 的某個范圍內(nèi)的某些像素組成,模型接收到這些信息后就在grid cell周圍以一定大小范圍去尋找所有滿足對象A特征的像素,經(jīng)過很多次帶懲罰的嘗試訓(xùn)練后,它就能找到這個準(zhǔn)確的范圍了(說明不是瞎找,如滑動窗口),當(dāng)然這個方位不僅是指長寬的大小范圍,也包括小幅度的中心位置坐標(biāo)變化,但是不管怎么變,中心位置不能越過該grid cell的范圍。這大大限制了模型在圖片中瞎找時做的無用功。這樣將位置檢測和類別識別結(jié)合到一個CNN網(wǎng)絡(luò)中預(yù)測,即只需要掃描一遍(you only look once)圖片就能推理出圖片中所有對象的位置信息和類別。舉例如下圖。

img1.jpg

以上是我個人理解的YOLO算法的核心思想,不管是YOLOv1還是v2、v3,其主要的核心還是以上所述,只是在bounding box的擬合方式、骨干網(wǎng)絡(luò)的設(shè)計、模型訓(xùn)練的穩(wěn)定性、精度方面有所提升罷了。下面對整個模型的網(wǎng)絡(luò)結(jié)構(gòu)、實現(xiàn)和訓(xùn)練細(xì)節(jié)進行闡述。

2.訓(xùn)練

既然已經(jīng)有了you only look once的想法,那接下來就要將這個想法數(shù)學(xué)化,這樣才能用數(shù)學(xué)的方法訓(xùn)練模型學(xué)習(xí)擬合坐標(biāo)和類別的特征,用于后期的預(yù)測。YOLO算法幾乎是輸入原圖就直接預(yù)測出每個grid cell“附近”是否有某個對象和具體的 box位置,那最終這個想法數(shù)學(xué)化后便體現(xiàn)在loss函數(shù)上,這里我先不給出loss函數(shù)的具體公式,因為在提出loss函數(shù)之前要先了解三個概念:anchor box、置信度(confidence)和對象條件類別概率(conditional class probabilities)。作者提出,在網(wǎng)絡(luò)最后的輸出中,對于每個grid cell對應(yīng)bounding box的輸出有三類參數(shù):一個是對象的box參數(shù),一共是四個值,即box的中心點坐標(biāo)(x,y)和box的寬和高(w,h);一個是置信度,這是個區(qū)間在[0,1]之間的值;最后一個是一組條件類別概率,都是區(qū)間在[0,1]之間的值,代表概率。下面分別具體介紹這三個參數(shù)的意義。

2.1 anchor box(bounding box prior)

anchor box最初是由Faster RCNN引入的。anchor box(論文中也稱為bounding box prior,后面均使用anchor box)其實就是從訓(xùn)練集的所有g(shù)round truth box中統(tǒng)計(使用k-means)出來的在訓(xùn)練集中最經(jīng)常出現(xiàn)的幾個box形狀和尺寸。比如,在某個訓(xùn)練集中最常出現(xiàn)的box形狀有扁長的、瘦高的和寬高比例差不多的正方形這三種形狀。我們可以預(yù)先將這些統(tǒng)計上的先驗(或來自人類的)經(jīng)驗加入到模型中,這樣模型在學(xué)習(xí)的時候,瞎找的可能性就更小了些,當(dāng)然就有助于模型快速收斂了。以前面提到的訓(xùn)練數(shù)據(jù)集中的ground truth box最常出現(xiàn)的三個形狀為例,當(dāng)模型在訓(xùn)練的時候我們可以告訴它,你要在grid cell 1附件找出的對象的形狀要么是扁長的、要么是瘦高的、要么是長高比例差不多的正方形,你就不要再瞎試其他的形狀了。anchor box其實就是對預(yù)測的對象范圍進行約束,并加入了尺寸先驗經(jīng)驗,從而可以有效解決對象多尺度的問題(Faster RCNN論文中指出的作用)。這篇文章對anchor box的作用進行了另外的解釋,個人覺得也很有道理,將部分內(nèi)容翻譯如下:

當(dāng)我們只對圖片中一個對象(且圖片中只有一個對象)進行box回歸時,我們只需要一個box回歸器,但是當(dāng)我們對圖片中多個對象進行回歸時(甚至一個類別會有多個對象),這時使用多個box回歸器預(yù)測多個對象位置時就會發(fā)生沖突,因為每個預(yù)測器都可能不受約束地預(yù)測圖片中任何一個對象的位置和類別。這時,我們就可以使用anchor來對每個回歸器進行約束,只讓每個回歸器負(fù)責(zé)一塊獨立區(qū)域內(nèi)的對象box回歸。以YOLO算法舉例,每個grid cell的位置其實也可以看做是anchor的位置(這不同于SSD或者Faster RCNN的anchor),如果最終的輸出為13x13,也即有13x13個grid cell,每個grid cell有三個anchor的話,整個模型就有13x13x3個回歸器,每個回歸器只負(fù)責(zé)相應(yīng)grid cell附近的對象預(yù)測。

要在模型中使用這些形狀,總不能告訴模型有個形狀是瘦高的,還有一個是矮胖的,我們需要量化這些形狀。YOLO的做法是想辦法找出分別代表這些形狀的寬和高,有了寬和高,尺寸比例即形狀不就有了。YOLO作者的辦法是使用k-means算法在訓(xùn)練集中所有樣本的ground truth box中聚類出具有代表性形狀的寬和高,作者將這種方法稱作維度聚類(dimension cluster)。細(xì)心的讀者可能會提出這個問題:到底找出幾個anchor box算是最佳的具有代表性的形狀。YOLO作者方法是做實驗,聚類出多個數(shù)量不同anchor box組,分別應(yīng)用到模型中,最終找出最優(yōu)的在模型的復(fù)雜度和高召回率(high recall)之間折中的那組anchor box。作者在COCO數(shù)據(jù)集中使用了9個anchor box,我們前面提到的例子則有3個anchor box。

那么有了量化的anchor box后,怎么在實際的模型中加入anchor box的先驗經(jīng)驗?zāi)??我們在前面中簡單提到過最終負(fù)責(zé)預(yù)測grid cell中對象的box的最小單元是bounding box,那我們可以讓一個grid cell輸出(預(yù)測)多個bounding box,然后每個bounding box負(fù)責(zé)預(yù)測不同的形狀不就行了?比如前面例子中的3個不同形狀的anchor box,我們的一個grid cell會輸出3個參數(shù)相同的bounding box,第一個bounding box負(fù)責(zé)預(yù)測的形狀與anchor box 1類似的box,其他兩個bounding box依次類推。作者在YOLOv3中取消了v2之前每個grid cell只負(fù)責(zé)預(yù)測一個對象的限制,也就是說grid cell中的三個bounding box都可以預(yù)測對象,當(dāng)然他們應(yīng)該對應(yīng)不同的ground truth。那么如何在訓(xùn)練中確定哪個bounding box負(fù)責(zé)某個ground truth呢?方法是求出每個grid cell中每個anchor box與ground truth box的IOU(交并比),IOU最大的anchor box對應(yīng)的bounding box就負(fù)責(zé)預(yù)測該ground truth,也就是對應(yīng)的對象,后面還會提到負(fù)責(zé)預(yù)測的問題。

到此,還有最后一個問題需要解決,我們才能真正在訓(xùn)練中使用anchor box,那就是我們怎么告訴模型第一個bounding box負(fù)責(zé)預(yù)測的形狀與anchor box 1類似,第二個bounding box負(fù)責(zé)預(yù)測的形狀與anchor box 2類似?YOLO的做法是不讓bounding box直接預(yù)測實際box的寬和高(w,h),而是將預(yù)測的寬和高分別與anchor box的寬和高綁定,這樣不管一開始bounding box輸出的(w,h)是怎樣的,經(jīng)過轉(zhuǎn)化后都是與anchor box的寬和高相關(guān),這樣經(jīng)過很多次懲罰訓(xùn)練后,每個bounding box就知道自己該負(fù)責(zé)怎樣形狀的box預(yù)測了。這個綁定的關(guān)系是什么?那就是下面這個公式:
\begin{aligned} b_{w} & = a_{w}e^{t_{w}} \\ b_{h} & = a_{h}e^{t_{h}} \end{aligned}
其中,a_{w}a_{h}為anchor box的寬和高,t_{w}t_{h}為bounding box直接預(yù)測出的寬和高,b_{w}b_{h}為轉(zhuǎn)換后預(yù)測的實際寬和高,這也就是最終預(yù)測中輸出的寬和高。你可能會想,這個公式這么麻煩,為什么不能用\begin{aligned} b_{w}=a_{w}*t_{w}, b_{h}=a_{h}*t_{h}\end{aligned} 這樣的公式,我的理解是上面的公式雖然計算起來比較麻煩,但是在誤差函數(shù)求導(dǎo)后還帶有t_{w}t_{h}參數(shù),而且也好求導(dǎo)(此觀點只是個人推測,需要進一步查證)。

既然提到了最終預(yù)測的寬和高公式,那我們也就直接帶出最終預(yù)測輸出的box中心坐標(biāo)(b_{x},b_{y})的計算公式,我們前面提到過box中心坐標(biāo)總是落在相應(yīng)的grid cell中的,所以bounding box直接預(yù)測出的t_{x}t_{y}也是相對grid cell來說的,要想轉(zhuǎn)換成最終輸出的絕對坐標(biāo),需要下面的轉(zhuǎn)換公式:
\begin{aligned} b_{x} & = \sigma(t_{x}) + c_{x} \\ b_{y} & = \sigma(t_{y}) + c_{y} \end{aligned}
其中,\sigma(t_{x})為sigmoid函數(shù),c_{x}c_{y}分別為grid cell方格左上角點相對整張圖片的坐標(biāo)。作者使用這樣的轉(zhuǎn)換公式主要是因為在訓(xùn)練時如果沒有將t_{x}t_{y}壓縮到(0,1)區(qū)間內(nèi)的話,模型在訓(xùn)練前期很難收斂。
最終可以得出實際輸出的box參數(shù)公式如下,這個也是在推理時將輸出轉(zhuǎn)換為最終推理結(jié)果的公式:

\begin{aligned} b_{x} & = \sigma(t_{x}) + c_{x} \\ b_{y} & = \sigma(t_{y}) + c_{y} \\ b_{w} & = a_{w}e^{t_{w}} \\ b_{h} & = a_{h}e^{t_{h}} \\ \end{aligned}

關(guān)于box參數(shù)的轉(zhuǎn)換還有一點值得一提,作者在訓(xùn)練中并不是將t_{x}、t_{y}、t_{w}t_{h}轉(zhuǎn)換為b_{x}、b_{y}、b_{w}b_{h}后與ground truth box的對應(yīng)參數(shù)求誤差,而是使用上述公式的逆運算將ground truth box的參數(shù)轉(zhuǎn)換為與t_{x}t_{y}、t_{w}t_{h}對應(yīng)的g_{x}g_{y}、g_{w}g_{h},然后再計算誤差,計算中由于sigmoid函數(shù)的反函數(shù)難計算,所以并沒有計算sigmoid的反函數(shù),而是計算輸出對應(yīng)的sigmoid函數(shù)值。

\begin{aligned} \sigma(\hat t_{x}) =g_x - c_{x} \\ \sigma(\hat t_{y}) =g_y - c_{y} \\ \hat t_{w} = \log(g_{w} / a_{w}) \\ \hat t_{h} = \log(g_{h} / a_{h}) \\ \end{aligned}

關(guān)于anchor box訓(xùn)練相關(guān)的問題除了與loss函數(shù)相關(guān)的基本上都解釋清楚了,但是預(yù)測的問題還沒有解釋清楚,還存在一個很關(guān)鍵的問題:在訓(xùn)練中我們挑選哪個bounding box的準(zhǔn)則是選擇預(yù)測的box與ground truth box的IOU最大的bounding box做為最優(yōu)的box,但是在預(yù)測中并沒有g(shù)round truth box,怎么才能挑選最優(yōu)的bounding box呢?這就需要另外的參數(shù)了,那就是下面要說到的置信度。

2.2 置信度(confidence)

置信度是每個bounding box輸出的其中一個重要參數(shù),作者對他的作用定義有兩重:一重是代表當(dāng)前box是否有對象的概率P_{r}(Object),注意,是對象,不是某個類別的對象,也就是說它用來說明當(dāng)前box內(nèi)只是個背景(backgroud)還是有某個物體(對象);另一重表示當(dāng)前的box有對象時,它自己預(yù)測的box與物體真實的box可能的IOU_{pred}^{truth}的值,注意,這里所說的物體真實的box實際是不存在的,這只是模型表達(dá)自己框出了物體的自信程度。以上所述,也就不難理解作者為什么將其稱之為置信度了,因為不管哪重含義,都表示一種自信程度:框出的box內(nèi)確實有物體的自信程度和框出的box將整個物體的所有特征都包括進來的自信程度。經(jīng)過以上的解釋,其實我們也就可以用數(shù)學(xué)形式表示置信度的定義了:

\begin{aligned} C_{i}^{j} & = P_{r}(Object) * IOU_{pred}^{truth} \end{aligned}

其中,C_{i}^{j}表示第i個grid cell的第j個bounding box的置信度。對于如何訓(xùn)練C_{i}^{j}的方法,在損失函數(shù)小節(jié)中說明。

2.3 對象條件類別概率(conditional class probabilities)

對象條件類別概率是一組概率的數(shù)組,數(shù)組的長度為當(dāng)前模型檢測的類別種類數(shù)量,它的意義是當(dāng)bounding box認(rèn)為當(dāng)前box中有對象時,要檢測的所有類別中每種類別的概率,其實這個和分類模型最后使用softmax函數(shù)輸出的一組類別概率是類似的,只是二者存在兩點不同:1.YOLO的對象類別概率中沒有background一項,也不需要,因為對background的預(yù)測已經(jīng)交給置信度了,所以它的輸出是有條件的,那就是在置信度表示當(dāng)前box有對象的前提下,所以條件概率的數(shù)學(xué)形式為P_{r}(class_{i}|Object);2.分類模型中最后輸出之前使用softmax求出每個類別的概率,也就是說各個類別之間是互斥的,而YOLOv3算法的每個類別概率是單獨用邏輯回歸函數(shù)(sigmoid函數(shù))計算得出了,所以每個類別不必是互斥的,也就是說一個對象可以被預(yù)測出多個類別。這個想法其實是有一些YOLO9000的意思的,因為YOLOv3已經(jīng)有9000類似的功能,不同只是不能像9000一樣,同時使用分類數(shù)據(jù)集和對象檢測數(shù)據(jù)集,且類別之間的詞性是有從屬關(guān)系的。

介紹完所有的輸出參數(shù)后,我們總結(jié)下模型最終輸出層的輸出維數(shù)是多少。假如一個圖片被分割成S*S個grid cell,我們有B個anchor box,也就是說每個grid cell有B個bounding box, 每個bounding box內(nèi)有4個位置參數(shù),1個置信度,classes個類別概率,那么最終的輸出維數(shù)是:S*S*[B*(4 + 1 + classes)]。

2.4 損失函數(shù)

介紹完模型最終輸出中有哪些參數(shù)后,我們應(yīng)該可以定義loss函數(shù)了,作者使用了最簡單的差平方和誤差(sum-squared error),使用的原因很簡單,因為好優(yōu)化。那我們試著給出loss函數(shù)的公式:

\begin{aligned} Loss = \sum_{i=0}^{S^{2}}\sum_{j=0}^{B}[({\sigma(t_{x})}_{i}^{j} - \sigma(\hat t_{x})_{i}^{j})^{2} + (\sigma(t_{y})_{i}^{j} - \sigma(\hat t_{y})_{i}^{j})^{2}] + \\ \sum_{i=0}^{S^{2}}\sum_{j=0}^{B}[({t_w}_{i}^{j} - {\hat t_w}_{i}^{j})^{2} + ({t_h}_{i}^{j} - {\hat t_h}_{i}^{j})^{2}] + \\ \sum_{i=0}^{S^{2}}\sum_{j=0}^{B}(C_{i}^{j} - \widehat C_{i}^{j})^{2} +\\ \sum_{i=0}^{S^{2}}\sum_{j=0}^{B}\sum_{c \in classes}(p_{i}^{j}(c) - \widehat p_{i}^{j}(c))^{2} \end{aligned}

如果看過YOLOv1的論文你會發(fā)現(xiàn),這里的公式和論文中的公式雖然相似,但是差別還是很大的。其實,作者是在上面這個公式的基礎(chǔ)上加了很多限制和優(yōu)化參數(shù),上面的公式只是我為了更好說明YOLO的loss公式而給出的對比公式,這樣有助于更好的理解YOLO的loss函數(shù)公式中加入的每個參數(shù)的意義,下面給出真正的YOLO loss函數(shù)公式(這個公式是我根據(jù)YOLO三篇論文前后的發(fā)展總結(jié)出來的,v3論文中未給出此類似的公式):

\begin{aligned} Loss = \sum_{i=0}^{S^{2}}\sum_{j=0}^{B} \mathbb{I}_{ij}^{obj} [({\sigma(t_{x})}_{i}^{j} - \sigma(\hat t_{x})_{i}^{j})^{2} + (\sigma(t_{y})_{i}^{j} - \sigma(\hat t_{y})_{i}^{j})^{2}] + \\ \sum_{i=0}^{S^{2}}\sum_{j=0}^{B}\mathbb{I}_{ij}^{obj}[({t_w}_{i}^{j} - {\hat t_w}_{i}^{j})^{2} + ({t_h}_{i}^{j} - {\hat t_h}_{i}^{j})^{2}] + \\ \sum_{i=0}^{S^{2}}\sum_{j=0}^{B}\mathbb{G}_{ij}(C_{i}^{j} - \widehat C_{i}^{j})^{2} + \\ \sum_{i=0}^{S^{2}}\sum_{j=0}^{B}\sum_{c \in classes}\mathbb{I}_{ij}^{obj}(p_{i}^{j}(c) - \widehat p_{i}^{j}(c))^{2} \end{aligned}

細(xì)心的你一定也注意到了,這個公式和YOLOv1論文中的公式是不一樣的。那是因為在YOLOv3中,作者將置信度和條件類別概率放到了每個bounding box中,即每個bounding box都有一對置信度和條件類別概率,而v1中所有的bounding box共用一個條件類別概率,上文中在說明輸出的各個參數(shù)時,默認(rèn)解釋的是v3的輸出格式,關(guān)于v1的細(xì)節(jié)不再贅述。下面幾點是loss函數(shù)的幾點細(xì)節(jié):

  • v1和v2 loss中的\lambda_{coord}\lambda_{noobj} 參數(shù)去哪了
    v3去掉了v1和v2 loss中的\lambda_{coord}\lambda_{noobj} 參數(shù)。這點在論文中未提及,但是在作者的實現(xiàn)源碼中去掉了,可能模型已經(jīng)變得更加穩(wěn)定,不需要這樣的微調(diào)。當(dāng)然,在darknet的yolov3.cfg配置文件中也沒有這兩個參數(shù)的配置。

  • 參數(shù)\mathbb{I}_{ij}^{obj}
    在訓(xùn)練中,如果某個grid cell的bounding box沒有負(fù)責(zé)預(yù)測某個對象,那我們就不應(yīng)該訓(xùn)練該bounding box的條件類別概率和坐標(biāo)參數(shù),因為使用這些參數(shù)的前提是在明確清楚該bounding box負(fù)責(zé)預(yù)測某個ground truth box(后面說明怎么決定是否負(fù)責(zé)),即不應(yīng)該根據(jù)條件類別概率和中心坐標(biāo)輸出誤差調(diào)整相應(yīng)的weights,那如何不進行這部分訓(xùn)練呢,當(dāng)然是不讓他們對loss做出貢獻(xiàn),也就沒有它們什么事情了,這個時候就需要參數(shù)\mathbb{I}_{ij}^{obj}了,當(dāng)該bounding box負(fù)責(zé)預(yù)測某個ground truth box時,\mathbb{I}_{ij}^{obj} =1,否則,\mathbb{I}_{ij}^{obj} =0。

  • \widehat C_{i}^{j}\mathbb{G}_{ij}的值如何確定
    訓(xùn)練中,\widehat C_{i}^{j}的取值是由grid cell的bounding box有沒有負(fù)責(zé)預(yù)測某個對象決定的。如果負(fù)責(zé),那么\widehat C_{i}^{j}=1,否則,\widehat C_{i}^{j}=0。下面我們來說明如何確定某個grid cell的bounding box是否負(fù)責(zé)預(yù)測該grid cell中的對象:前面在說明anchor box的時候提到每個bounding box負(fù)責(zé)預(yù)測的形狀是依據(jù)與其對應(yīng)的anchor box(bounding box prior)相關(guān)的,那這個anchor box與該對象的ground truth box的IOU在所有的anchor box(與一個grid cell中所有bounding box對應(yīng),COCO數(shù)據(jù)集中是9個)與ground truth box的IOU中最大,那它就負(fù)責(zé)預(yù)測這個對象,因為這個形狀、尺寸最符合當(dāng)前這個對象,這時\widehat C_{i}^{j}=1,其他情況下\widehat C_{i}^{j}=0。注意,你沒有看錯,就是所有anchor box與某個ground truth box的IOU最大的那個anchor box對應(yīng)的bounding box負(fù)責(zé)預(yù)測該對象,與該bounding box預(yù)測的box沒有關(guān)系。另外,這里有個例外,當(dāng)某個bounding box不負(fù)責(zé)對應(yīng)grid cell中g(shù)round truth box的預(yù)測,但是又與該ground truth box的IOU大于設(shè)定的閾值時(論文中是0.5,darknet中針對COCO數(shù)據(jù)集使用的是0.7),忽略該bounding box所有輸出的對loss的誤差貢獻(xiàn),包括置信度誤差,這時\mathbb{G}_{ij}=0,其他情況\mathbb{G}_{ij}=1。結(jié)合之前的說明可以看出,參數(shù)\mathbb{I}_{ij}^{obj}\widehat C_{i}^{j}的值其實是保持一致的。 如果你不理解為何作者這樣做,建議閱讀Faster RCNN的論文,作者的做法其實是借鑒了Faster RCNN的anchor box思想。

  • grid cell的個數(shù)S如何確定
    自v2后,YOLO算法網(wǎng)絡(luò)結(jié)構(gòu)中只使用卷積和池化操作進行特征提取和推理運算,去掉了傳統(tǒng)的全連接層,這樣的做法有一個好處,就是理論上整個網(wǎng)絡(luò)不再限制輸入圖片的尺寸,因為卷積層本來就對輸入的尺寸沒有限制。作者在這樣的基礎(chǔ)上,每隔一段訓(xùn)練周期隨意改變輸入層的尺寸后再進行下一階段訓(xùn)練,這樣就讓模型在不同尺寸的圖片上都表現(xiàn)良好,作者將之稱為Multi-Scale training。當(dāng)然,輸入的尺寸并不是隨心所欲地改變,而是在(10*32, 11*32, 12*32, 13*32, 14*32, 15*32, 16*32, 17*32, 18*32, 19*32)這幾個尺寸中隨機選擇。當(dāng)確定了輸入層的大小后,模型通過卷積層輸入輸出尺寸公式計算后,便能預(yù)先知道在某個輸入尺寸前提下,最后的輸出層尺寸是多少了,也就是grid cell的個數(shù),即loss函數(shù)中S的值。其實,S的取值只可能在集合(10*10,11*11, 12*12,...,19*19)中,因為YOLO模型的降采樣(down-sample)因子是32。

2.5 跨尺寸預(yù)測(Predictions across scales)

YOLO算法從三個不同的尺寸預(yù)測對象box,這三個不同的尺寸來自不同層級的卷積層的輸出。該方法借鑒了feature pyramid network的思想: 由于卷積層每隔幾層,特征映射(feature mapping)的寬和高就會減少,而通道數(shù)會增加,隨著網(wǎng)絡(luò)層次的加深,特征映射組成的形狀類似于金字塔,如果將不同層級的特征映射轉(zhuǎn)換為最終的輸出,那么將有助于提升模型在對象不同尺度大小上的表現(xiàn),即有助于提高模型從小目標(biāo)到大目標(biāo)的綜合檢測(box的精度)能力,關(guān)于feature pyramid network的具體內(nèi)容,此處不詳細(xì)展開,可參考論文。我們先看下YOLO模型的網(wǎng)絡(luò)結(jié)構(gòu),我們以檢測COCO數(shù)據(jù)集輸入尺寸為416*416的網(wǎng)絡(luò)結(jié)構(gòu)為例(COCO數(shù)據(jù)集類別數(shù)為80,anchor box總數(shù)為9):

從上面的模型的網(wǎng)絡(luò)結(jié)構(gòu)圖我們可以明顯看出基于darknet-53的最新的模型結(jié)構(gòu)有以下幾個特點:

  1. 從網(wǎng)絡(luò)的不同層次映射不同尺寸的輸出,如圖中從79層(外加兩個卷積層)得到13*13的的輸出;從91層(外加兩個卷積層)得到26*26的輸出;最后再得到52*52的輸出。
  2. 后面的高層結(jié)合使用低層特征(圖中的86、98層,分別使用了61層和36層的特征映射),使高層能使用細(xì)粒度(fine grained)特征和更多的語義信息。
  3. 最后一個尺寸輸出使用了前兩個尺寸計算的特征映射,使得最后的尺寸輸出也能使用細(xì)粒度。
  4. 每個YOLO輸出層中,每個grid cell的bounding box數(shù)量為3,而不是9,這樣不同的YOLO輸出層便能負(fù)責(zé)不同尺寸大小的對象預(yù)測了,這個思想來自SSD。例如,COCO數(shù)據(jù)集中,作者讓YOLO scale1負(fù)責(zé)預(yù)測的尺寸有(116,90)、(156,198)和(373,326), YOLO scale2負(fù)責(zé)預(yù)測的尺寸有(30,61)、(62,45)和(59,119),YOLO scale3負(fù)責(zé)預(yù)測的尺寸有(10,13)、 (16,30)和 (33,23)。

以上,就是我個人理解的YOLO算法的一些細(xì)節(jié)。

作者能力有限,不正確之處歡迎斧正。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容