【深度學習】目標檢測算法 YOLO 最耐心細緻的講解

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

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

YOLO 勝在它的簡單與快速。

  • YOLO 是單個神經網絡進行端到端的預測,沒有多個步驟和過程。
  • YOLO 的速度非常快,可以達到實時的 45 fps,簡化版本甚至達到 155 fps。

本博文是基於 YOLO v1 的論文講解,最新的版本已經進化到了 YOLO v3,但我還是覺得先從它最基本的思路開始講解要好。

YOLO V1 論文地址

YOLO 目標預測如同捕魚

在 YOLO 前,目標檢測一般通過算法生成候選區域,然後在數量衆多的候選區域中做目標的分類和 bbox 位置的迴歸。

更古老的方法是通過滑動窗口的形式去挨個預測與判別。

但 YOLO 大不相同。

在這裏插入圖片描述

如果把目標檢測看做是一個捕魚的過程,其他算法是拿着漁叉一個一個精準地狙擊,那麼 YOLO 就粗獷的多,一個漁網撒撒下去,一網打盡。

YOLO 的預測是基於整個圖片的,並且它會一次性輸出所有檢測到的目標信息,包括類別和位置。

YOLO 的算法思路。

YOLO 的算法思路其實挺簡單的。

在這裏插入圖片描述

  1. 縮放輸入的圖片
  2. 將圖片送入到卷積神經網絡中進行預測
  3. 通過預測的結果進行置信度的閾值處理,得到最終的結果。

下面講解算法細節。

分割圖片

YOLO 會把輸入圖片分割成 SxS 個網格,如果一個目標的中心點落在某個網格當中,那麼對應的那個網格就負責預測這個目標的大小和類別。

在這裏插入圖片描述
上面的圖片示例中,狗的中心點落在了藍色的網格當中,所以藍色的網格就負責這個目標的信息預測。

每個網格目標的預測

每個網格都會預測 B 個 bbox 和 bbox 對應的置信值 Confidence,bbox 預測目標的位置,Confidence 用來反映這個網格是否有包含目標及 bbox 的準確性有多高。

C=Pr(obj)IOUtruthpred C = Pr(obj) * IOU_{truth}^{pred}

但是需要注意的是,如果一個網格它並不包含目標,那麼 Pr(obj)Pr(obj) 就等於 0,反之等於 1,所以,C 等同於預測出來的 bbox 同 groundtruth 的 IOU。

每一個 bbox 由 5 個預測量組成:x、y、w、h、confidence。

x,y 是 bbox 中心點相對於對應網格的偏移量比例,並且它們的取值是 0 ~ 1 之間,也就是它們有相對於網格的尺寸做歸一化處理。

同樣,w、h 都有經過歸一化,因此它們的值都在 0 ~ 1 之間。

w 和 h 是 bbox 相對於整張圖片尺寸的比例。

confidence 剛剛有講過,它代表了預測出來的 bbox 與 groundtruth 的 bbox 之間的 IOU。

每個網格除了 bbox 外,還會預測 C 個條件概率 Pr(classiOjbect)Pr(class_{i}|Ojbect)

這個條件概率指的是當網格中存在目標時候,目標類別的概率分佈。

條件概率針對的是每一個網格,而不是每一個 bbox,因爲每個網格會預測 B 個 bbox。

在測試階段,YOLO 會將條件概率和每個 bbox 的 confidence 相乘。

在這裏插入圖片描述

這樣的結果是針對每一個 bbox 而言的目標類別概率分佈的置信值,這個置信值同時表達了 2 樣東西,一個是目標是某個類別的概率,一個是預測的 bbox 離真實的 bbox 有多遠。

在這裏插入圖片描述
YOLO 把輸入圖片劃分成 SxS 個網格,每個網格都會預測 B 個 bbox 和 C 個目標類別的條件概率,並且每一個 bbox 包含 x、y、w、h、confidence 5 個參數。

所以,YOLO 最終的預測結果可以整合成一個尺寸爲 SS(5*B+C) 的 tensor。

B、S、C 這幾個值都由網絡結構的設計者決定,YOLO v1 在 PASCAL VOC 數據集上評估時,S = 7,B = 2。
因爲這個數據集有 20 個種類,所以 C = 20,套用前面的公式,最終預測時 Tensor 的尺寸爲 7730。

YOLO 的網絡結構設計

YOLO 是基於 CNN 的,論文作者說他受 GooLeNet 結構的啓發,然後構建了一個新的網絡結構。

YOLO 用 1x1 的卷積核代替了 GooLeNet 的 Inception 模塊來做降維度。

YOLO 有 24 個卷積層,然後後面跟着 2 個全連接層。

下面是它的網絡結構。

在這裏插入圖片描述
大家看到,YOLO 最終的預測輸出就是一個 7x7x30 的 tensor。

在這裏插入圖片描述
這張圖片也可以大致示意最終預測的 tensor 的結構。

YOLO 的訓練過程

YOLO 在 ImageNet 上用前 20 個卷積層和 1 個全連接層做通用的類別識別訓練,並達到比較高的準確率。

