參考:
http://blog.csdn.net/u011534057/article/details/51244354
https://zhuanlan.zhihu.com/p/24916786
論文下載:http://arxiv.org/abs/1506.02640
darknet版的代碼下載:https://github.com/pjreddie/darknet
tensorflow版本的代碼下載:https://github.com/hizhangp/yolo_tensorflow
源碼分析可參考:https://zhuanlan.zhihu.com/p/25053311
後續我會針對這個模型給出具體的實踐文章。
這是繼RCNN,fast-RCNN 和 faster-RCNN之後,rbg(Ross Girshick)大神掛名的又一大作,起了一個很娛樂化的名字:YOLO。
雖然目前版本還有一些硬傷,但是解決了目前基於DL檢測中一個大痛點,就是速度問題。
其增強版本GPU中能跑45fps,簡化版本155fps。
YOLO主要特點是:
- 速度快,能夠達到實時的要求。在 Titan X 的 GPU 上 能夠達到 45 幀每秒。
- 使用全圖作爲 Context 信息,背景錯誤(把背景錯認爲物體)比較少。
- 泛化能力強。
1. YOLO的核心思想
-
YOLO的核心思想就是利用整張圖作爲網絡的輸入,直接在輸出層迴歸bounding box的位置和bounding box所屬的類別。
-
沒記錯的話faster RCNN中也直接用整張圖作爲輸入,但是faster-RCNN整體還是採用了RCNN那種 proposal+classifier的思想,只不過是將提取proposal的步驟放在CNN中實現了。
2.YOLO的實現方法
- 將一幅圖像分成SxS個網格(grid cell),如果某個object的中心 落在這個網格中,則這個網格就負責預測這個object。
-
每個網格要預測B個bounding box,每個bounding box除了要回歸自身的位置之外,還要附帶預測一個confidence值。
這個confidence代表了所預測的box中含有object的置信度和這個box預測的有多準兩重信息,其值是這樣計算的:
其中如果有object落在一個grid cell裏,第一項取1,否則取0。 第二項是預測的bounding box和實際的groundtruth之間的IoU值。 -
每個bounding box要預測(x, y, w, h)和confidence共5個值,每個網格還要預測一個類別信息,記爲C類。則SxS個網格,每個網格要預測B個bounding box還要預測C個categories。輸出就是S x S x (5*B+C)的一個tensor。
注意:class信息是針對每個網格的,confidence信息是針對每個bounding box的。 -
舉例說明: 在PASCAL VOC中,圖像輸入爲448x448,取S=7,B=2,一共有20個類別(C=20)。則輸出就是7x7x30的一個tensor。
整個網絡結構如下圖所示:網絡設計:
網絡結構借鑑了 GoogLeNet 。24個卷積層,2個全鏈接層。(用1×1 reduction layers 緊跟 3×3 convolutional layers 取代Goolenet的 inception modules )
-
在test的時候,每個網格預測的class信息和bounding box預測的confidence信息相乘,就得到每個bounding box的class-specific confidence score:
等式左邊第一項就是每個網格預測的類別信息,第二三項就是每個bounding box預測的confidence。這個乘積即encode了預測的box屬於某一類的概率,也有該box準確度的信息。 -
得到每個box的class-specific confidence score以後,設置閾值,濾掉得分低的boxes,對保留的boxes進行NMS處理,就得到最終的檢測結果。
3.YOLO的實現細節
-
每個grid有30維,這30維中,8維是迴歸box的座標,2維是box的confidence,還有20維是類別。
其中座標的x,y用對應網格的offset歸一化到0-1之間,w,h用圖像的width和height歸一化到0-1之間。 -
在實現中,最主要的就是怎麼設計損失函數,讓這個三個方面得到很好的平衡。作者簡單粗暴的全部採用了sum-squared error loss來做這件事。
這種做法存在以下幾個問題:
第一,8維的localization error和20維的classification error同等重要顯然是不合理的;
第二,如果一個網格中沒有object(一幅圖中這種網格很多),那麼就會將這些網格中的box的confidence push到0,相比於較少的有object的網格,這種做法是overpowering的,這會導致網絡不穩定甚至發散。
解決辦法:- 更重視8維的座標預測,給這些損失前面賦予更大的loss weight, 記爲在pascal VOC訓練中取5。
- 對沒有object的box的confidence loss,賦予小的loss weight,記爲在pascal VOC訓練中取0.5。
- 有object的box的confidence loss和類別的loss的loss weight正常取1。
-
對不同大小的box預測中,相比於大box預測偏一點,小box預測偏一點肯定更不能被忍受的。而sum-square error loss中對同樣的偏移loss是一樣。
爲了緩和這個問題,作者用了一個比較取巧的辦法,就是將box的width和height取平方根代替原本的height和width。這個參考下面的圖很容易理解,小box的橫軸值較小,發生偏移時,反應到y軸上相比大box要大。 -
一個網格預測多個box,希望的是每個box predictor專門負責預測某個object。具體做法就是看當前預測的box與ground truth box中哪個IoU大,就負責哪個。這種做法稱作box predictor的specialization。
- 最後整個的損失函數如下所示:
這個損失函數中:- 只有當某個網格中有object的時候纔對classification error進行懲罰。
- 只有當某個box predictor對某個ground truth box負責的時候,纔會對box的coordinate error進行懲罰,而對哪個ground truth box負責就看其預測值和ground truth box的IoU是不是在那個cell的所有box中最大。
- 其他細節,例如使用激活函數使用leak RELU,模型用ImageNet預訓練等等。
損失函數設計:
損失函數的設計目標就是讓座標(x,y,w,h),confidence,classification 這個三個方面達到很好的平衡。簡單的全部採用了sum-squared error loss來做這件事會有以下不足: a) 8維的localization error和20維的classification error同等重要顯然是不合理的; b) 如果一個網格中沒有object(一幅圖中這種網格很多),那麼就會將這些網格中的box的confidence push到0,相比於較少的有object的網格,這種做法是overpowering的,這會導致網絡不穩定甚至發散。 解決方案如下:
- 更重視8維的座標預測,給這些損失前面賦予更大的loss weight, 記爲 ,在pascal VOC訓練中取5。(上圖藍色框)
- 對沒有object的bbox的confidence loss,賦予小的loss weight,記爲 ,在pascal VOC訓練中取0.5。(上圖橙色框)
- 有object的bbox的confidence loss (上圖紅色框) 和類別的loss (上圖紫色框)的loss weight正常取1。
-
對不同大小的bbox預測中,相比於大bbox預測偏一點,小box預測偏一點更不能忍受。而sum-square error loss中對同樣的偏移loss是一樣。 爲了緩和這個問題,作者用了一個比較取巧的辦法,就是將box的width和height取平方根代替原本的height和width。 如下圖:small bbox的橫軸值較小,發生偏移時,反應到y軸上的loss(下圖綠色)比big box(下圖紅色)要大。
-
一個網格預測多個bounding box,在訓練時我們希望每個object(ground true box)只有一個bounding box專門負責(一個object 一個bbox)。具體做法是與ground true box(object)的IOU最大的bounding box 負責該ground true box(object)的預測。這種做法稱作bounding box predictor的specialization(專職化)。每個預測器會對特定(sizes,aspect ratio or classed of object)的ground true box預測的越來越好。(個人理解:IOU最大者偏移會更少一些,可以更快速的學習到正確位置)
大致流程:
- Resize成448*448,圖片分割得到7*7網格(cell)
- CNN提取特徵和預測:卷積不忿負責提特徵。全鏈接部分負責預測:a) 7*7*2=98個bounding box(bbox) 的座標 和是否有物體的confidence 。 b) 7*7=49個cell所屬20個物體的概率。
- 過濾bbox(通過nms)
訓練:
預訓練分類網絡: 在 ImageNet 1000-class competition dataset上預訓練一個分類網絡,這個網絡是Figure3中的前20個卷機網絡+average-pooling layer+ fully connected layer (此時網絡輸入是224*224)。
訓練檢測網絡:轉換模型去執行檢測任務,《Object detection networks on convolutional feature maps》提到說在預訓練網絡中增加捲積和全鏈接層可以改善性能。在他們例子基礎上添加4個卷積層和2個全鏈接層,隨機初始化權重。檢測要求細粒度的視覺信息,所以把網絡輸入也又224*224變成448*448。見Figure3。
- 一幅圖片分成7x7個網格(grid cell),某個物體的中心落在這個網格中此網格就負責預測這個物體。
-
最後一層輸出爲 (7*7)*30的維度。每個 1*1*30的維度對應原圖7*7個cell中的一個,1*1*30中含有類別預測和bbox座標預測。總得來講就是讓網格負責類別信息,bounding box主要負責座標信息(部分負責類別信息:confidence也算類別信息)。具體如下:
- 每個網格(1*1*30維度對應原圖中的cell)要預測2個bounding box (圖中黃色實線框)的座標(,w,h) ,其中:中心座標的 相對於對應的網格歸一化到0-1之間,w,h用圖像的width和height歸一化到0-1之間。 每個bounding box除了要回歸自身的位置之外,還要附帶預測一個confidence值。 這個confidence代表了所預測的box中含有object的置信度和這個box預測的有多準兩重信息:confidence = 。其中如果有ground true box(人工標記的物體)落在一個grid cell裏,第一項取1,否則取0。 第二項是預測的bounding box和實際的ground truth box之間的IOU值。即:每個bounding box要預測 ,共5個值 ,2個bounding box共10個值,對應 1*1*30維度特徵中的前10個。
-
- 每個網格還要預測類別信息,論文中有20類。7x7的網格,每個網格要預測2個 bounding box 和 20個類別概率,輸出就是 7x7x(5x2 + 20) 。 (通用公式: SxS個網格,每個網格要預測B個bounding box還要預測C個categories,輸出就是S x S x (5*B+C)的一個tensor。 注意:class信息是針對每個網格的,confidence信息是針對每個bounding box的)
測試:
Test的時候,每個網格預測的class信息( )和bounding box預測的confidence信息( ) 相乘,就得到每個bounding box的class-specific confidence score。
-
- 等式左邊第一項就是每個網格預測的類別信息,第二三項就是每個bounding box預測的confidence。這個乘積即encode了預測的box屬於某一類的概率,也有該box準確度的信息。
- 對每一個網格的每一個bbox執行同樣操作: 7x7x2 = 98 bbox (每個bbox既有對應的class信息又有座標信息)
- 得到每個bbox的class-specific confidence score以後,設置閾值,濾掉得分低的boxes,對保留的boxes進行NMS處理,就得到最終的檢測結果。
4.YOLO的缺點
-
YOLO對相互靠的很近的物體,還有很小的羣體 檢測效果不好,這是因爲一個網格中只預測了兩個框,並且只屬於一類。
-
對測試圖像中,同一類物體出現的新的不常見的長寬比和其他情況是。泛化能力偏弱。
-
由於損失函數的問題,定位誤差是影響檢測效果的主要原因。尤其是大小物體的處理上,還有待加強。