# Object Detection - YOLO v1
> [name=謝朋諺(Adam Hsieh)]
> [time=Tue, Apr 9, 2019 4:01 PM]
###### tags: `paper`
---
## Reference
> [目标检测|YOLO原理与实现](https://zhuanlan.zhihu.com/p/32525231)
> [YOLO算法的原理与实现](https://blog.csdn.net/jyy555555/article/details/80411149)
> [图解YOLO](https://zhuanlan.zhihu.com/p/24916786)
> [CNN经典神经网络模型 | 目标检测(续)](http://www.laphiler.com/2018/01/15/cnn-classic-model-objectdetection2/)
> [目标检测系列(六):YOLO v1](https://blog.csdn.net/weixin_43854922/article/details/86509975)
---
## You Only Look Once: Unified, Real-Time Object Detection
[論文連結](https://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/Redmon_You_Only_Look_CVPR_2016_paper.pdf)
{%pdf https://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/Redmon_You_Only_Look_CVPR_2016_paper.pdf %}
### 與 R-CNN 比較
1. R-CNN 先在影像中生成潛在的 Bounding Box 並在這些框上執行分類器。在分類之後再運用後處理細化 Bounding Box 消除重複的檢測,並根據場景中的其他目標重新定位 Bounding Box
==缺點:流程很慢,很難優化,因為每個元件都必須單獨訓練。==
2. YOLO 將檢測問題作為一個回歸問題,直接從影像到 Bounding Box 和分類的機率
==優點:只要看影像一次就能預測出現的目標跟位置。==
### YOLO 優點們
1. YOLO 在 Titan X GPU 沒有批次處理可達到 45 FPS,若是快速版本可到 150 FPS,而且在即時偵測的準確度還比其他系統高兩倍以上。
:::success
:+1: 因為 YOLO 只用一個 CNN 來實現檢測跟分類
:::
2. YOLO 與 Fast R-CNN 相比背景誤檢測數量少了一半。
:::success
:+1: YOLO 會看整張圖片而不是 Sliding Window 或 Region proposal-based 的方法,所以可以說他隱晦地 encode 類別的上下文關係和他們的外觀。
:::
3. YOLO 學習目標的 Generalizable 能力大幅優於 DPM 跟 R-CNN 等頂級方法。
4. 所有訓練很測試程式都是開源的。連模型都可以下載。
### YOLO 缺點
1. 在偵測的準確度上仍然落後最先進的檢測系統。
2. 對於小物體表現不如人意。
3. 對於物體的寬高比的 Generalization 較弱,無法定位不尋常比例的物體。
### Method
1. 將輸入影像分成 $S \times S$ 的網格。==如果物件的中心在某個網格的單元中,該網格就負責檢測該物件==。
2. 每格網格預測 $B$ 個 Bounding Box 和對這些 Bounding Box 的信心指數。這分數反映了該模型對 Box 是否包含物件的信心以及他預測 Box 的準確程度。
* Bounding Box 信心指數的公式設為:==$Pr(Object)*IOU^{truth}_{pred}$==
* 如果該網格沒有任合物件,$Pr(Object)=0$ 則信心指數就為 0。否則 $Pr(Object)=1$ 信心指數就等於預測框跟真實框的 IOU。
3. 每個 Bounding Box 包含五個預測值:==$x, y, w, h, confidence$==
* $x, y$ 表示 Bounding Box 中心座標,相對於網格邊界框左上角座標點的偏移量,單位是幾個單元格,ex:(0.8, 0.2)格
* $w, h$ 表示相對於整張圖像的寬度和高度的比例
* $confidence$ 表示預測框與實際框之間的 IOU
* $x,y,w,h$ 數值皆在 0~1 之間

4. 每個網格還預測 $C$ 個分類的條件機率: $Pr(Class_{i}|Object)$
* 每個網格只預測一組類別機率,而不管 Bounding Box 的數量 $B$ 是多少。
:::danger
:fire: 雖然看起來是由該網格負責預測 Bounding Box 其物件屬於各個類別的機率,但這些機率值其實是在各個 Bounding Box 信心指數下的條件機率。
:::
5. 在**測試**時本文乘以分類的條件機率和單個 Box 預測出的信心指數:
==$Pr(Class_{i}|Object)*Pr(Object)*IOU^{truth}_{pred}=Pr(Class_{i})*IOU^{truth}_{pred}$==
這個公式為我們提供了每個框特定的類別信心分數,這些分數編碼了==類別出現在此框中的機率==以及==預測框與目標的擬合程度==。
:::danger
:fire: Bounding Box 類別信心值表徵是該 Bounding Box 中物件屬於各個類別的可能性大小以及 Bounding Box 匹配物件的好壞。
:::
6. 本文在 PASCAL VOC 上做驗證,$S=7$, $B=2$,因為 PASCAL VOC 有 20 個類別,因此 $C=20$。總共會有 ==$S\times S\times (B*5+C)$== => $7 \times 7 \times 30$ 的 tensor

### Network Design

網路的一開始的 CNN Layer 負責提取特徵,而全連接層則輸出預測的機率跟座標。
* 24 CNN Layer (受到 GoogLeNet 啟發)
* 2 Fully Connected Layer
* 只使用 $1 \times 1$ 的降維層以及後面的 $3 \times 3$ 卷積層
* 有先在 ImageNet 上預訓練模型 (影像大小是 224*224)
* 最後預測結果都是 $7 \times 7 \times 30$ 的 tensor

* 前面 20 個是類別機率值,後 2 個元素是 Bounding Box 信心指數,兩者相乘可得類別的信心分數。
* 後 8 個元素為框框的 $(x,y,w,h)$
這邊解釋一下網路的預測值是一個二維 tensor $P$
* Shape 為 $[batch,7 \times 7 \times 30]$
* $P_{[:,0:7*7*20]}$ 就是類別機率部分
* $P_{[:,7*7*20:7*7*(20+2)]}$ 就是類別信心分數的部分
* $P_{[:,7*7*(20+2):]}$ 就是 Bounding Box 預設的結果
另外還有一個版本是快速版本的 YOLO 主要是為了能夠達到快速目標檢測的界線。
* 24 層改為只有 9 層的 CNN Layer
* 使用較少的濾波器
* 其他訓練和測試的參數都是相同的
### Training
* 在 ImageNet 1000-class 數據集中預訓練本文的 CNN Layer,但只使用圖三中的前 20 個 CNN Layer 接著加上 average-pooling layer 跟 fully connected layer。
* 訓練了一週的時間並在 ImageNet 2012 驗證集中獲得像 top-5 的準確率高達 88%。
* 將後面的 average-pooling layer 跟 fully connected layer 拔掉加入四個卷積層與兩個全連接層並且隨機初始化權重。
* 由於檢測通常需要看到較細微的資訊,因此將網路的輸入解析度從 $224 \times 224$ 改為 $448 \times 448$
* 除了最後一層使用線性 activation function 其餘層都是使用以下的公式激活(Leaky ReLU):
$\phi (x) = \begin{cases} x,\ if\ x>0 \\0.1x,\ otherwise \end{cases}$
* 由於 YOLO 是將物件檢測看成回歸問題,所以採用得是 ==Sum-squared error== 因為他比較好優化但並不理想,原因是若網格中未包含物件他的信心指數往往都是 0,會壓倒有包含物件的網格的梯度,這可能導致模型不穩定,進而導致訓練早期就發散。
* 為了彌補上述這點,本文==增加了 Bounding Box 座標預測的 loss== 並==減少了不包含物件 Bounding Box 信心水準的 loss==,多使用了兩個參數 $\lambda _{coord} =5$、$\lambda _{noobj}=0.5$
* Sum-squared error 也可以在 Large Box 跟 Small Box 做權重改變。==Large Box 的小偏差重要性比起 Small Box 的小偏差重要性來得低==。為了解決這問題本文直接預測 Bounding Box 的==平方根==而不是寬度和高度。
* YOLO 的每個網格單元都會預測多個 Bounding Box,但對應類別只有一個。因此在訓練階段對每個物件,我們希望只有一個 Bounding Box 預測器負責。我們指定一個 Bounding Box 最高 IOU 的預測器“負責”來預測物件,而其他 Bounding Box 則判定為沒有物件。
:::danger
:ghost: 缺點是一旦網格出現多個不同物件還是只能輸出一個類別。
:::
* 以下是 Loss Function:

* $\mathbb{1}^{obj}_{i}$ 表示假設物件出現在網格單元 $i$ 中,$\mathbb{1}^{obj}_{ij}$ 代表網格單元 $i$ 中第 $j$ 個 Bounding Box 預測器負責該預測。
* 第一項是 Bounding Box 中心座標的誤差值
* 第二項是 Bounding Box 高與寬的誤差值
* 第三項是包含物件 Bounding Box 信心指數的誤差值
* 第四項是不包含物件的 Bounding Box 信心指數的誤差值
* 最後一項是包含物件的網格的分類誤差值
* 信心指數的 target 值 $C_i$,如果是不存在物件此時由於 $Pr(object)=0$,那麼 $C_{i}=0$。如果存在物件 $Pr(object)=1$,此時就需要確定 $IOU^{truth}_{pred}$
:::warning
:bulb: 最好的情況是希望將 IOU 取 1,這樣就可得到 $C_i=1$,但是在 YOLO 實現中,使用了一個控制 rescore (默認為 1),當其為 1 時,IOU 不是設置為 1,而是計算真實的 IOU 不過很多復現 YOLO 的作者還是取 $C_i=1$ 這個差異可能不會太影響結果吧
:::
* 如果物件出現在該網格中(前面討論的條件類別機率),則 Loss Function 只懲罰分類錯誤。如果預測器負責實際框框的邊界(即該網格單元中具有最高 IOU 的預測器),則他也只懲罰邊界框座標的錯誤。

### Inference
每張影像在網路上皆會預測 $7 \times 7 \times 2 = 98$ 個 Bounding Box 和類別
YOLO 作法先使用 NMS 才確定各個 Box 的類別。
:::info
:book: NMS(Non maximum suppression) 演算法,主要是為了解決同個物件被多次檢測的問題,首先從所有檢測框中找到信心值最大的框,然後一個一個計算其與剩餘框的 IOU,如果其值大於 Threshold,那麼就將該框剔除,然後將剩餘的檢測框重複上述過程,直到處理完所有的檢測框。
:::

1. 對於 98 個 box 將小於信心指數閾質的值歸 0
2. 然後分類別地對信心指數使用 NMS,被合併的信心指數也設為 0
3. 最後才確認不為 0 的 Bounding Box 的各個類別
4. NMS方法大概可以提昇 mAP 2-3%

每個網格跟 tensor 代表的意義匹配:


整體流程如下圖:



最後就可利用前面所述的閾值與 NMS 處理得到最終檢測結果

### YOLO 限制總整理
1. YOLO 中每個網格只能預測兩個 Bounding Box,且只能有一個類別,這使得模型不太能預測鄰近目標的數量,比如鳥群
2. 測試的圖像中,若同類物體出現不常見的長寬比和其他情況時 Generalized 能力較弱
3. 由於 Loss Function 的問題,定位誤差是影響檢測效果最主要原因,尤其是小物體處理上還要加強
### 與其他系統的比較
資料集是 PASCAL VOC 2007 以及 2012,比較的系統有 DPM、R-CNN 以及 Faster R-CNN

### 錯誤分析
為了進一步分析,本文將預測結果按照分類與定位準確性分成以下 5 類:
* Correct: 正確的類別且 $IOU > 0.5$(準確度)
* Localization: 正確的類別,$0.1 < IOU < 0.5$ (定位不準)
* Smiliar: 類別相似,$IOU > 0.1$
* Other: 類別錯誤,$IOU > 0.1$
* Background: 任何 $IOU < 0.1$(誤把背景當物體)

YOLO 主要錯誤在定位部分,Fast R-CNN 定位錯誤少很多但背景錯誤多很多。
YOLO 還有在真實環境跟藝術品中的行人做檢測來驗證它的效能
