# YOLO9000: Better, Faster, Stronger ###### tags: `CV論文` [論文連結](https://arxiv.org/pdf/1612.08242.pdf) ## Introduction 相較於物件偵測,物件分類的資料集通常比較好取得。不過到目前為止,我們仍無法將這兩種資料集結合。在這篇論文中,提出了一種方法可以處理這種問題:使用階層式的方式來看待物件分類,這可以讓我們將不同種類的資料集結合。 除了階層式的方法外,論文中也提出了一種joint training algorithm。透過這種演算法,可以<font color="blue">讓我們同時使用物件分類、物件偵測的資料集來訓練物件偵測模型</font>。透過物件辨識的資料集可以讓我們精準地定出物件的位置;透過物件分類資料集則可以擴充模型的預測類別種類,這樣可以讓物件辨識模型變得更加穩健(robust)。 本篇論文的思路為:先透過各種優化方式來改進YOLO,產生YOLOv2。接著再透過整合不同類型資料集的方式,讓模型變得更加穩健,進而得到YOLO9000。 ## Better 這是得到YOLOv2的過程,以下分別介紹各種優化方式: ### 1. Batch Normalization - 作法:在各個YOLO的各個捲積層都加上Batch Normalization。 - 優點:可以讓模型更容易收斂,最後讓mAP提高了2%。 ### 2. High Resolution Classifier 目前最好的物件偵測方法都是先使用ImageNet中,解析度小於256\*256的物件分類資料集來pre-train,之後再使用物件偵測的資料集進行第二次訓練。不過在YOLOv2中,他們在使用224\*224的分類資料集pretrain後,<font color="orangered">**還會再使用解析度為448\*448的分類資料集pre-train一次**</font>,過程中一共經歷了10個epochs。待第一階段的訓練fine tune後,再接著使用物件偵測資料集來訓練。這一共讓mAP提升了快4%。 ### 3. Convolutional With Anchor Boxes #### 引入Anchor Box概念,並取消全連接層 YOLOv2加入了Anchor Box,並且將原本YOLO中的全連接層拿掉。使用了Anchor Box的概念,就可以讓一個Grid Cell預測多個物體。這裡雖然提到要將全連接層拿掉,但其實不是因為使用了Anchor Box才不能用全連階層,而是作者想要透過捲積層讓網路有能力掌握全局。除了以上的改變外,作者為了提高輸出特徵圖的解析度,還將最後一層的pooling layer拿掉。 #### 強制讓Grid Cell變成奇數個 除了網路架構的改變外,作者還將原本大小為448\*448的訓練圖片改成416\*416。這麼做的原因是因為,這樣可以<font color="orangered">**讓Grid Cell變成奇數個,就可以讓圖片出現單一中心Grid Cell**</font>。 - 為什麼是變成416\*416呢? 由於YOLOv2輸出特徵圖的大小為輸入維度除以32,因此改成416\*416之後,可以讓14\*14的Grid Cell變成13\*13。 - 出現單一中心Grid Cell的好處? 大型物體的中心通常會出現在圖片正中心,照本來的做法,該物體會對應到中間四個Grid Cells。不過做完這個調整後,可以讓該類型物體只對應到一個Grid Cell。 #### 採用此方式對結果造成的變化 加入了Anchor Box後,mAP下降了一點,從69.5變成69.2。不過recall卻有了大提升,從81%變成88%。recall的提升說明了我們的模型還有可以提升的空間。 ### 4. Dimension Clusters 傳統選擇Anchor Box的作法為人工選擇,不過人工選擇的形狀不一定是最好的,因此YOLOv2提出<font color="orange">**採用K-Means來指定Anchor Box形狀**</font>的方式。YOLOv2在指定Anchor Box的形狀時,使用了K-Means的概念,將資料集中所有圖片的各個Bounding Box做分群,使用各群的群中心作為Anchor Box的形狀。透過這樣的方式,之後預測出來的Bounding Box也會比較準確。這可以使用機器學習的角度來解釋,由於給了一個好的初始值,因此也較容易收斂在好的地方。 比較特別的是<font color="blue">論文中採用的K-Means不是一般的作法,而是使用下圖公式來衡量樣本點到群中心的距離</font>。傳統K-Means使用歐式距離來衡量樣本點到群中心的距離,但這樣的做法不符合我們的期待,因為這樣會導致大BBox會產生比較小BBox還大的error。由於我們使用群中心來做為Anchor Box,因此會希望同群BBox的IoU算出來很大。使用以下公式時,他會將形狀接近的樣本分到同一群。 ![](https://i.imgur.com/sH7SnDs.png =80%x) 下圖左半邊是在不同數量cluster的情況下,對應的平均IoU。可以發現如果cluster的數量越多,則對應的IoU會越高,最後論文在IoU、模型複雜度的取捨下選擇了k=5。下圖右半邊則是選擇5個Anchor Box的情況下,COCO Dataset、VOC Dataset選到的5個群中心。可以發現最後選出來的結果,會有比較多瘦長的Anchor Box。 ![](https://i.imgur.com/SBg9kmD.png) ### 5. Direct location prediction 本篇論文中採用其他論文中提到的Anchor Box概念,在其它篇論文中預測Bounding Box的方式是:透過神經網路得到$t_x$、$t_y$、$x_a$、$y_a$等參數,之後再透過下圖式子得到預測出的Bounding Box,其中式子中的$w_a$、$h_a$代表的是Anchor Box a的長、寬。不過使用這個式子會有個問題,因為<font color="blue">$t_x$、$t_y$、$x_a$、$y_a$的數值範圍都沒有被限制,因此神經網路在訓練的過程也會變得比較不穩定,需要花很多的時間才能得到比較好的結果</font>。 ![](https://i.imgur.com/Uf0f5OA.png) 基於以上原因,本篇論文沿用與YOLOv1相同的方法,針對各個Grid Cell來做預測,並且將$t_x$、$t_y$、$t_x$、$t_y$、$t_o$限制在0、1之間。下圖式子為Bounding Box的詳細計算方式,其中$\sigma(x)$代表sigmoid function,$p_h$、$p_w$則分別代表Anchor Box的長、寬,$c_x$、$c_y$代表的是Grid Cell的左上角。 ![](https://i.imgur.com/zDbNRIf.png) 改成以上的做法後,Bounding Box的位置、大小會變得較好學習。最後可以得到結論:加上**Dimension Clusters**、**Direct location prediction**後,讓mAP提升了5%。 ### 6. Fine-Grained Features YOLOv2的架構中使用了5個pooling layers,因此原本416\*416的輸入圖片會被縮小為13\*13的特徵圖,之後再將這個特徵圖丟到捲積層預測輸出張量。13\*13的特徵圖的解析度很低,雖然預測大型物體時沒什麼問題,但卻<font color="blue">很難預測小型物體</font>。 我認為解析度造成預測小型物體的困難點在於:在池化的過程中,本來已經很小的物體會變得更小,造成很難觀察出該物體的特性。以極端一點的例子來說,假如一個物體本來的大小為32\*32,那麼經過壓縮後他的大小就會變成1\*1,就很難辨識。如果物體再小一點的話,甚至有可能該物體完全不會出現在13\*13的特徵圖上。 基於以上原因,本篇論文引入了<font color="orangered">**passthrough layer**</font>的概念。所謂的passthrough layer就是將前面比較高解析度的特徵圖往後連接,本論文中他將前面26\*26的特徵圖往後拉到13\*13那層,並將它們串連起來。透過這個方式,我們就<font color="blue">可以同時針對高解析度、低解析度的特徵圖做捲積,得到物件的預測</font>。具體的串聯作法為:將本來26\*26\*512的特徵圖轉換成13\*13\*2048的特徵圖,之後再將他跟本來13\*13的特徵圖串在一起,也就是增加13\*13特徵圖的Channel數。 ### 7. Multi-Scale Training 如同前面說的,YOLOv2是使用大小為416\*416的訓練資料訓練而成的。但因為YOLOv2的整體架構只包含捲積層、池化層,因此讓我們可以在訓練的過程中,任意調整訓練資料的大小。善用這個特性,我們可以在訓練的過程中,使用各種不同大小的圖片,讓訓練出來的模型可以用來預測任意大小的圖片。訓練過程中,作者每間隔10個epoches就會從{320, 352, ..., 608}這些尺寸中,隨機選擇新的大小來訓練。 由於YOLOv2使用了多種尺寸的資料來做訓練,因此他得到的模型可以用於預測任意尺寸圖片。如果使用該模型來預測小尺寸圖片,可以在更短的時間內預測完成,不過伴隨著的是準確率的下降。將模型應用於預測288\*288的圖片,可以達到90FPS的預測速度,而且mAP也跟Fast R-CNN差不多;如果應用於預測544\*544的圖片,mAP則是可以達到78.6,比其他物件偵測模型都還要好,而且預測速度也還有40FPS,仍然屬於real-time detection。 ![](https://i.imgur.com/o8yuu8k.png) ## Faster 目前有很多物件偵測模型都使用VGG-16作為base feature extractor。VGG-16雖然是個很精準的物件分類網路,但缺點就是太複雜了。因此這篇論文中,提出了一個新的特徵抽取模型Darknet-19。Darknet-19的運算比VGG-16少很多,而且最後可以得到跟VGG-16差不多的精準度。 ### Darknet-19 採用跟VGG-16差不多的設計方式,使用大量$3\times3$的捲積層,並且每次經過Pooling後,都會將通道數量變為原本的兩倍。除此之外,也採用跟Network in Network差不多的做法,在神經網路的最後使用Global Average Pooling,以及在$3\times3$捲積層中加加入$1\times1$捲積層來壓縮特徵數。另外,也會在每個捲積層後加入Batch Normalization,這可以加快訓練時收斂的速度。 下圖為Darknet-19的架構: ![](https://i.imgur.com/288tmxB.png) ### Training for Classification 首先先使用ImageNet 1000 class物件分類資料集來訓練上述架構,訓練過程共經歷160個epochs,使用Stochastic Gradient Descent來訓練(詳細參數設置見論文)。另外,也使用了一些資料增強的方式,包含random crops, rotations,以及色調、飽和度、曝光度的轉換。 在上述的訓練完成後,會像前面提到的一樣,再轉到$448\times448$的圖片訓練。訓練過程一樣採用Stochastic Gradient Descent,不過這次只訓練10個epochs。 ### Training for Detection 在訓練完分類模型後,稍微修改一下網路,將原本最後一層的捲積層拿掉,改成連接三個$3\times3$,通道數為$1024$的捲積層。之後再連接一個$1\times1$的捲積層,這個捲積層的通道數取決於每個Grid Cell的特徵數。以VOC來說,假如一個Grid Cell預測5個Bounding Box,則一個Grid Cell就會有125維的特徵,因此就是使用125個通道的$1\times1$捲積層。另外,就像前面提到的,架構中還使用了passthrough layer,從$3\times3\times512$的最後一層連接到整個網路的倒數第二層,這樣做可以讓最後一層抓到的特徵包含高解析度、低解析度的特徵。 訓練的過程使用了160個epochs,並搭配Stochastic Gradient Descent(參數詳見論文)。 ## Stronger 這是論文中屬於YOLO9000的部分,前面則是YOLOv2,YOLO9000即為將多個不同類型的資料集結合起來訓練。他的概念是使用物件偵測的資料集來做基本訓練,並用物件分類的資料集來擴展物件的分類類別。<font color="blue">訓練的過程中,如果遇到物件分類的資料,就只更新Loss Function中分類相關的部分;如果遇到物件偵測的資料,則對完整Loss Function更新</font>。不過這個方法有個問題:由於物件偵測、物件分類資料集中的各個類別不是互斥的,因此如果使用一般Softmax時會有問題。 ### Hierarchical classification 如果我們要將COCO Dataset跟ImageNet 1000合併在一起訓練,就必須將ImageNet 1000以階層式表示。因為如果我們知道某個物件最可能是狗,接著要再看他屬於哪一種狗,這時就會需要知道有哪些類別是狗,並將這些類別的結果取Softmax,就可以進而知道該物件是屬於哪一種狗。 **如何將ImageNet 1000的類別表示為階層式呢?** 由於ImageNet 1000各類別名稱從WordNet得到的,而WordNet表示了各個英文字彙的階層關係,因此可以透過WordNet來建立ImageNet 1000的階層關係。不過因為英文字彙是非常複雜的,一個類別可能會對應到多個父類別,因此必須再想辦法讓所有類別都只對應到一個父節點。作法即使用Minimal Spanning Tree,透過這個方法就可以將本來的Directed Graph變成Tree。不過在建立Tree的過程,我們希望Tree越小越好,因此如果某個類別對應到不同父節點,我們就只會保留到根節點的最短路徑。透過這個方法得到的結果就叫做<font color="red">**WordTree**</font>,他以階層的方式表達了ImageNet 1000。 使用WordTree架構來做物件分類時,模型會計算各個類別物件的<font color="red">**條件機率**</font>。例如狗一共分成三種,這時就會透過Softmax來得到目標是狗的條件下,他屬於不同品種的條件機率。由於我們會分別針對各個類別計算條件機率,因此最後<font color="blue">如果想要知道物件屬於某個類別的確切機率,就要沿著父節點往上走到root,將過程中所有條件機率相乘</font>。 為了驗證這個方式,論文中使用Darknet-19,搭配前面得到的WordTree來訓練。他在訓練的過程中,將WordTree中的所有類別加入預測,因此總類別數會從原本的1000變成1369。假如訓練時的Ground Truth是德國獵犬,那麼除了德國獵犬的所有父類別也都會標記為1<font color="gray">(這部分論文中沒有提到確切的方式,但我猜是針對各個類別都做一次權重更新,在相同輸入圖片的情況下,分別將目標函數設為德國獵犬、哺乳類、狗來訓練一次。)</font>。<font color="orange">**在預測時**</font>,我們為了要知道物件屬於各個類別的確切機率,因此要<font color="orange">**針對預測結果中相同類別的物件取Softmax**</font>,得到他們的條件機率。 之後使用跟之前相同的參數來訓練,結果可以發現,雖然加了那麼多類別,但精準度只有下降一些。除此之外,透過這個方式還有一個好處,如果模型預測出某個物件是狗,但不確定他是什麼類型的狗,他可能就不會再細分下去,直接將結果回傳為狗。<font color="blue">他的做法是從root來看他屬於各個類別的機率,每次取較大的條件機率來相乘,並且一直往下看,直到算出來的確切機率小於某個閾值。</font> ### Dataset combination with WordTree 由於WordTree是從WordNet衍伸而來的,因此他裏面包含了很多種英文詞彙。我們可以透過WordTree來將多個Dataset合併,合併方法為:將額外資料集的各個類別加入WordTree中合適的位置。 ### Joint classification and detection 透過WordTree,我們就可以將多個不同的資料集合在一起訓練。由於我們希望訓練大規模的物件偵測器,因此我們將COCO Dataset跟ImageNet中最多的9000類合併,合併後的WordTree會對應到9418類。由於ImageNet的規模比COCO Dataset要大上許多,因此我們在訓練的時候,會對Oversampling四倍COCO Dataset。 使用上述資料集來訓練YOLO9000模型,訓練使用的神經網路架構為YOLOv2,只是為了減少輸出張量的維度,因此每個Grid Cell只使用3個Anchor Box。訓練過程中,如果遇到物件分類的訓練資料,則只更新損失函數中類別的部分。而且在反向傳播的時候還要注意,我們<font color="blue">不會去計算Ground Truth計算子類別的Error</font>。例如Ground Truth是狗,那我們就不會去計算德國獵犬、柴犬等類別的誤差。 物件分類的訓練資料只有圖片中主要物體的類別,但其實一張圖片可能存在多個不同物品,直接套用我們的模型就會預測出多個Bounding Box。為了確保訓練時看的是正確的物體,因此我們應該去<font color="blue">看哪個Bounding Box最可能代表該物體,之後就只使用該Bounding Box的預測結果來更計算訓練誤差</font>。另外,我們還會要求預測出來的Bounding Box跟Ground Truth的<font color="blue">IoU要大於0.3</font>。 在完成訓練後,論文中使用ImageNet的detection task來評估模型,其中有156個類別是我們沒看過的。最後測出來的結果,整體平均為19.7mAP,如果只看沒看過的那些類別則為16.0mAP。由於得到的結果不太好,因此之後論文有去觀察沒看過的這156類資料的預測結果。最後發現他在預測沒看過的動物也可以很準,最好的為61.7AP,只是裡面有很多服飾類的就預測不準,結果為0.0AP。造成這個的原因是因為COCO裡面沒有服飾類別的資料,但由於有動物的資料,因此動物的預測還算精準。 ![](https://i.imgur.com/lNPX2bq.png)