前面介紹的R-CNN系的目標檢測采用的思路是:首先在圖像上提取一系列的候選區域,然后將候選區域輸入到網絡中修正候選區域的邊框以定位目標,對候選區域進行分類以識別。雖然,在Faster R-CNN中利用RPN網絡將候選區域的提取以放到了CNN中,實現了end-to-end的訓練,但是其本質上仍然是提取先提取候選區域,然后對候選區域識別,修正候選區域的邊框位置。這稱為tow-stage的方法,雖然在精度已經很高了,但是其速度卻不是很好。造成速度不好的主要原因就是候選區域的提取,這就需要一種網絡能夠直接預測出圖像中目標的位置,中間不需要候選區域的計算,這就是one-stage。
YOLO系就是one-stage目標檢測的一種,其全名You only look once很形象,只需要將圖片輸入到網絡中就預測中其中目標的bounding box以及bounding box所屬的類別。相比R-CNN,YOLO損失了一定的精度,但是其有點就是速度快。
YOLO V1
YOLO V1將目標檢測定義為一個回歸問題,從圖像像素信息直接得到目標的邊框以及所屬類別的概率,其有以下的優點:
- 快。其整個網絡結構就是解決回歸問題,很快。
- 在做predict的時候,使用的一整張圖像的全局信息。two-stage的方法,每次只是“看到”圖像的一塊區域,YOLO 一次“看”一整張圖像,所以它可以將目標整個的外觀信息以及類別進行編碼,目前最快最好的Fast R-CNN,較容易誤將圖像中的 background patches (背景的一個小塊)看成是物體,因為它看的范圍比較小。YOLO 的 background errors(背景錯誤) 比 Fast R-CNN 少一半多。
- YOLO得到的目標的特征表示更容易泛化
YOLO 和R-CNN性能的對比
YOLO的也有一定的缺點,其准確度落后於Faster R-CNN,並且由於其使用比較粗糙的網格來划分原圖,導致其對小目標的檢測效果不是很好。
主要思路
相對於R-CNN系首先從原圖中計算出一系列的候選區域,YOLO則使用簡單的方法,首先將圖像划分為\(S\times S\)(論文中\(S = 7\))的網格,如果某個目標的中心位於一個grid cell中,則該grid cell就負責檢測這個目標。
在YOLO網絡中,目標的坐標信息是通過相對於某個grid cell左上角的偏移來表示的,目標的寬和高是用原圖的寬和高占比表示的。 這就是這里為什么會說,如果某個目標的中心位於一個grid cell中,則該grid cell就負責檢測這個目標,在做邊框回歸的時候,其GT就是該grid cell。
上面提到如果某個目標的中心位於一個grid cell中,則該grid cell就負責檢測這個目標,也就是說在YOLO中,grid cell設計為可以代表目標,在網絡中也是針對grid cell進行處理的。 在每個grid cell中預測出來\(B\)(\(B = 2\)個bounding box,而且要為每個預測出來的bounding box打個分數,來表示該bounding box是否包含目標以及該bbox作為目標邊框的可信度,這個分數稱為Confidence。Confidence 的定義如下:
其中,\(Pr(object)\)為bbox包含目標的概率(bbox存在目標則$Pr(object) =1 \(,不存在目標則\)Pr(object) = 0\(;\)IoU_{pred}^{truth}$表示預測出來的bbox和Ground Truth之間的IoU。 也就是說,如果bbox不含目標則其confidence = 0,包含目標的話Confidence就是bbox和Ground Truth之間的IoU。
這樣,通過每個grid cell預測出來的bbox可由一個五元組表示\((x,y,w,h,Confidence)\),其中\((x,y)\)表示bbox的中心相對該grid cell左上角的偏移量,使用grid cell的長寬為比例,將其值歸一化到\([0,1]\)之間;\((w,h)\)為bbox的寬度和長度,以圖像的寬度和長度歸一化到\([0,1]\)之間;\(C\)就是上面提到的Confidence,其值也是在\([0,1]\)之間。 這樣每個bbox可以使用五元組\((x,y,w,h,Confidence)\)表示,並且其值都是在\([0,1]\)之間。
以grid cell為准預測出來的bbox表示了目標的邊框信息,並不能判斷出來其中包含的目標是屬於哪一個類。所以YOLO網絡還為每一個grid cell預測出\(C\)個conditional class probability(條件類別概率):
即在一個grid cell中有一個Object的前提下,它屬於某個類的概率。只為每個grid cell預測一組類概率,而不考慮框的數量。
類別概率\(P(class_i | object)\)是對於某個grid cell的,表示該grid cell能夠預測一個目標的條件下,其目標的屬於某個類的概率;而bbox的confidence表示的是,包含目標的可行性。 將這兩個值相乘,就可以得到bbox中包含的目標的的類別的概率了。
所以在測試階段,將grid cell的\(P(class_i | object)\)和以該grid cell為准預測出來bbox的confidence相乘
該值就能反應出bbox包含某一個具體類別的目標的可信度。
在YOLO論文中,使用VOC的數據集,即有20個類別,將圖像划分為\(7 \times 7\)的網格,每個grid cell預測出2個bbox,因此最終輸出的數據張量尺寸為\(7 \times 7 \times 30\)。(\(S \times S \times (B \times 5 + C)\))。
上圖表示了YOLO網絡針對某個grid cell的輸出。
- 由於YOLO的最后輸出層是全連接層,所以只能處理固定尺寸的圖像\(448 \times 448 \times 3\)
- 雖然每個格子可以預測B個bounding box,但是最終只選擇只選擇IOU最高的bounding box作為物體檢測輸出,即每個格子最多只預測出一個物體。當物體占畫面比例較小,如圖像中包含畜群或鳥群時,每個grid
cell 負責多個物體,但卻只能檢測出其中一個。這是YOLO方法的一個缺陷
網絡結構
YOLO使用CNN來提取圖像的特征,最后使用全連接層做回歸預測,並且借鑒GooLeNet的思路,使用了\(1 \times 1\)卷積核。
YOLO由24個卷積層和2個全連接層組成,最終的輸出為\(7 \times 7 \times 30\)的張量,也就是針對每一個grid cell YOLO網絡都輸出了一個30維的向量,這個30維的向量就包括上面提到的各種信息:grid cell為基准預測出來的兩個bbox五元組,以及針對grid cell的預測某個類別的條件概率。具體如下:
目標函數
YOLO網絡的輸出實際上包含了三部分信息:bbox的位置信息,每個bbox的confidence以及每個grid cell的類別條件概率。 目標函數也就包含的三個部分:
很長的損失函數,首先來看兩個超參\(\lambda_{coord}\)和\(\lambda_{noobj}\).
由於要將bbox的位置信息,confidence以及類別的概率放到同一個目標函數中,而且各個分量占的輸出數據的多少也相差很多(位置信息只占了8個維度,而類別則占了20個維度),如果只是簡單的使用方差作為損失則很難對三個要優化的目標做好平衡:
- 8維的位置損失和20維的分類損失同等重要顯然是不合理的
- 如果一個grid cell中沒有object(一幅圖中這種grid cell很多),那么就會將這些grid cell中的box的confidence 置為0,相比於較少的有object的grid cell,這種做法是overpowering的,這會導致網絡不穩定甚至發散。
針對上述問題,損失函數中使用權重來解決。
-
為了表示8維的位置損失的重要性,給位置損失前面設置個大的權重,論文中設置的是\(\lambda_{coord}= 5\)
-
為了平衡沒有目標的grid cell,給沒有目標的損失設較小的權重,論文中設置的是\(\lambda_{noobj} = 0.5\)
-
公式中的第一行表示bbox位置損失。關於bbox位置損失有兩點,
- \(1_{ij}^{obj}\)第\(i\)個grid的第\(j\)個bbox是否負責該object的檢測(與該object的ground truth的IoU最大的bbox負責該object的檢測)。如果負責object的檢測,則\(1_{ij}^{obj} = 1\),否則為0,不參與位置損失的計算。
- 因為目標的大小不同,其位置偏移量也不能同等對待。對於小的物體對偏移量的容忍度則較小,而大的物體其對偏移的容忍則大一些,也是是不同大小的目標,其偏移量的損失也不能一概而論。為了平衡這個問題,YOLO使用了一個比較巧妙的方法,不是直接使用預測目標的寬和高計算損失,而是使用其平方根\((\sqrt{w_i} - \sqrt{\hat{w_i}})^2 + (\sqrt{h_i} - \sqrt{\hat{h_i}})^2\),如下圖
相同的位置偏移,反應在小目標的偏移損失比大目標預測的bbox要大。
-
公式的第二行是bbox的confidence的損失。 YOLO中一個目標被一個grid cell負責檢測,而同一個grid cell生成的\(B\)個bbox,也是和目標的 ground truth 的IoU負責。這樣就會有大量的bbox是不負責檢測目標的,也就是\(1_{ij}^{obj} = 0,1_{ij}^{noobj}=1\),而且由於包含目標的bbox較不包含目標的bbox要多很多,這里使用權值\(\lambda_{noobj}\)作為平衡,論文中使用\(\lambda_{noobj}=0.5\)
-
公式的第三行是grid cell的類別條件概率損失. \(1_{i}^{obj}\)表示第\(i\)個grid cell是否負責一個目標的檢測。
下圖能更好的解釋YOLO損失函數的意義
測試
輸入圖片,網絡會按照與訓練時相同的分割方式將測試圖片分割成\(S \times S\)的網格,因此,划分出來的每個網格預測的class信息和Bounding box預測的confidence信息相乘,就得到了每個Bounding box的class-specific confidence score,即得到了每個Bounding box預測具體物體的概率和Ground Truth重疊的好壞。
對於論文中,圖片划分為\(7 \times 7\)的網格,最終會得到98個bbox。要分類的目標有20個類給,這樣每個bbox對得到20個分數,表示該bbox在20個對象的得分。根據這20個得分情況,對98個bbox進行最大值抑制NMS,選出每個類別的最終bbox。
NMS的步驟如下:
1. 設置一個Score的閾值(0.2),低於該閾值的候選對象排除掉(將該Score設為0)。
2. 遍歷20個對象(找到每個對象的最好的bbox)
2.1 遍歷所有的98個bbox
2.1.1 選擇socre最大的bbox添加到輸出列表中
2.1.2 將計算余下的bbox的和score最大的bbox的IoU,如果大於設定的IoU閾值(0.5),則將該bbox的socre 設置為0.
2.1.3 從余下的bbox中選擇score最大的,重復上面的過程,直到所有的bbox要么在輸出列表中,要不其socre為0
2.2 輸出列表中bbox即為當前類的預測bbox
summary
YOLO是one-stage的目標檢測網絡,其優點:
- 快
- 使用整幅圖片進行預測,視野大,召回率低,表現為背景誤檢率低。
- 泛化能力強,對其他類的東西,訓練后效果也是挺好的
缺點:
- 一個網格中只預測了兩個框,並且只負責一類,YOLO對相互靠的很近的物體,還有很小的群體檢測效果不好。
- 當同一類物體出現的不常見的長寬比和其他情況時泛化能力偏弱
- 大邊界框的小誤差通常是良性的,但小邊界框的小誤差對IOU的影響要大得多。但YOLO會同樣的對待小邊界框與大邊界框的誤差,雖然做了一定的處理,但是物體的大小對仍有很大的影響。