論文心得系列
You Only Look Once(YOLO) : Unified,Real-Time Object Detection
(以上的圖片部分參考至此篇論文)
論文連結 : https://arxiv.org/abs/1506.02640
目錄 :
1.前情提要以及背景介紹
2.核心技術 (特製的output架構以及lossfunction)
3.如何訓練YOLO以及運作中的小細節
4.結論
5.後續補充與紀錄
1.前情提要以及背景介紹 :
YOLO為 Joseph Redmon大神所造出用於object detection的deep learning framework。在以往的做法包含DPM、R-CNN皆無法及時的處理物件偵測的問題,並且再模型架構上都有著較為複雜的結構,而YOLO的核心目的就是為了要解決這些問題,它有著非常清楚簡潔的模型架構(不用分開多次訓練)以及非常快的速度。然而深度學習的技術隨著時間不斷的在演化精進,YOLO也在不斷的變化,由最原始的YOLO V1演變至現在的YOLO V5,我們將匯率續的介紹這些不同YOLO版本的細節以及其相關的連動性。
2.核心技術 :
在YOLO橫空出世以前,R-CNN系列的方法稱霸了整個object detection,並有著很高的精準度(其中的翹楚為Faster R-CNN)。然而儘管如此,Faster R-CNN還是有著讓人詬病的缺點 : 模型分成兩段(分別為RPN網路,以及Faster R-CNN的本體網路)。也因為這樣我們會遇到底下幾個問題 :
- 在訓練模型的時候需要分開訓練(RPN網路與Faster R-CNN網路交互訓練)。
- 在訓練RPN網路的過程中,需要計算大量的IoU。這部分會使得整體的速度大幅下降,導致於無法及時對物體偵測。
- 在之前的文章中亦有提到過,微調物體框這個動作分別在兩個網路中都有進行,似乎有著重複運算的嫌疑。
- 精準度的侷限性。(這部分可能比較勝之不武,畢竟Faster R-CNN是以VGG16為底層架構去發展,而YOLO系列則為較新的主架構)
為了解決這些問題,YOLO提出的解法為 : 將物件偵測的問題思考為一個回歸問題。這也是YOLO最為核心的想法。
講的白化一點就是 : Input為一張待檢測image,而輸出則為其(x,y,w,h,類別1的機率,類別2的機率...)。其中x,y分別為物體中心點的座標而w,h則為其大小(寬、高)。

這樣的想法看起來非常直覺且簡單,然而當換一張影像時,我們會發現有一個致命性的問題 : output的size無法定義!

面對這樣的問題,YOLO提出一個簡單的方式來解決,將輸入影像分割成固定等分(論文中輸入影像為448x448,將其分割為7x7的網格)。
設立這個網格的目的為固定output size。以上面的影像作為例子,也就是說對於所有的input image而言,output vector size都為49x6。

我們只需要對那些真實物體框所落在的網格進行label其物體資訊,也就是說當我們將影像分割為49個部分後,我們的輸出最多可以有49個物體。而這些物體只要其中心點落在不同的網格之中,我們都可以清楚地把它標記(找)出來,而不會發生輸出維度無法定義的問題。(實際上在論文中每個網格可以有2個框的輸出,也就是最多可以偵測出98個框,這裡先賣個關子,產生框不代表是輸出物體)
定義完輸入與輸出,我們就需要提到YOLO的loss function長什麼樣子。以下為其loss的定義 :

如上式,YOLO的loss function 總共區分為5個部分的加總,分別對應到了其輸出的結果。其中有幾個部分比較有意思 :
- 在計算w,h的loss時,先使其開更號才進行計算。這部分主要是在避免大物體的長寬loss過大而影響到整個loss的更新。
- 在計算網格中物體的類別誤差項時,並未使用cross entropy,而是使用least squares來對其計算。這部分在論文中有進行解釋,原因least squares為於訓練中較好收斂。
介紹完loss function我們來看看YOLO的網路架構,受到GoogLeNet的啟發,YOLO將網路設計成24個卷機層與2個全連接層 :

可以看到網路架構清楚簡單,主要是透過GoogLeNet的1x1Conv來降低參數量,並與VGG16合併。其中output的7x7為grid的數量,而每個grid中含有2個bounding box(2x5)以及20個類別的分類結果,總共合起來剛好是30個維度。
另外,YOLO選擇使用Leaky ReLU來作為其模型架構的activition function。

3.如何訓練YOLO以及運作中的小細節
如果沒有仔細思考或是實際運作過的經驗,到這裡後就會認為YOLO已經結束了,沒什麼特別了不起的地方(很直覺),然而仔細思考後會發現其實內部隱藏了許多的小細節等著我們慢慢的琢磨品味。
我們將從output開始慢慢說起 :
- YOLO對每個grid都產生兩個bounding box,並計算其位置以及類別。然而對於每個grid,我們只會有一組類別的output!為什麼會這樣呢?
對於同一個grid中,雖然我們會有兩個bounding box,並分別使用這兩個bounding boxed與ground truth中IoU最大的那個結果進行loss的計算(ground truth中要先有物體才會計算),然而最後我們只會在同一個grid中選擇一個最好的bounding box作為輸出,故只需要output一組類別就好。
那竟然只要輸出一個物體,為什麼需要有兩個bounding box?我的理解是因為這些box是非常隨機的,如果只選擇一個bounding box,而這個bounding box因為起始的參數與ground truth有著較大的差距,這樣會容易讓模型不好收斂(就跟Anchor需要取多個一樣)。而增加bounding box的數量有助於每次更新參數時,較貼近ground truth的機率,而讓模型較好訓練。(我的推測)
有這樣的想法後,我們可以再次回來看我們的loss function :