之後,YOLO 作者在預訓練好的結構上添加了 4 個卷積層和 1 個全連接層做目標識別訓練。

因爲想提高目標識別的整體表現,所以 YOLO 在 ImageNet 預訓練時,輸入圖片尺寸是 224x224,但在 PASCAL VOC 上做目標識別的專項訓練時,輸入圖片尺寸變成了 448x448

除了最後一層採用線性激活函數外,其他層都採用 leaky Relu。

YOLO 的 Loss 設定

我們都知道,採用合適的 loss 對於訓練一個神經網絡而言非常重要。

而我認爲,只有理解了 YOLO 的 loss 設計原則,纔算真正理解了 YOLO 算法的核心.

我們知道,一般 Loss 值越低,代表網絡準確度越高,訓練的越有效,所以訓練時基本上是以減弱 loss 值爲目標的。

YOLO 作者在訓練時,用 sum-squared error (誤差的平方的和)來作爲 loss 進行優化。

採用 sum-squared error 是因爲它容易進行優化,但是它也有不好的地方,那就是對於提高 mAP 的表現有些吃力。

sum-squared error 會讓 Loss 函數對於位置預測、類別預測的誤差權重一樣。

實際情況是,YOLO 在每一張圖片上會預測 772=98 個 bbox,但只有很少的 bbox 才包含目標,哪些不包含目標的 bbox 它們的 confidence 會在訓練過程中很快變成 0,所以哪些包含了目標的網格它們預測的 bbox 的梯度會更加急劇變化,這樣而言,整個預測系統處於不平衡也不穩定的狀態,最終可能出現 loss 無法收斂。

爲了,糾正和改善情況,YOLO 的作者調整了 bbox 的座標誤差和 沒有包含目標時 confidence 的誤差權重,也可以看做是添加了不同的懲罰係數,分別是 5 和 0.5。

爲什麼這樣做呢?

可以這樣理解,整個 YOLO 系統其實最有效的地方就是那些包含了目標中心點的網格它們所預測的 2 個 bbox,所以它們這 2 個 bbox 的位置信息就至關重要,所以它們的座標就不允許它們變化劇烈,所以就需要添加一個係數放大它們的誤差,進而達到懲罰的目的。

而沒有包含目標的網格,雖然它們也會預測 bbox,也會有 confidence 的預測,但基本等同於無效,所以可以看做它們對於整體的 Loss 而言,沒有那麼重要,因此要減弱它們對於 Loss 的影響,以防止它去幹擾正常的包含了目標的那些 bbox 的 confidence 表現,畢竟它無關緊要。

說到這裏,我有思考一個問題:
如果要減弱沒有 object 時的 confidence 對 loss 整體的影響,爲什麼不做到極致?讓懲罰係數由 0.5 變成 0 不更好嗎?

我沒有標準答案,但我的理解是那樣會讓 YOLO 這個系統失衡,喪失了預測背景的能力,所以也失去了某種綜合的能力。

sum-squared error 還有一個問題,那就是它會讓大的 bbox 和小的 bbox 位置誤差敏感度一樣。

比如預測一個小的 bbox,groundtruth 的 width 是 4,它預測是 3,那麼它的誤差是 1.

再預測一個大的 bbox,groundtruth 的 width 是 100,預測值是 99,那麼誤差也是 1.

但大家很容易發現,進行小尺寸的 bbox 預測時,誤差更敏感,所以 sum-sqaured error 手段需要改良。

YOLO 採用的是用預測值和 groundtruth 各自的平方根做誤差,然後再 sum-sqaured error。

還是用剛纔的例子,小的 bbox width prediction = 3,groundtruth = 4,誤差爲 0.067。
大的 bbox width prediction = 99,groundtruth = 100,誤差爲 0.0025。

所以,完美的解決了這個問題。

最終的 Loss 變成了一個複合的 Loss,公式如下:

在這裏插入圖片描述

需要注意的是,YOLO 每個網格預測兩個 bbox,最終只有 1 個 bbox 來負責代表相應的目標的 bbox 位置,它們通過 Confidence 比較,也就是 IOU 比較,勝出的是分數更高的那個,進行 loss 計算時,也是這個 bbox 才能參與。

其它具體的訓練策略如下:

  1. 第一個 epoch,學習率從 0.001 緩慢變成 0.01.
  2. 接下來的 75 個 epoch ,學習率固定爲 0.01
  3. 之後又用 0.001 訓練 30 個 epoch
  4. 最後用 0.0001 訓練 40 個 epoch
  5. 爲了避免過擬合,YOLO 訓練時有采用 dropout 和數據增強手段。

總結

YOLO v1 也有和當年其它傑出的目標檢測系統做對比,但在今天來看,這個並不十分重要,重要的是我們需要理解 YOLO 快的原因。

  • YOLO 就是一個撒漁網的捕魚過程,一次性搞定所有的目標定位。
  • YOLO 快的原因在於比較粗的粒度將輸入圖片劃分網格,然後做預測。
  • YOLO 的算法精髓都體現在它的 Loss 設計上及作者如何針對問題改進 Loss,這種思考問題的方式纔是最值得我們學習的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章