[目標檢測]YOLO原理


1 YOLO

創新點: 端到端訓練及推斷 + 改革區域建議框式目標檢測框架 + 實時目標檢測

1.1 創新點

(1) 改革了區域建議框式檢測框架: RCNN系列均需要生成建議框,在建議框上進行分類與回歸,但建議框之間有重疊,這會帶來很多重復工作。YOLO將全圖划分為SXS的格子,每個格子負責中心在該格子的目標檢測,采用一次性預測所有格子所含目標的bbox、定位置信度以及所有類別概率向量來將問題一次性解決(one-shot)。

1.2 Inference過程

YOLO網絡結構由24個卷積層與2個全連接層構成,網絡入口為448x448(v2為416x416),圖片進入網絡先經過resize,網絡的輸出結果為一個張量,維度為:

\[S * S * (B * 5 + C) \]

其中,S為划分網格數,B為每個網格負責目標個數,C為類別個數。該表達式含義為:
(1) 每個小格會對應B個邊界框,邊界框的寬高范圍為全圖,表示以該小格為中心尋找物體的邊界框位置。
(2) 每個邊界框對應一個分值,代表該處是否有物體及定位准確度:$$P(object)*IoU_{pred}^{truth}$$
(3) 每個小格會對應C個概率值,找出最大概率對應的類別\(P(Class | object)\),並認為小格中包含該物體或者該物體的一部分。

1.3 分格思想實現方法

一直困惑的問題是:分格思想在代碼實現中究竟如何體現的呢?
在yolov1的yolo.cfg文件中:

[net]
batch=1
subdivisions=1
height=448
width=448
channels=3
momentum=0.9
decay=0.0005
saturation=1.5
exposure=1.5
hue=.1

conv24 。。。

[local]
size=3
stride=1
pad=1
filters=256
activation=leaky
[dropout]
probability=.5
[connected]
output= 1715
activation=linear

[detection]
classes=20
coords=4
rescore=1
side=7
num=3
softmax=0
sqrt=1
jitter=.2

object_scale=1
noobject_scale=.5
class_scale=1
coord_scale=5

最后一個全連接層輸出特征個數為1715,而detction層將該1715的特征向量整個為一個,\(side * side * ((coodrds + rescore) * num + classes)\)的張量。其中,\(side * side\)即為原圖中\(S * S\)的小格。為什么side位置的輸出會對應到原圖中小格的位置呢?因為訓練過程中會使用對應位置的GT監督網絡收斂,測試過程中每個小格自然對應原圖小格上目標的檢測。

預測處理過程數據的歸一化

在訓練yolo前需要先准備數據,其中有一步為:

python voc_label.py

中有個convert函數

def convert(size, box):
    dw = 1./(size[0])
    dh = 1./(size[1])
    x = (box[0] + box[1])/2.0 - 1
    y = (box[2] + box[3])/2.0 - 1
    w = box[1] - box[0]
    h = box[3] - box[2]
    x = x*dw
    w = w*dw
    y = y*dh
    h = h*dh
    return (x,y,w,h)

GT邊界框轉換為(xc, yc, w, h)的表示方式,wc, yc, w, h被歸一化到0~1之間。
再看損失函數
參見博文

1.4 YOLO缺點

  1. 對小物體及鄰近特征檢測效果差:當一個小格中出現多於兩個小物體或者一個小格中出現多個不同物體時效果欠佳。原因:B表示每個小格預測邊界框數,而YOLO默認同格子里所有邊界框為同種類物體。
    (2) 圖片進入網絡前會先進行resize為448 x 448,降低檢測速度(it takes about 10ms in 25ms),如果直接訓練對應尺寸會有加速空間。
    (3) 基礎網絡計算量較大,yolov2使用darknet-19進行加速。

1.5 實驗結論

(1) 速度更快(實時):yolo(24 convs) -> 45 fps,fast_yolo(9 convs) -> 150 fps
(2) 全圖為范圍進行檢測(而非在建議框內檢測),帶來更大的context信息,使得相對於Fast-RCNN誤檢率更低,但定位精度欠佳。

1.6 YOLO損失函數

Yolo損失函數的理解學習於潛伏在代碼中
** Loss = \(λcoord\) * 坐標預測誤差(1) + 含object的box confidence預測誤差 (2)+ $λnoobj $* 不含object的box confidence預測誤差(3) + 每個格子中類別預測誤差(4) **

\[= \]

(1) 整個損失函數針對邊界框損失(圖中1, 2, 3部分)與格子(4部分)主體進行討論。
(2) 部分1為邊界框位置與大小的損失函數,式中對寬高都進行開根是為了使用大小差別比較大的邊界框差別減小。例如,一個同樣將一個100x100的目標與一個10x10的目標都預測大了10個像素,預測框為110 x 110與20 x 20。顯然第一種情況我們還可以失道接受,但第二種情況相當於把邊界框預測大了一倍,但如果不使用根號函數,那么損失相同,都為200。但把寬高都增加根號時:

\[(sqrt(20) - sqrt(10))^2 = 3.43 \]

\[(sqrt(110) - sqrt(100))^2 = 0.48 \]