可以觀察到在第五式在判斷類別誤差項的式子並沒有考慮到每個bounding box。而在第一式中,我們會注意到有一個1的參數,這個參數是用來判斷這個grid中是否有物體,如果沒有物體則很顯然就不用計算邊界框的所有誤差項,那如果有物體的話,我們就會去看這個grid中哪一個bounding box與ground truth中IoU最大,我們僅計算這個bounding box的邊框誤差項,並且將剩餘的那個bounding box視為沒有框到實際物體。
- 觀察到第二式中在計算邊界框長寬誤差項時,先對其開更號才對其計算least square,那為什麼要這樣做呢?
對於大物體跟小物題而言,邊框的大小比例變動對於其IoU的影響並不一致 :

所以說在loss的部分必須要謹慎地將這部分考慮進去,才不會讓小物體在判斷上失準。而YOLO使用的方式則是透過加入開更號來巧妙的避開這個問題。
我們可以透過把更號的圖形畫出來解讀他 :

可以發現透過更號的調整後,對於同樣的增幅,在數字比較小的情況下會有較大的變動。透過這樣的方式可以些微(很重要!在YOLO v1並沒有完整解決這個問題)改善小物體不容易被訓練好的部分。也就是這樣,我們才會看到loss function進行這樣的調整。
- 幾個輿論文中提及,能夠讓模型更容易收斂的方法 :
- 將w,h,x,y透過座標轉換的方式讓其皆於01之間。(對於每個grid,將其大小視為1,以此來定義x,y的位置;分別把w,h除以原始影像的長與寬)。
- 將ground truth的置信值設計為(是否有物體x偵測框與ground truth的IoU)。也就是說每一次ground truth的置信值都是不一樣的!(仔細想想就會覺得很合理。對於一個偵測框而言,要如何去定義這個框的置信值。假設給定了一個隨意的徵測框,我們不會認為他的置信值應該要是1,而是給予其一個相對應的置信結果。)

- 最後有一個值得思考的事為其輸出! 在YOLO架構中最後幾層為fully connected,而我們又要如何把它換成7x7x30的樣式呢?其實單純是把flatten後的資料reshape回去而已。所以對於這些資料排列的順序並沒有太大的意義,只要定義好確定的位置即可。然而我們會發現一件事! 在YOLO v1的架構中並沒有softmax(而是只通過一個sigmal function讓結果皆於01之間)也就是說對於物體的分類與置信值而言,我們並不是去預測一個機率,而是把它當成迴歸分析一樣,將其學習為1或0這個數字。這也呼應了最開始YOLO v1的核心概念 : 利用回歸的想法來解決分類的問題!
(可能是狗的置信值為0.8、是貓的置信值為0.7,類似這樣的概念)
4.結論
YOLO v1提出了一個突破性的想法,並沒有項R-CNN系列一樣將模型分成兩個部份去訓練,而是一氣呵成的把所有結果都訓練出來。並且在速度上有著驚人的表現,然而透過我們上述的介紹,還是能發現YOLO v1的部分缺陷 :
- 對於小物體比較容易出錯(雖然透過修改w,h的loss計算,但仍然無法解決本質上的問題)
- 對於較為密集的物體較無法判斷。(每個grid只能有一個output)
然而這些缺陷都會成為YOLO v2與v3的突破口,讓整體算法更為精進。
以上是我對YOLO v1的心得分享,謝謝。
5.後續補充與紀錄 :
- 論文中提及YOLO的算力為1秒45幀(Titan X GPU),並且提及了Fast YOLO為1秒155幀。其中Fast YOLO的整體架構與YOLO一致,不過其類神經網路由24層簡化至9層。
網路上也有查到其他稱之為Fast YOLO的paper,不過看起來根本文所提及的Fast YOLO並不一致。
附上其論文地址 : https://arxiv.org/pdf/1902.06827。
- YOLO主要的對手其實是DPM與R-CNN系列。關於這兩個部分DPM尚須研讀;R-CNN已經研讀完畢。
- YOLO命名的由來you only look once (YOLO) at an image to predict what objects are present and where they are.其實這也挺重要的,將以往需要分段來解物件偵測的問題合併成一個完整架構,只需要看一次 !
- 在pre-train model的時候採用224x224的data size來pre-train,但在正式訓練的部分則使用較高的解析度來訓練。(448x448)
- 因為大多數的格子點內是沒有物體的(假設),所以YOLO在設計loss function的時候才會設計(有物體;沒物體)的參數,來平衡避免沒物體的資料過多而導致所有的置信值都逼近沒物體的方向收斂。
- 使用Non-maximal suppression來做後處理(當一個物體很大時,中心點可能很接近1個以上的偵測框,導致產生多個結果,這時候就會使用Non-maximal suppression來做偵測框挑選的動作)
