目標檢測之YOLO V1

前面介紹的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損失了必定的精度,可是其有點就是速度快。ide

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 的定義以下:
\[ Confidence = Pr(object) \cdot IoU_{pred}^{truth} \]
其中,\(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。spa

這樣,經過每一個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(條件類別機率):
\[ P(class_i | object) \]
即在一個grid cell中有一個Object的前提下,它屬於某個類的機率。只爲每一個grid cell預測一組類機率,而不考慮框的數量。code

類別機率\(P(class_i | object)\)是對於某個grid cell的,表示該grid cell可以預測一個目標的條件下,其目標的屬於某個類的機率;而bbox的confidence表示的是,包含目標的可行性。 將這兩個值相乘,就能夠獲得bbox中包含的目標的的類別的機率了。
因此在測試階段,將grid cell的\(P(class_i | object)\)和以該grid cell爲準預測出來bbox的confidence相乘
\[ P(class_i | object) \cdot P(object) \cdot IoU_{pred}^{truth} \]
該值就能反應出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的類別條件機率。 目標函數也就包含的三個部分:
\[ \begin{align*} & \lambda_{coord}\sum_{i=0}^{S^2}\sum_{j=0}^{B}1_{ij}^{obj}\left(x_i - \hat{x_i})^2 + (y_i - \hat{y_i)^2}) \right] + \lambda_{coord}\sum_{i=0}^{S^2}\sum_{j=0}^{B}1_{ij}^{obj} \left[(\sqrt{w_i} - \sqrt{\hat{w_i}})^2 + (\sqrt{h_i} - \sqrt{\hat{h_i}})^2 \right] \\& + \sum_{i=0}^{S^2}\sum_{j=0}^{B}1_{ij}^{obj}(C_i - \hat{C_i})^2 + \lambda_{noobj}\sum_{i=0}^{S^2}\sum_{j=0}^{B}1_{ij}^{noobj}(C_i - \hat{C_i})^2 \\& + \sum_{i=0}^{S^2}1_{i}^{obj}\sum_{c \in classes}(p_i(c) - \hat{p_i)(c))^2}) \end{align*} \]

很長的損失函數,首先來看兩個超參\(\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會一樣的對待小邊界框與大邊界框的偏差,雖然作了必定的處理,可是物體的大小對仍有很大的影響。
相關文章
相關標籤/搜索