死磕YOLO系列,YOLOv1 的大腦、軀幹和手腳

YOLO 是我非常喜歡的目標檢測算法,堪稱工業級的目標檢測,能夠達到實時的要求,它幫我解決了許多實際問題。

在這裏插入圖片描述
這就是 YOLO 的目標檢測效果。它定位了圖像中物體的位置,當然,也能預測物體的類別。

之前我有寫博文介紹過它,但是每次重新讀它的論文,我都有新的收穫,爲此我準備寫一個系列的文章來詳盡分析它。這是第一篇,從它的起始 YOLOv1 講起。

YOLOv1 的論文地址:https://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/Redmon_You_Only_Look_CVPR_2016_paper.pdf

建議沒有看過原論文的都應該好好看看。

在這裏插入圖片描述

YOLO 預測時,很簡單。

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

本文圍繞:

  1. YOLO 爲什麼能檢測目標?
  2. YOLO 長什麼樣子?
  3. YOLO 如何訓練?

三大問題來詳細展開,爲此我類比爲 YOLO 的大腦、軀幹和手腳。

1. 大腦,爲什麼能檢測目標?

YOLO 是 One-Stage (單階段) 檢測算法,它只需要看圖片一次,就可以預測圖片中所有的物體邊框。

我個人有一個形象的比喻,那就是撒漁網。

一個漁網撒下去,所有的魚兒都要捕獲。

在這裏插入圖片描述

而實際上,YOLO 真的有類似漁網的操作。

YOLO 把一張圖片劃分成了 SxS 個格子。

這裏的 S 不固定,可以根據實際情況由開發者自主決定。

在這裏插入圖片描述
論文中,S 取值爲 7,所以整張圖片被分割成 7*7=49 個格子(Cell)。

這些格子像不像漁網的網眼呢?

那麼,這些 Cell 是幹什麼用的呢?爲什麼要設置這麼多的 Cell ?

這些 Cell 每個 Cell 都會預測 B 個 bbox。在論文中 B 取值爲 2。

所以,一張圖片經 YOLO 跑一遍,就會產生 98 個 bbox。

在這裏插入圖片描述
有同學可能會思考:

這麼多 bbox,比目標的個數還要多,怎麼選擇呢?

以上面的圖片爲例:

在這裏插入圖片描述
圖片中有狗、自行車、汽車 3 個目標,但是預測到的 bbox 有 98 個之多,最終肯定只能從 98 個 bbox 中選擇 3 個。

那麼,怎麼操作呢?

分 2 步走。

第一步,有選擇的響應 cell。

總共有 49 個 cell,但是並不是每一個 cell 的預測都有意義,我們需要找出有意義的 cell。

那麼哪些 cell 算是有意義呢?

先來看看一個叫做 Confidence 可信度的概念。

每個 Cell 預測 B 個 bbox,還有每個 bbox 對應的 Confidence。

Confidence 公式定義如下:
Confidence=Pr(Obj)IOUpredtruth Confidence = Pr(Obj)*IOU_{pred}^{truth}

其中 Pr(Obj)Pr(Obj) 取值只有 0 和 1 兩種可能性,代表一個 cell 中是否存在物體。

下面對這個概念詳細解釋一下。

假設:我們要檢測的目標只有狗、汽車、自行車 3 種,那麼其他的物體都被當成背景。

在這裏插入圖片描述
在上面的圖片中,00,01,02 這些 cell 不包含任何的目標,所以它們的 Pr(Obj)Pr(Obj) 爲0,所以 Confidence 也爲 0.

10 和 20 兩個 cell 因爲包含了自行車的一部分,所以它們的 Pr(Obj)Pr(Obj) 爲 1,它們的 Confidence 實質上就是 bbox 和 groundtruth 的 IOU。

另外怎麼判斷某個 cell 中有沒有包含 Object 呢?

這其實是通過 label 中的 groundtruth 在線算出來的。

因此,一張圖片經過 YOLO 跑一遍後,除了預測出 98 個 bbox,還會給出 49 個 cell 的 confidence.

所以,那些 confidence 不爲 0 的 cell 都算作有意義。

不過,還可以更進一步。

一個 Object 可能覆蓋很多個 Cell。

我們還需要從中選擇一個 Cell,作爲代表,這個 Cell 就負責(responsible)此 Object 的預測。

在這裏插入圖片描述
我們看上圖。

狗的 groundtruth 覆蓋了總共 15 個 Cell,那麼哪個 cell 否則這條狗呢?

在這裏插入圖片描述
答案就是我上圖標示出來的 cell。

爲什麼是它呢?

原則只有 1 個:Object 的中心落在哪個 cell,就決定了那個 cell 的核心地位。

在這裏插入圖片描述

很好理解嘛,一個國家最高的機構落地的城市,就是首都。

再往下走。

每個 Cell 還會預測 C 個類別的概率。

這是條件概率。

Pr(ClassiObject) Pr(Class_{i}|Object)

如果一個 Cell 存在 Object,預測這個 Object 的 class 纔有意義。

在測試階段,這個條件概率還要與 Cell 的 Confidence 相乘。
在這裏插入圖片描述
它的公式表達了兩個思想:

  1. 類別的概率
  2. 預測的框距離 groudtruth 有多接近

需要注意的是,每個 Cell 輸出的是一組概率,代表了 C 個類別的概率,在論文中 YOLO 的 C 取值爲 20.

所以,YOLO 最終就是通過下圖的方式來預測的。

在這裏插入圖片描述它的本質是因爲 YOLO 模型的最後一層是一個 7x7x30 的 tensor。

7x7 對應圖像分割成 49 個 cell。

30 包含了 2 個 bbox 的數據,及 20 個 class 的概率。

在這裏插入圖片描述
以上,就是 YOLOv1 目標檢測的核心思想,它能檢測就是基於上面的思路。

2.軀幹,長什麼樣子?

我指的軀幹其實就是 YOLO 的神經網絡結構。

這部分比較簡單,我將快速略過。

在這裏插入圖片描述原論文中說到,YOLO v1 的模型結構受 GoogLeNet 啓發。

但是,有少許不同。

YOLO 採用了 1x1 和 3x3 的序列組合替代 Inception 模塊。

總共 24 個卷積層加上 2 個全連接層。

輸出層正是前面提到過的 7x7x30 的 tensor,用來預測最終的結果。

然後,需要注意的是 YOLO 將定位和目標分類統一成了一個迴歸問題。

3. 手腳,如何訓練

YOLO 的訓練並不複雜,其中最重要的內容就是 Loss 的設定。

1. 預訓練

取 YOLO 模型前面的 20 個卷積加上 1 個全連接層在 ImageNet 上訓練,也就是爲了目標識別,目的是爲了獲取目標的特徵表達能力。

2. 目標檢測訓練

在 pretrain 的基礎上增加了 4 個卷積層和 2 個全連接層。

因爲目標檢測任務的訓練一般對圖像分辨率精細度要求比較高,所以,在這以階段,輸入圖像的尺寸從之前 ImageNet 需要的尺寸 224x224,變成了 448x448。

另外,爲了歸一化的效果,對於之前預測的 bbox,YOLO 也做了特別的處理。

一般,我們講 bbox 中的 4 個參數 (x,y,width,height) 指的是下圖所示:

在這裏插入圖片描述
YOLO 做了調整。

X,Y 在預測的 bbox 中代表框的中心點位置,並且是相對於 Cell 中心點的偏移比例,取值是 0 到 1 之間。

可能難以理解,圖例說明。

在這裏插入圖片描述
上圖中某個 cell 預測了一個 bbox。

黃色的原點代表 cell 的中心。
紅色的圓圈代表 bbox 的中心。

那麼 x,y 的取值就是兩個中心的偏移量和 cell 本身寬高的比值。

