Deep Learning Notes — Object Detection Model YOLO

Source: Deep Learning on Medium


Go to the profile of Woody Yao

自從Faster R-CNN上台講完之後就一直提不起勁再接著寫YOLO,加上前陣子在看的GAN、VAE跟Q-Learning原理又太複雜一直卡住看不懂,只好再回頭寫這篇湊個數。

YOLO實際上並未使用到什麼非常高深的數學或原理,其實大部分概念如sliding window及共用卷積層都是取自DPM、Faster R-CNN,但架構上比Faster R-CNN更加簡化,且毋須像Faster R-CNN將regional proposal、object detection、image classification三者分開訓練(如果想知道Faster R-CNN在訓練階段到底有多麻煩的話請參考上一篇介紹。),加上卷積層的資訊共享程度更高而可以使計算速度可以更進一步達到45FPS以上。因此在2016一發佈便造成轟動,直到現在YOLO仍是相當主流的物件框架辨識演算法。

具體而言,YOLO相較於之前的其他演算法,有什麼突破/優化呢?

  1. 將物件辨識簡化為一個迴歸問題,將影像內的像素經過訓練壓縮後輸出框架的錨點、長寬及物件存在可能性(近似Faster R-CNN,但Faster R-CNN將分類及框架定位分開計算及訓練)。YOLO只需要單一一個卷積網路就可以同時預測多個框架以及這些框架存在物件的可能性,訓練時也是將整張圖丟進去訓練並直接依結果調整演算法參數以達到最佳化,無需像之前SS做大量裁切。
  2. 訓練完之後實際執行達到45FPS,做部分準確度與模型複雜度的trade-off之後甚至可達到150FPS,而在此之前的Faster R-CNN也僅能達到5FPS,運算速度完全海放舊模型。
  3. YOLO因將整張原圖一起丟進模型裡做運算及偵測,故在執行框架預測時有更多的背景及周邊資訊可以協助判斷。比起採用SS裁切後才進行判斷及訓練的Fast R-CNN,YOLO將背景及物件搞混的數量的僅為Fast R-CNN的一半不到。
  4. YOLO比起之前的物件偵測演算法可以更完整學習物件的泛化特徵,故即使訓練YOLO時只使用照片等真實圖像,將非真實的藝術作品如繪畫、塗鴉等納入此模型做物件偵測其表現也完全海放DPM及R-CNN。
  5. 雖然YOLO比起之前的其他演算法真的是好棒棒,但它還是有物件定位不精準的問題,尤其是對於小型物件(個人猜測應該是因為論文採用的sliding window較小的關係?)

Unified Detection

YOLO成功將多個物件偵測功能整合進單一一個神經網路中。因此YOLO可以依圖片的不同特徵來辨認各個物件框架,並能同時預測個別框架分別屬於哪個物件。

那實際上這網路框架要怎麼運作呢?

首先,YOLO會將一張圖片拆分成不重疊的SxS網格,而當我們要預測的物件中心點位於哪一個網格中,該網格便要負責成功偵測此物件。

接著每一個網格在輪到它表現的時候都要各預測出B個物件框架(超參數)以及對這些框架的信心程度(是物件或是背景)。信心程度的計算式如下所示:

  • conf. score = Pr(Object) * IOU (groundtruth)

如預期沒有任何物件落在這個網格內,則所有信心程度均應為0;若否則依物件可能性及估計框架與實際框架重合程度計算信心程度。

而每個框架都需要計算五個核心元素:框架中心座標值(x, y)、框架長寬(w, h)、及信心程度 (0–1)。論文中提到(x,y)是相對於網格邊界的位置,而(w,h)則是佔整張圖片的比例,兩者與信心程度均介於0到1之間。但Andrew Ng的Deep Learning 課程中則是將(w,h)一樣依網格比例計算,故(w,h)值是很有可能超過1的。

而除了這五個必備數值以外,剩下的即是想要偵測的各種物件/class的可能性Pr(Class-i|Object),想偵測N種就另外加N個欄位。值得特別注意的是,這裡物件類別的偵測是以網格為單位而非以框架為單位,也就是說如果A網格總共會產出B個物件框架,但在整個A網格裡只會計算一組C種物件存在於這個網格之中的可能性並由該網格內的所有框架共用。測試時是將conditional class probabilities乘上每個box的conf. predictions:

  • Pr(Class-i|Object) * Pr(Object) * IOU = Pr(Class-i) * IOU

如此一來便可得到每個box中對各個類別的信心程度。這些信心分數同時量化該類物件存在於框架中的可能性以及預測的框架大小是否適合該物件。

圖解YOLO作業模式,輸出值的框架為 N * N * (B * 5 + C) (網格欄數 * 網格列數 * ((每個網格須預測的框架數 * 每個框架必須要有的5個定位及預測分數) + 網格內包含每種物件類別的可能性))

(筆者在Andrew Ng的課堂作業中看到這部分在執行時會以每個框架為單位在這種類別偵測時會採用softmax,惟還會另外採用Non-maximum supression,故結果出來僅有可能性最大者為1,其他均為0。但採用此法的前提即是每個框架都只偵測一個物件,故計算時是以框架為單位輸出N*N*(B*(5+C))。相較於論文採用整個網格內的所有框架共用一組類別預測值的方式,Andrew的方式在Coding及loss function的設計上更直觀一些;論文並未詳細說明其如何整合不同框架對該共用類別的分數回饋機制,這部份可能要去看團隊釋出的原始碼才能略知一二了。希望他們有Python的版本lol)

YOLO framework from Andrew Ng

Network Design