顯然,對小框預測偏差10個像素帶來了更高的損失。通過增加根號,使得預測相同偏差與更小的框產生更大的損失。但根據YOLOv2的實驗證明,還有更好的方法解決這個問題。
(3) 若有物體落入邊界框中,則計算預測邊界框含有物體的置信度\(C_{i}\)和真實物體與邊界框IoU\(\widehat{C_{i}}\)的損失,我們希望兩差值越小損失越低。
(4) 若沒有任何物體中心落入邊界框中,則\(\widehat{C_{i}}\)為0,此時我們希望預測含有物體的置信度\(C_{i}\)越小越好。然而,大部分邊界框都沒有物體,積少成多,造成loss的第3部分與第4部分的不平衡,因此,作才在loss的三部分增加權重\(\lambda_{nobj} = 0.5\)
(5) 對於每個格子而言,作者設計只能包含同種物體。若格子中包含物體,我們希望希望預測正確的類別的概率越接近於1越好,而錯誤類別的概率越接近於0越好。loss第4部分中,若\(\widehat{p_{i}(c)}\)中c為正確類別,則值為1,若非正確類別,則值為0。
參考譯文
參考潛伏在代碼中

2 YOLOv2

yolov1基礎上的延續,新的基礎網絡,多尺度訓練,全卷積網絡,Faster-RCNN的anchor機制,更多的訓練技巧等等改進使得yolov2速度與精度都大幅提升,改進效果如下圖:

2.1 BatchNorm

Batchnorm是2015年以后普遍比較流行的訓練技巧,在每一層之后加入BN層可以將整個batch數據歸一化到均值為0,方差為1的空間中,即將所有層數據規范化,防止梯度消失與梯度爆炸,如:

\[0.9^{30} = 0.04 \]

加入BN層訓練之后效果就是網絡收斂更快,並且效果更好。YOLOv2在加入BN層之后mAP上升2%。
關於BN作用

2.2 預訓練尺寸

yolov1也在Image-Net預訓練模型上進行fine-tune,但是預訓練時網絡入口為224 x 224,而fine-tune時為448 x 448,這會帶來預訓練網絡與實際訓練網絡識別圖像尺寸的不兼容。yolov2直接使用448 x 448的網絡入口進行預訓練,然后在檢測任務上進行訓練,效果得到3.7%的提升。

2.3 更細網絡划分

yolov2為了提升小物體檢測效果,減少網絡中pooling層數目,使最終特征圖尺寸更大,如輸入為416 x 416,則輸出為13 x 13 x 125,其中13 x 13為最終特征圖,即原圖分格的個數,125為每個格子中的邊界框構成(5 x (classes + 5))。需要注意的是,特征圖尺寸取決於原圖尺寸,但特征圖尺寸必須為奇數,以此保存中間有一個位置能看到原圖中心處的目標。

2.4 全卷積網絡

為了使網絡能夠接受多種尺寸的輸入圖像,yolov2除去了v1網絡結構中的全連層,因為全連接層必須要求輸入輸出固定長度特征向量。將整個網絡變成一個全卷積網絡,能夠對多種尺寸輸入進行檢測。同時,全卷積網絡相對於全連接層能夠更好的保留目標的空間位置信息。

2.5 新基礎網絡

下圖為不同基礎網絡結構做分類任務所對就的計算量,橫坐標為做一次前向分類任務所需要的操作數目。可以看出作者所使用的darknet-19作為基礎預訓練網絡(共19個卷積層),能在保持高精度的情況下快速運算。而SSD使用的VGG-16作為基礎網絡,VGG-16雖然精度與darknet-19相當,但運算速度慢。關於darknet-19基礎網絡速度

2.6 anchor機制

yolov2為了提高精度與召回率,使用Faster-RCNN中的anchor機制。以下為我對anchor機制使用的理解:在每個網格設置k個參考anchor,訓練以GT anchor作為基准計算分類與回歸損失。測試時直接在每個格子上預測k個anchor box,每個anchor box為相對於參考anchor的offset與w,h的refine。這樣把原來每個格子中邊界框位置的全圖回歸(yolov1)轉換為對參考anchor位置的精修(yolov2)。
至於每個格子中設置多少個anchor(即k等於幾),作者使用了k-means算法離線對voc及coco數據集中目標的形狀及尺度進行了計算。發現當k = 5時並且選取固定5比例值的時,anchors形狀及尺度最接近voc與coco中目標的形狀,並且k也不能太大,否則模型太復雜,計算量很大。

2.7 新邊界框預測方式

這部分沒有看太懂,先占個坑,等以后明白了再來補,感覺應該是在彌補大小邊界框回歸誤差損失的問題吧。這里發現有篇博文對這部分講得挺仔細的。

2.8 殘差層融合低級特征

為了使用網絡能夠更好檢測小物體,作者使用了resnet跳級層結構,網絡末端的高級特征層與前一層或者前幾層的低級細粒度特征結合起來,增加網絡對小物體的檢測效果,使用該方法能夠將mAP提高1%。
同樣,在SSD檢測器上也可以看出使用細粒度特征(低級特征)將進行小物體檢測的思想,但是不同的是SSD直接在多個低級特征圖上進行目標檢測,因此,SSD對於小目標檢測效果要優於YOLOv2,這點可以coco測試集上看出,因為coco上小物體比較多,但yolov2在coco上要明顯遜色於ssd,但在比較簡單的檢測數據集voc上優於ssd。

2.9 多尺寸訓練

yolov2網絡結構為全卷積網絡FCN,可以適於不同尺寸圖片作為輸入,但要滿足模型在測試時能夠對多尺度輸入圖像都有很好效果,作者訓練過程中每10個epoch都會對網絡進行新的輸入尺寸的訓練。需要注意的是,因為全卷積網絡總共對輸入圖像進行了5次下采樣(步長為2的卷積或者池化層), 所以最終特征圖為原圖的1/32。所以在訓練或者測試時,網絡輸入必須為32的位數。並且最終特征圖尺寸即為原圖划分網絡的方式
譯文參見
ref1
ref2比較明白
ref3


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM