1. 程式人生 > >這可能是最詳細的目標檢測YOLO_v1的解釋

這可能是最詳細的目標檢測YOLO_v1的解釋

YOLO 是 2016 年提出來的目標檢測演算法,在當時比較優秀的目標檢測演算法有 R-CNN、Fast R-CNN 等等,但 YOLO 演算法還是讓人感到很新奇與興奮。

YOLO 是 You only look once 幾個單詞的縮寫,大意是你看一次就可以預測了,靈感就來自於我們人類自己,因為人看一張圖片時,掃一眼就可以得知這張圖片不同型別目標的位置。

1.創新

YOLO將物體檢測作為迴歸問題求解。基於一個單獨的end-to-end網路,完成從原始影象的輸入到物體位置和類別的輸出。從網路設計上,YOLO與rcnn、fast rcnn及faster rcnn的區別如下:

[1]
YOLO訓練和檢測均是在一個單獨網路中進行。YOLO沒有顯示地求取region proposal的過程。而rcnn/fast rcnn 採用分離的模組(獨立於網路之外的selective search方法)求取候選框(可能會包含物體的矩形區域),訓練過程因此也是分成多個模組進行。Faster rcnn使用RPN(region proposal network)卷積網路替代rcnn/fast rcnn的selective
search模組,將RPN整合到fast rcnn檢測網路中,得到一個統一的檢測網路。儘管RPN與fast rcnn共享卷積層,但是在模型訓練過程中,需要反覆訓練RPN網路和fast rcnn網路(注意這兩個網路核心卷積層是引數共享的)。
[2]


YOLO將物體檢測作為一個迴歸問題進行求解,輸入影象經過一次inference,便能得到影象中所有物體的位置和其所屬類別及相應的置信概率。而rcnn/fast rcnn/faster rcnn將檢測結果分為兩部分求解:物體類別(分類問題),物體位置即bounding box(迴歸問題)。
在這裡插入圖片描述

2.設計理念

整體來看,Yolo演算法採用一個單獨的CNN模型實現end-to-end的目標檢測,整個系統如下圖所示:首先將輸入圖片resize到448x448,然後送入CNN網路,最後處理網路預測結果得到檢測的目標。相比R-CNN演算法,其是一個統一的框架,其速度更快,而且Yolo的訓練過程也是end-to-end的。
在這裡插入圖片描述

YOLO將輸入影象分成SxS個格子,每個格子負責檢測‘落入’該格子的物體。若某個物體的中心位置的座標落入到某個格子,那麼這個格子就負責檢測出這個物體。如下圖所示,圖中物體狗的中心點(紅色原點)落入第5行、第2列的格子內,所以這個格子負責預測影象中的物體狗。
在這裡插入圖片描述
每個格子輸出B個bounding box(包含物體的矩形區域)資訊,以及C個物體屬於某種類別的概率資訊。

Bounding box資訊包含5個數據值,分別是x,y,w,h,和confidence。其中x,y是指當前格子預測得到的物體的bounding box的中心位置的座標。w,h是bounding box的寬度和高度。注意:實際訓練過程中,w和h的值使用影象的寬度和高度進行歸一化到[0,1]區間內;x,y是bounding box中心位置相對於當前格子位置的偏移值,並且被歸一化到[0,1]。

confidence反映當前bounding box是否包含物體以及物體位置的準確性,計算方式如下:在這裡插入圖片描述
若bounding box包含物體,則P(object) = 1;否則P(object) = 0. IOU(intersection over union)為預測boundingbox與物體真實區域的交集面積(以畫素為單位,用真實區域的像素面積歸一化到[0,1]區間)。

因此,YOLO網路最終的全連線層的輸出維度是 S * S * (B * 5 + C)。YOLO論文中,作者訓練採用的輸入影象解析度是448x448,S=7,B=2;採用VOC 20類標註物體作為訓練資料,C=20。因此輸出向量為7 * 7 * (20 + 2 * 5)=1470維。作者開源出的YOLO程式碼中,全連線層輸出特徵向量各維度對應內容如下:
在這裡插入圖片描述

注:

  • 由於輸出層為全連線層,因此在檢測時,YOLO訓練模型只支援與訓練影象相同的輸入解析度。

  • 雖然每個格子可以預測B個bounding box,但是最終只選擇只選擇IOU最高的bounding box作為物體檢測輸出,即每個格子最多隻預測出一個物體。當物體佔畫面比例較小,如影象中包含畜群或鳥群時,每個格子包含多個物體,但卻只能檢測出其中一個。這是YOLO方法的一個缺陷。

總結一下,每個單元格需要預測大小的張量。在下面的網路結構中我們會詳細講述每個單元格的預測值的分佈位置。
在這裡插入圖片描述