YOLO在卷積網路的設計上主要參考GoogLeNet,共24個卷積層及2個全連接層;但和GoogLeNet不同的地方在於這裡並不採用Inception Module並聯多個卷積層(相關說明詳GoogLeNet)而僅採用單純的將1*1及3*3等卷積層做單向連結(論文另外訓練了一版只有9個卷積層的Fast YOLO版本,但參數及模型設計與YOLO一致):

在這個網路架構中1*1卷積層可以極佳達到壓縮模型及降維;其中卷積層先以ImageNet分類集做參數的Pre-train(將資料及原本224*224的圖片擴展為448*448以和YOLO論文適用的資料集圖片大小一致)

此網路結構最後會輸出一個7*7*30(長寬均分為7*7=49個網格,每個網格預測2個框架*5個框架值+20類物件分類)的張量(tensor)。

Training

YOLO使用了2012 ImageNet 1000-class 訓練資料集來執行上圖模型中的前20層卷積層,後面接一層avg.-pooling layer 跟一個全連結層。大概花了1週的訓練時間而最後 top-5 accuracy(意即前五個可能性最高的預測值中有一個與實際值一致)達到88% (ImageNet 2012 資料庫中的驗證資料集),其中訓練及推算皆是使用Darknet架構(一個以C語言編寫,專為YOLO設計的演算法環境)。訓練後在模型後面加上隨機初始參數的4個卷積層及2個全連接層以提升準確度。由於物件偵測需要更多的紋理細節特徵所以將原本輸入從224×224擴展至448×448。最後的全連接層同時預測每一類別的機率以及框架參數值,同時會將框架的長寬值針對影像長寬來正規化至0到1(稍早已提過Andrew Ng課程採用不同的設計方式,不再贅述)以及將中心座標值(x,y)也針對該執行預測輸出的網格進行正規化至0到1。在網路結構中最後一層使用linear activation(此處筆者查了其他文章均未見說明。基本上受限於微積分的基本原理,激勵函數的設計必須是非線性。應該是指ReLU),而其他層的激勵函數則是使用leaky ReLU:

Leaky ReLU

最佳化則使用最小平方法來做評估及迭代。使用最小平方法的好處是使用上相當簡單,缺點是無法完美符合演算法最大化平均準確率的目標。這個方法會將框架定位錯誤跟物件分類錯誤用一樣的比重做衡量。此外對未包含任何物件之網格,其框架的信心程度會被推向0,而導致有偵測到物件的網格在計算梯度時其重要性會被過度放大。這些都會導致模型的不穩定,並使訓練走偏方向。為了改善這部分,模型增加了框架迭代值的權重並減少未包含物件的信心指數權重,分別採用兩個超參數 λ-coord = 5 及 λ-noobj = 0.5。

此外最小平方法也會給予小框架及大框架一樣的權重,但一樣的離散值在對大框架的影響程度應低於其對小框架之影響。為解決此問題,YOLO透過利用預測框架時輸出寬高的平方根而非直接輸出寬高值。

再來因為YOLO架構下每個網格都會輸出多個框架預測值,但無論在訓練或測試階段我們都只想要用單一框架來對應每個物件。這可以藉由採用與訓練集中的實際框架有最高IOU(重疊比例)的框架預測值來達成。

將上述所有考量及調整納入後,YOLO採用的最佳化loss function為如下所示:

值得注意的是該loss function只在網格裡”應該要偵測到物件”時對分類錯誤進行懲罰(Otherwise we don’t care about it),以及只懲罰擁有最高IOU的框架預測值。

其他訓練資訊(超參數設計):對PASCAL VOC 2007 及 2012的訓練及驗證資料集進行135次迭代、在測試PASCAL VOC 2012時將PASCAL VOC 2007的測試集資料也納入訓練;
Batch-size:64
Momentum:0.9
Weight-decay:0.0005
Learning-rate:
0–75 epochs: 0.01
76–105 epochs: 0.001
106–135 epochs: 0.0001
Dropout: 0.5 (在第一個全連接層之後)
並另外採用data augmentation以增加更多的訓練資料。

實際測試時其實就跟訓練階段沒什麼差別,另外提到部分超大型物件可能會有被分散在多個預測框架內的情形,採用NMS可以有效抑制並使mAP提升2~3%。

LIMITATION

論文中提到YOLO對於較小且成群出現的物件偵測及框架預測上表現不佳;此外因為模型中為了加快速度在多個卷積層中都加入了降維的設計(downsampling),對於長寬比和形狀較為特異的物件表現也會受到影響;最後則是演算法對於小型框架及大型框架的偏差值用一樣的模式去衡量,但兩者對IOU的影響可能相當不同。YOLO主要的錯誤也是集中在不正確的框架定位。

PERFORMANCE

相較於當時已經是最快速且準確率也還不錯的物件偵測演算法Faster R-CNN,YOLO依然快上至少一個檔次且尚能維持還不錯的準確率。


在YOLO發表之後,因為其簡單且泛用的特性,著實讓機器視覺跟物件偵測演算法在近年來起飛。但與物件偵測一起降臨的人臉辨識演算法也在近年對文明、人身自由(各式各樣的實時監控系統)及資訊傳播(fake face)帶來極大的威脅。有時候也真的不太清楚這種科技知識普及大眾化到底是好還是壞。

過陣子再來談談YOLO v2及v3做了哪些修正跟改進。

參考資料:

YOLO Original Paper

YOLO — You Only Look Once 介紹

GoogLeNet Introduction

Hackernoon — Understanding YOLO

Real-time Object Detection with YOLO, YOLOv2 and now YOLOv3

Bounding box object detectors: understanding YOLO, You Look Only Once


Originally published at python5566.wordpress.com on February 13, 2019.