x = (bbox.x-cell.x)/cell.width
y = (bbox.y - cell.y)/cell.height

另外 bbox 包含的 w,h 也是一個歸一化的結果。是 bbox 的寬高和整張圖片的寬高的比值。

所以,w,h 同樣取值爲 0 到 1。

w = bbox.width / image.width
h = bbox.height / image.height

好,講完 bbox 的 4 個參數,再回到訓練上來。

YOLO 的激活層除了最後一層外都是採用 ReLu。

YOLO 用誤差平方和(SSE) 進行優化,作者說因爲這樣比較簡單。

但是 YOLO 的 Loss 由 4 個子 Loss 構成,也是最難以理解的一部分。

在這裏插入圖片描述
公式很長,慢慢分析其實也還行。

首先 Loss 要計算:

  • 中心點的 Loss
  • 寬高的 Loss
  • 置信度的 Loss
  • 目標類別的 Loss

前面講到一張圖片產生 49 個 cell,有些 cell 沒有什麼意義,因爲它們不包含任何的 Object。

所以,計算 Loss 時就只考慮有 Object 存在的 cell。

這也是下面的符號代表的意義。

1ijobj 1_{ij}^{obj}

下標 i 代表 cell 的序號,下標 j 代表這個 cell 的第 j 個 bbox。
在這裏插入圖片描述
這行 Loss 就是所有的存在目標的 cell 中所預測的 bbox 中心點的 SSE。

前面的 λcoord\lambda_{coord} 是權重,爲什麼要加這個權重呢?

這個需要細緻說一下。

SSE 導致了 bbox 的定位和分類問題權重一樣,並且那些沒有包含物體的 cell ,它們的 confidence 是 0,這會導致訓練過程中,梯度變化不平衡,整個模型變得不穩定。

爲了解決這個問題,所以引入了兩個 λ\lambda 分別代表有 object 和沒有 object 的權重。

這兩個權重是懲罰項,代表不同的內容對於整個優化過程的貢獻度。

另外有人注意到計算 bbox 寬高的 Loss 時。

在這裏插入圖片描述

爲啥是平方根的差呢?

因爲 bbox 對於尺寸敏感度很高。

在這裏插入圖片描述
假設上圖兩組 bbox 預測與真值比對結果中,w 這一維度的結果都是 0.2.

但是左右兩組對於這個數值敏感度是不一樣的,我們可以看到,右邊那組小尺寸的更加敏感。

所以,用平方根就是爲了縮短這種差距。

爲此,我們可以對 Loss 總結如下:

  • 計算有物體的 Cell 的 bbox 中心點、寬高、物體類別的 Loss
  • 計算所有 Cell 的 Confidence 的 Loss,但是無 Object 的 Cell 它的 Loss 權重很低
  • 相對於物體類別,bbox 定位的權重要更高。

Loss 講完後,YOLO 就差不多講完了,接下來快速陳述一下它的訓練過程。

訓練過程

在 PASCAL VOC 2007 和 2012 訓練和驗證,總共 135 epochs。

batch size 是 64.
momentum 是 0.9
decay 是 0.0
  1. 第一個 epoch ,學習率緩慢從 0.001 到 0.02.
  2. 以 0.02 訓練 75 個 epochs。
  3. 以 0.001 訓練 30 個 epochs。
  4. 以 0.0001 訓練最後 30 個 epochs。

爲了防止過擬合,採用了 dropout 技術,比率爲 0.5.

另外還做了數據增強。

YOLO 的侷限性

因爲一個 cell 只能預測一個類別,所以如果比較小的物體成羣出現,會導致許多的 object 的中心點其實在一個 cell 中,那麼就會出現漏檢。

下一步

學完 YOLOv1 只是第一步。

下一步建議你將 YOLOv2 和 YOLOv3 也學習。

另外,你可以根據你的理解用 Tensorflow 或 Pytorch 復現或者仿照一個 YOLO 網絡。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章