3.網路設計

YOLO檢測網路包括24個卷積層和2個全連線層,如下圖所示。
在這裡插入圖片描述
YOLO網路借鑑了GoogLeNet分類網路結構。不同的是,YOLO未使用inception
module,而是使用1x1卷積層(此處1x1卷積層的存在是為了跨通道資訊整合)+3x3卷積層簡單替代。

YOLO論文中,作者還給出一個更輕快的檢測網路fast YOLO,它只有9個卷積層和2個全連線層。使用titan x GPU,fast YOLO可以達到155fps的檢測速度,但是mAP值也從YOLO的63.4%降到了52.7%,但卻仍然遠高於以往的實時物體檢測方法(DPM)的mAP值。

可以看到網路的最後輸出為是邊界框的預測結果。這樣,提取每個部分是非常方便的,這會方面後面的訓練及預測時的計算。
在這裡插入圖片描述

在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處理,就得到最終的檢測結果。

4.Loss函式定義

YOLO使用均方和誤差作為loss函式來優化模型引數,即網路輸出的S * S * (B * 5 + C)維向量與真實影象的對應S * S * (B * 5 + C)維向量的均方和誤差。如下式所示。其中,coordError、iouError和classError分別代表預測資料與標定資料之間的座標誤差、IOU誤差和分類誤差。

在這裡插入圖片描述
這種做法存在以下幾個問題:
因為每個grid有30維,這30維中,8維是迴歸box的座標,2維是box的confidence,還有20維是類別。其中座標的x,y用對應網格的offset歸一化到0-1之間,w,h用影象的width和height歸一化到0-1之間。從而有以下問題:
第一,8維的localization error和20維的classification error同等重要顯然是不合理的;
第二,如果一個網格中沒有object(一幅圖中這種網格很多),那麼就會將這些網格中的box的confidence push到0,相比於較少的有object的網格,這種做法是overpowering的,這會導致網路不穩定甚至發散。

解決辦法:
YOLO對上式loss的計算進行了如下修正。

[1] 位置相關誤差(座標、IOU)與分類誤差對網路loss的貢獻值是不同的,因此YOLO在計算loss時,使用 λ c o o r d = 5 \lambda _{coord} =5 修正coordError。

[2] 在計算IOU誤差時,包含物體的格子與不包含物體的格子,二者的IOU誤差對網路loss的貢獻值是不同的。若採用相同的權值,那麼不包含物體的格子的confidence值近似為0,變相放大了包含物體的格子的confidence誤差在計算網路引數梯度時的影響。為解決這個問題,YOLO 使用 λ n o o b j = 0.5 \lambda _{noobj} =0.5 修正iouError。(注此處的‘包含’是指存在一個物體,它的中心座標落入到格子內)。

[3] 對於相等的誤差值,大物體誤差對檢測的影響應小於小物體誤差對檢測的影響。這是因為,相同的位置偏差佔大物體的比例遠小於同等偏差佔小物體的比例。YOLO將物體大小的資訊項(w和h)進行求平方根來改進這個問題。(注:這個方法並不能完全解決這個問題)。

綜上,YOLO在訓練過程中Loss計算如下式所示:
在這裡插入圖片描述
其中,在這裡插入圖片描述為網路預測值,在這裡插入圖片描述帽 為標註值。 Π i o b j \Pi _{i}^{obj} (這裡這個符號其實是空心的1)表示物體落入格子i中, Π i j o b j \Pi _{ij}^{obj} Π i j n o o b j \Pi _{ij}^{noobj} 分別表示物體落入與未落入格子i的第j個bounding box內。

注:

  • YOLO方法模型訓練依賴於物體識別標註資料,因此,對於非常規的物體形狀或比例,YOLO的檢測效果並不理想。
  • YOLO採用了多個下采樣層,網路學到的物體特徵並不精細,因此也會影響檢測效果。
  • YOLO loss函式中,大物體IOU誤差和小物體IOU誤差對網路訓練中loss貢獻值接近(雖然採用求平方根方式,但沒有根本解決問題)。因此,對於小物體,小的IOU誤差也會對網路優化過程造成很大的影響,從而降低了物體檢測的定位準確性。

5.網路訓練

在訓練之前,先在ImageNet上進行了預訓練,其預訓練的分類模型採用之前圖中前20個卷積層,然後新增一個average-pool層和全連線層。預訓練之後,在預訓練得到的20層卷積層之上加上隨機初始化的4個卷積層和2個全連線層。由於檢測任務一般需要更高清的圖片,所以將網路的輸入從224x224增加到了448x448。整個網路的流程如下圖所示:
在這裡插入圖片描述

我們再來詳細回顧下具體的訓練流程

一幅圖片分成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 (圖中黃色實線框)的座標 x c e n t e r , y c e n t e r , w , h (x_{center},y_{center},w,h) ,其中:中心座標的 x c e n t e r , y c e n t e r x_{center},y_{center} 相對於對應的網格歸一化到0-1之間,w,h用影象的width和height歸一化到0-1之間。 每個bounding box除了要回歸自身的位置之外,還要附帶預測一個confidence值。 這個confidence代表了所預測的box中含有object的置信度和這個box預測的有多準兩重資訊: c o n f i d e n c e = P r ( O b j e c t ) I O U p r e d t r u t h confidence = Pr(Object) \ast IOU^{truth}_{pred} 。其中如果有ground true box(人工標記的物體)落在一個grid cell裡,第一項取1,否則取0。 第二項是預測的bounding box和實際的ground truth box之間的IOU值。即:每個bounding box要預測 x c e n t e r , y c e n t e r , w , h , c o n f i d e n c e x_{center},y_{center},w,h,confidence 共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的)
    -在這裡插入圖片描述

6.網路測試與預測

Test的時候,每個網格預測的class資訊 ( P r ( C l a s s i O b j e c t ) ) ( Pr(Class_i | Object) ) 和bounding box預測的confidence資訊 ( P r ( O b j e c t ) I O U p r e d t r u t h ) ( Pr(Object) \ast IOU^{truth}_{pred} ) 相乘,就得到每個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處理,就得到最終的檢測結果。

這裡先介紹一下非極大值抑制演算法(non maximum suppression, NMS),這個演算法不單單是針對Yolo演算法的,而是所有的檢測演算法中都會用到。NMS演算法主要解決的是一個目標被多次檢測的問題,如圖中人臉檢測,可以看到人臉被多次檢測,但是其實我們希望最後僅僅輸出其中一個最好的預測框,比如對於美女,只想要紅色那個檢測結果。那麼可以採用NMS演算法來實現這樣的效果:首先從所有的檢測框中找到置信度最大的那個框,然後挨個計算其與剩餘框的IOU,如果其值大於一定閾值(重合度過高),那麼就將該框剔除;然後對剩餘的檢測框重複上述過程,直到處理完所有的檢測框。Yolo預測過程也需要用到NMS演算法。
在這裡插入圖片描述
下面就來分析Yolo的預測過程,這裡我們不考慮batch,認為只是預測一張輸入圖片。根據前面的分析,最終的網路輸出是個邊界框。

所有的準備資料已經得到了,那麼我們先說第一種策略來得到檢測框的結果,我認為這是最正常與自然的處理。首先,對於每個預測框根據類別置信度選取置信度最大的那個類別作為其預測標籤,經過這層處理我們得到各個預測框的預測類別及對應的置信度值,其大小都是。一般情況下,會設定置信度閾值,就是將置信度小於該閾值的box過濾掉,所以經過這層處理,剩餘的是置信度比較高的預測框。最後再對這些預測框使用NMS演算法,最後留下來的就是檢測結果。一個值得注意的點是NMS是對所有預測框一視同仁,還是區分每個類別,分別使用NMS。Ng在deeplearning.ai中講應該區分每個類別分別使用NMS,但是看了很多實現,其實還是同等對待所有的框,我覺得可能是不同類別的目標出現在相同位置這種概率很低吧。

上面的預測方法應該非常簡單明瞭,但是對於Yolo演算法,其卻採用了另外一個不同的處理思路(至少從C原始碼看是這樣的),其區別就是先使用NMS,然後再確定各個box的類別。其基本過程如圖所示。對於98個boxes,首先將小於置信度閾值的值歸0,然後分類別地對置信度值採用NMS,這裡NMS處理結果不是剔除,而是將其置信度值歸為0。最後才是確定各個box的類別,當其置信度值不為0時才做出檢測結果輸出。這個策略不是很直接,但是貌似Yolo原始碼就是這樣做的。Yolo論文裡面說NMS演算法對Yolo的效能是影響很大的,所以可能這種策略對Yolo更好。測試了普通的圖片檢測,兩種策略結果是一樣的。

YOLO預處理流程

7.YOLOv1的缺點

YOLO對相互靠的很近的物體,還有很小的群體檢測效果不好,這是因為一個網格中只預測了兩個框,並且只屬於一類。

對測試影象中,同一類物體出現的新的不常見的長寬比和其他情況是。泛化能力偏弱。

由於損失函式的問題,定位誤差是影響檢測效果的主要原因。尤其是大小物體的處理上,還有待加強。

於是,便有了後來的YOLO_v2…

參考:https://blog.csdn.net/c20081052/article/details/80236015
https://blog.csdn.net/m0_37192554/article/details/81092514