前段時間看了YOLO的論文,打算用YOLO模型做一個遷移學習,看看能不能用於項目中去。但在實踐過程中感覺到對於YOLO的一些細節和技巧還是沒有很好的理解,現學習其他人的博客總結(所有參考連接都附於最后一部分“參考資料”),加入自己的理解,整理此學習筆記。
概念補充:mAP:mAP是目標檢測算法中衡量算法精確度的一個指標,其涉及到查准率(Precision)和查全率(Recall)。對於目標檢測任務,對於每一個目標可以計算出其查准率和查全率,多次實驗進行統計,可以得到每個類有一條P-R曲線,曲線下面的面積即是AP的值,m的意思是對每一個類的AP值求平均,即mAP的定義,mAP的大小在[0, 1]區間內。
0 - 背景
過去的目標檢測算法很多的思路是通過算法(經典的如region proposal)產生大量的可能包含目標物體的邊界框(potential bounding box),然后用分類器去判斷每一個邊界框里面是否包含物體,以及包含物體的類別以及置信度(confidence),經典的模型由R-CNN以及其多個變種。但正如YOLO論文中反復提及的,這種做法一方面會使得訓練變得麻煩(因為整個模型由多個部分組成,而每一部分通常都需要獨立訓練),不僅費時,也很難綜合幾部分結果求得最好的整體結果,另一方面,多個部分的協同使得整個模型的效率較為低下。
一直以來,計算機視覺對於檢測兩個距離很近的同類目標或者不同目標都具有很大的挑戰。很多算法會對輸入的圖像進行尺寸的放縮,而如果當圖像中由兩個目標相近的時候,加上縮小尺寸,這使得對於相近目標的檢測變得很困難。對於這種情況(特別是小目標檢測,如鳥群),YOLO v3做得很好。
1 - 與其他算法的比較
YOLO不同於上述的目標檢測算法,它將目標檢測抽象為一個回歸問題(regression problem),直接使用一個神經網絡,輸入為原始圖片,輸出為邊界框坐標、目標類別、目標置信度等,YOLO將其他模型分開的部分都綜合到一個神經網絡中,使得訓練能夠采用端到端(end-to-end)來優化。同時,這種改進不僅使得訓練變得容易,也使得檢測速度很快。並且,論文中提到,YOLO遷移到其他數據集(如藝術圖像)上的表現遠好於其他目標檢測算法,這表明了YOLO較其他模型學習了較好的抽象特征,泛化能力更強。
但YOLO也有缺點,其在物體定位時容易出錯,不過在誤將在背景檢測出本不存在的物品的情況相對少一些。
不同算法的檢測流程對比如下(圖來自於博客:https://blog.csdn.net/hrsstudy):
綜上,將YOLO的優點總結如下:
- 檢測快速
- 不同於其他檢測算法,YOLO的模型只由一個神經網路構成,原始圖像和最終結果是模型的輸入和輸出。論文中提到,YOLO在Titan X的GPU上能達到45 FPS,其快速版本Fast YOLO能達到155 FPS
- 減少背景錯誤(將背景識別成本不存在的物體)
- 其他檢測算法,采用的諸如滑動窗口或者region proposal產生預選邊界框,一定程度忽略了全局信息(上下文信息),而過多關注了局部信息。而YOLO采用整張圖片進行輸入,很好的利用了檢測目標的上下文信息(環境信息),從而有效避免了背景錯誤(值得一提的是,YOLO的背景錯誤不到Fast R-CNN的一半)
- 較好的學習了目標的泛化特征
- YOLO對於其他數據集的遷移學習能力較強,這說明其學到了目標的泛化特征,提高了泛化能力。我的理解是,相比其他算法,YOLO用一個神經網絡代替了復雜的多部分綜合,從而減少了人工干預,使得模型能學習到更加好的參數,從而提高了效果
以上總結了YOLO的優點,下面總結其缺點:
- YOLO的目標檢測精度低於R-CNN為代表的其他state-of-the-art的物體檢測算法
- YOLO的定位錯誤相比其他算法較為嚴重
- YOLO對小物體的檢測效果也不佳,這是因為划定網絡單元的時候限制了其每一個單元最多打的邊界框數量,因此網格單元的數量以及每個單元的邊界框數量都成了額外影響結果的參數
下面是各個目標檢測算法的性能對比(圖來自於博客:https://blog.csdn.net/hrsstudy):
2 - 相關計算
2.1 - 網格單元置信度計算
如果該網格單元存在目標,則計算公式為:$confidence=Pr(Object)\times IOU_{pred}^{truth}$,否則其$confidence$應為0。
2.2 - 邊界框目標類別置信度計算
注意到,$confidence$是針對每一個邊界框(有沒有目標),而$conditional\ class\ probabilities$是對整個網格單元的。因此可以通過如下公式計算每一個邊界框對於每一個具體類別的置信度。
$$Pr(Class_i|Object)\times Pr(Object)\times IOU_{pred}^{truth}=Pr(Class_i)\times IOU_{pred}^{truth}$$
2.3 - 輸出張量計算
YOLO將圖像分成$S \times S$個網格單元,每一個網格單元最后輸出$B$個邊界框(每個邊界框包括$x,y,w,h,confidence$,$x,y$表示預測的邊界框中心與網格單元邊界的相對值,$w,h$表示預測的邊界框的寬和高相對於整幅圖像的$width,height$的比例值,$confidence$表示預測的邊界框與真實的邊界框的$IOU$的值),以及$C$個類別的概率($Pr(Class|Object)$,即如果一個網格單元包含目標的前提下,其屬於某個類別的概率,對於一個網格單元只預測一組類的概率,而不考慮邊界框$B$的數量)。因此,最后輸出的張量維度為$S \times S \times (B \times 5 + C)$。
2.4 - 損失函數計算
損失函數需要設計得讓目標的$(x,y,w,h),confidence,classification$這三個衡量部分達到很好平衡,則需要注意到:
- 坐標是8維的,類別概率是20維的,它們在衡量中不能以同等重要的權重
- 如果網絡單元中沒有目標,則這些單元的邊界框的置信度要為0,而往往圖中這種單元很多,這將使得它們對於梯度的貢獻可能遠大於那些有目標的單元,這將導致網絡不穩定而發散
因此,解決方法如下:
- 相比於20維的類別概率,8維的坐標預測需要得到重視,因此給其分配更大的損失權重$\lambda_{coord}$,在pascal VOC訓練中取5(下圖藍色框)
- 對於沒有目標的網絡單元,其損失權重$\lambda_{noobj}$需要小一點,在pascal VOC訓練中取0.5(下圖黃色框)
- 其他的損失權重:有目標的邊界框的置信度損失權重(下圖紫色框)以及類別概率的損失權重均取1(下圖紅色框)
下圖為損失函數理解(圖來自於博客:https://blog.csdn.net/hrsstudy):
注意到,上面的損失函數對於$w,h$的損失計算是先取了開方再平方的,這是因為對於不同的小的邊界框預測中,相同的偏差影響程度不同(小偏差對於小邊界框的影響更大,因此需要更嚴重的懲罰),基於此,作者想到了這個巧妙的方法,其原理可以由下圖直觀理解(圖來自於博客:https://blog.csdn.net/hrsstudy):
參考資料
https://www.imooc.com/article/36391