1. 程式人生 > >yolo演算法詳解

yolo演算法詳解

相關內容:

目標檢測:目標檢測是一件比較實際的且具有挑戰性的計算機視覺任務,其可以看成影象分類與定位的結合,給定一張圖片,目標檢測系統要能夠識別出圖片的目標並給出其位置,由於圖片中目標數是不定的,且要給出目標的精確位置,目標檢測相比分類任務更復雜。

上圖是語義分割,定位,檢測和例項分割的例子

定位是是識別出一個目標的類別並預測出位置,檢測是識別出多個目標的類別並預測出位置。

目標檢測比較流行的演算法可以分為兩類:第一類是基於Region Proposal的R-CNN系演算法(R-CNN,Fast R-CNN, Faster R-CNN),它們是two-stage的,需要先使用啟發式方法(selective search)或者CNN網路(RPN)產生Region Proposal,然後再在Region Proposal上做分類(rcnn)或者分類與邊框迴歸(fast rcnn,faster rcnn?)

。第二類是Yolo,SSD這類one-stage演算法,其僅僅使用一個CNN網路直接預測不同目標的類別與位置。第一類方法是準確度高一些,但是速度慢,但是第二類演算法是速度快,但是準確性要低一些。

滑動視窗

採用滑動視窗的目標檢測演算法思路非常簡單,它將檢測問題轉化為了影象分類問題。其基本原理就是採用不同大小和比例(寬高比)的視窗在整張圖片上以一定的步長進行滑動,然後對這些視窗對應的區域做影象分類,這樣就可以實現對整張圖片的檢測了。如DPM就是採用這種思路。但是這個方法有致命的缺點,就是你並不知道要檢測的目標大小是什麼規模,所以你要設定不同大小和比例的視窗去滑動,而且還要選取合適的步長。但是這樣會產生很多的子區域,並且都要經過分類器去做預測,這需要很大的計算量,所以你的分類器不能太複雜,因為要保證速度。解決思路之一就是減少要分類的子區域,這就是R-CNN的一個改進策略,其採用了selective search方法來找到最有可能包含目標的子區域(Region Proposal),其實可以看成採用啟發式方法過濾掉很多子區域,這會提升效率。

非極大值抑制演算法(non maximum suppression, NMS),這個演算法不單單是針對Yolo演算法的,而是所有的檢測演算法中都會用到。NMS演算法主要解決的是一個目標被多次檢測的問題。流程是:首先從所有的檢測框中找到置信度最大的那個框,然後挨個計算其與剩餘框的IOU,如果其值大於一定閾值(重合度過高),那麼就將該框剔除;然後對剩餘的檢測框重複上述過程,直到處理完所有的檢測框。Yolo預測過程也需要用到NMS演算法。

yolo演算法

可以認為特徵圖的每個元素也是對應原始圖片的一個小方塊,然後用每個元素來可以預測那些 中心點在該小方格內的目標,這就是Yolo演算法的樸素思想。

具體來說,Yolo的CNN網路將輸入的圖片(本文的大小是resize成448*448)分割成S×S(本文取的是7*7)網格,然後每個網格負責去檢測那些中心點落在該網格內的目標,如圖6所示,可以看到狗這個目標的中心落在左下角一個單元格內,那麼該單元格負責預測這個狗。每個網格會預測B(本文取B=2)個邊界框和C(本文使用VOC資料集,所以C=20?)個條件類別概率Pr(當網格包含目標時,Pr=1,否則Pr=0),其表徵的是由該網格負責預測的邊界框其目標屬於各個類別的概率,但是這些概率值其實是在各個邊界框置信度下的條件概率,即Pr(classi|object),不管一個單元格預測多少個邊界框,其只預測一組類別概率值,這是Yolo演算法的一個缺點,在後來的改進版本中,Yolo9000是把類別概率預測值與邊界框是繫結在一起的。而每個邊界框包含(x,y,w,h,S),S是置信度,S=Pr*IOU,所以S實際上只有兩種取值,0或者IOU本身。中心座標的預測值(x,y)是相對於每個單元格左上角座標點的偏移值,並且單位是相對於單元格大小的(相當於歸一化,所以這裡都是介於0--1之間的?),而邊界框的w和h預測值是相對於整個圖片的寬與高的比例,這樣理論上4個元素的大小應該在[0,1]範圍(即x,y是邊框相對於網格的位置,而w,h是相對於整張圖片而言的)。每個單元格需要預測(B∗5+C)個值。如果將輸入圖片劃分為S×S網格,那麼最終預測值為S×S×(B∗5+C)大小的張量。

Yolo演算法將目標檢測看成迴歸問題,所以採用的是均方差損失函式。並且對不同的部分採用了不同的權重值。

下面這段話寫的要看懂

下面是訓練損失函式的分析,Yolo演算法將目標檢測看成迴歸問題,所以採用的是均方差損失函式。但是對不同的部分採用了不同的權重值。首先區分定位誤差和分類誤差。對於定位誤差,即邊界框座標預測誤差,採用較大的權重λcoord=5。然後其區分不包含目標的邊界框與含有目標的邊界框的置信度,對於前者,採用較小的權重值λnoobj=0.5。其它權重值均設為1。然後採用均方誤差,其同等對待大小不同的邊界框,但是實際上較小的邊界框的座標誤差應該要比較大的邊界框要更敏感。為了保證這一點,將網路的邊界框的寬與高預測改為對其平方根的預測,即預測值變為(x,y,w‾‾√,h‾√)。
另外一點時,由於每個單元格預測多個邊界框。但是其對應類別只有一個。那麼在訓練時,如果該單元格內確實存在目標,那麼只選擇與ground truth的IOU最大的那個邊界框來負責預測該目標,而其它邊界框認為不存在目標。這樣設定的一個結果將會使一個單元格對應的邊界框更加專業化,其可以分別適用不同大小,不同高寬比的目標,從而提升模型效能。大家可能會想如果一個單元格記憶體在多個目標怎麼辦,其實這時候Yolo演算法就只能選擇其中一個來訓練,這也是Yolo演算法的缺點之一。要注意的一點時,對於不存在對應目標的邊界框,其誤差項就是隻有置信度,左標項誤差是沒法計算的。而只有當一個單元格內確實存在目標時,才計算分類誤差項,否則該項也是無法計算的。

Yolo的優缺點。首先是優點,Yolo採用一個CNN網路來實現檢測,是單管道策略,其訓練與預測都是end-to-end,所以Yolo演算法比較簡潔且速度快。第二點由於Yolo是對整張圖片做卷積,所以其在檢測目標有更大的視野,它不容易對背景誤判。其實我覺得全連線層也是對這個有貢獻的,因為全連線起到了attention的作用。另外,Yolo的泛化能力強,在做遷移時,模型魯棒性高。

Yolo的缺點,首先Yolo各個單元格僅僅預測兩個邊界框,而且屬於一個類別。對於小物體,Yolo的表現會不如人意。這方面的改進可以看SSD,其採用多尺度單元格。也可以看Faster R-CNN,其採用了anchor boxes。Yolo對於在物體的寬高比方面泛化率低,就是無法定位不尋常比例的物體。當然Yolo的定位不準確也是很大的問題。