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.通過預測的結果進行置信度的閾值處理,得到最終的結果。
本文圍繞:
- YOLO 爲什麼能檢測目標?
- YOLO 長什麼樣子?
- 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 公式定義如下:
其中 取值只有 0 和 1 兩種可能性,代表一個 cell 中是否存在物體。
下面對這個概念詳細解釋一下。
假設:我們要檢測的目標只有狗、汽車、自行車 3 種,那麼其他的物體都被當成背景。
在上面的圖片中,00,01,02 這些 cell 不包含任何的目標,所以它們的 爲0,所以 Confidence 也爲 0.
10 和 20 兩個 cell 因爲包含了自行車的一部分,所以它們的 爲 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 個類別的概率。
這是條件概率。
如果一個 Cell 存在 Object,預測這個 Object 的 class 纔有意義。
在測試階段,這個條件概率還要與 Cell 的 Confidence 相乘。
它的公式表達了兩個思想:
- 類別的概率
- 預測的框距離 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。
這也是下面的符號代表的意義。
下標 i 代表 cell 的序號,下標 j 代表這個 cell 的第 j 個 bbox。
這行 Loss 就是所有的存在目標的 cell 中所預測的 bbox 中心點的 SSE。
前面的 是權重,爲什麼要加這個權重呢?
這個需要細緻說一下。
SSE 導致了 bbox 的定位和分類問題權重一樣,並且那些沒有包含物體的 cell ,它們的 confidence 是 0,這會導致訓練過程中,梯度變化不平衡,整個模型變得不穩定。
爲了解決這個問題,所以引入了兩個 分別代表有 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
- 第一個 epoch ,學習率緩慢從 0.001 到 0.02.
- 以 0.02 訓練 75 個 epochs。
- 以 0.001 訓練 30 個 epochs。
- 以 0.0001 訓練最後 30 個 epochs。
爲了防止過擬合,採用了 dropout 技術,比率爲 0.5.
另外還做了數據增強。
YOLO 的侷限性
因爲一個 cell 只能預測一個類別,所以如果比較小的物體成羣出現,會導致許多的 object 的中心點其實在一個 cell 中,那麼就會出現漏檢。
下一步
學完 YOLOv1 只是第一步。
下一步建議你將 YOLOv2 和 YOLOv3 也學習。
另外,你可以根據你的理解用 Tensorflow 或 Pytorch 復現或者仿照一個 YOLO 網絡。