本文逐步介紹YOLO v1~v3的設計歷程。javascript
YOLO將輸入圖像分紅SxS個格子,若某個物體 Ground truth 的中心位置的座標落入到某個格子,那麼這個格子就負責檢測出這個物體。html
每一個格子預測B個bounding box及其置信度(confidence score),以及C個類別機率。bbox信息(x,y,w,h)爲物體的中心位置相對格子位置的偏移及寬度和高度,均被歸一化.置信度反映是否包含物體以及包含物體狀況下位置的準確性,定義爲\(Pr(Object)×IOU^{truth}_{pred}\),其中\(Pr(Object)∈{0,1}\)。java
YOLOv1網絡借鑑了GoogLeNet分類網絡結構。不一樣的是,YOLO未使用inception module,而是使用1x1卷積層(此處1x1卷積層的存在是爲了跨通道信息整合)+3x3卷積層簡單替代。
YOLOv1網絡在最後使用全鏈接層進行類別輸出,所以全鏈接層的輸出維度是 \(S×S×(B×5+C)S×S×(B×5+C)\)。
YOLOv1網絡比VGG16快(浮點數少於VGG的1/3),準確率稍差。linux
缺餡:git
YOLO所有使用了均方和偏差做爲loss函數.由三部分組成:座標偏差、IOU偏差和分類偏差。github
\[ loss=∑i=0s2coordErr+iouErr+clsErrloss=∑i=0s2coordErr+iouErr+clsErr \]算法
簡單相加時還要考慮每種loss的貢獻率,YOLO給coordErr設置權重\(λ_{coord=5}\).在計算IOU偏差時,包含物體的格子與不包含物體的格子,兩者的IOU偏差對網絡loss的貢獻值是不一樣的。若採用相同的權值,那麼不包含物體的格子的confidence值近似爲0,變相放大了包含物體的格子的confidence偏差在計算網絡參數梯度時的影響。爲解決這個問題,YOLO 使用\(λ_{noobj}=0.5\)修正iouErr。(此處的‘包含’是指存在一個物體,它的中心座標落入到格子內)。對於相等的偏差值,大物體偏差對檢測的影響應小於小物體偏差對檢測的影響。這是由於,相同的位置誤差佔大物體的比例遠小於同等誤差佔小物體的比例。YOLO將物體大小的信息項(w和h)進行求平方根來改進這個問題,但並不能徹底解決這個問題。數組
綜上,YOLO在訓練過程當中Loss計算以下式所示:網絡
其中有寶蓋帽子符號\((\hat{x},\hat{y},\hat{w},\hat{h},\hat{C},\hat{p})\)爲預測值,無帽子的爲訓練標記值。\(\mathbb 1_{ij}^{obj}\)表示物體落入格子i的第j個bbox內.若是某個單元格中沒有目標,則不對分類偏差進行反向傳播;B個bbox中與GT具備最高IoU的一個進行座標偏差的反向傳播,其他不進行.app
1)預訓練。使用 ImageNet 1000 類數據訓練YOLO網絡的前20個卷積層+1個average池化層+1個全鏈接層。訓練圖像分辨率resize到224x224。
2)用步驟1)獲得的前20個卷積層網絡參數來初始化YOLO模型前20個卷積層的網絡參數,而後用 VOC 20 類標註數據進行YOLO模型訓練。檢測一般須要有細密紋理的視覺信息,因此爲提升圖像精度,在訓練檢測模型時,將輸入圖像分辨率從224 × 224 resize到448x448。
訓練時B個bbox的ground truth設置成相同的.
YOLO與Fast R-CNN相比有較大的定位偏差,與基於region proposal的方法相比具備較低的召回率。可是,YOLO在定位識別背景時準確率更高,而 Fast-R-CNN 的假陽性很高。基於此做者設計了 Fast-R-CNN + YOLO 檢測識別模式,即先用R-CNN提取獲得一組bounding box,而後用YOLO處理圖像也獲得一組bounding box。對比這兩組bounding box是否基本一致,若是一致就用YOLO計算獲得的機率對目標分類,最終的bouding box的區域選取兩者的相交區域。這種組合方式將準確率提升了3個百分點。
爲提升物體定位精準性和召回率,YOLO做者提出了 《YOLO9000: Better, Faster, Stronger》 (Joseph Redmon, Ali Farhadi, CVPR 2017, Best Paper Honorable Mention),相比v1提升了訓練圖像的分辨率;引入了faster rcnn中anchor box的思想,對網絡結構的設計進行了改進,輸出層使用卷積層替代YOLO的全鏈接層,聯合使用coco物體檢測標註數據和imagenet物體分類標註數據訓練物體檢測模型。相比YOLO,YOLO9000在識別種類、精度、速度、和定位準確性等方面都有大大提高。
YOLO與Fast R-CNN相比有較大的定位偏差,與基於region proposal的方法相比具備較低的召回率。所以YOLO v2主要改進是提升召回率和定位能力。下面是改進之處:
Batch Normalization: v1中也大量用了Batch Normalization,同時在定位層後邊用了dropout,v2中取消了dropout,在卷積層所有使用Batch Normalization。
高分辨率分類器:v1中使用224 × 224訓練分類器網絡,擴大到448用於檢測網絡。v2將ImageNet以448×448 的分辨率微調最初的分類網絡,迭代10 epochs。
Anchor Boxes:v1中直接在卷積層以後使用全鏈接層預測bbox的座標。v2借鑑Faster R-CNN的思想預測bbox的偏移.移除了全鏈接層,而且刪掉了一個pooling層使特徵的分辨率更大一些.另外調整了網絡的輸入(448->416)以使得位置座標是奇數只有一箇中心點(yolo使用pooling來下采樣,有5個size=2,stride=2的max pooling,而卷積層沒有下降大小,所以最後的特徵是\(416/(2^5)=13\)).v1中每張圖片預測7x7x2=98個box,而v2加上Anchor Boxes能預測超過1000個.檢測結果從69.5mAP,81% recall變爲69.2 mAP,88% recall.
YOLO v2對Faster R-CNN的手選先驗框方法作了改進,採樣k-means在訓練集bbox上進行聚類產生合適的先驗框.因爲使用歐氏距離會使較大的bbox比小的bbox產生更大的偏差,而IOU與bbox尺寸無關,所以使用IOU參與距離計算,使得經過這些anchor boxes得到好的IOU分值。距離公式:
\[D(box,centroid)=1−IOU(box,centroid)\]
使用聚類進行選擇的優點是達到相同的IOU結果時所需的anchor box數量更少,使得模型的表示能力更強,任務更容易學習.k-means算法代碼實現參考:k_means_yolo.py.算法過程是:將每一個bbox的寬和高相對整張圖片的比例(wr,hr)進行聚類,獲得k個anchor box,因爲darknet代碼須要配置文件中region層的anchors參數是絕對值大小,所以須要將這個比例值乘上卷積層的輸出特徵的大小.如輸入是416x416,那麼最後卷積層的特徵是13x13.
細粒度特徵(fine grain features):在Faster R-CNN 和 SSD 均使用了不一樣的feature map以適應不一樣尺度大小的目標.YOLOv2使用了一種不一樣的方法,簡單添加一個 pass through layer,把淺層特徵圖(26x26)鏈接到深層特徵圖(鏈接到新加入的三個卷積核尺寸爲3 * 3的卷積層最後一層的輸入)。 經過疊加淺層特徵圖相鄰特徵到不一樣通道(而非空間位置),相似於Resnet中的identity mapping。這個方法把26x26x512的特徵圖疊加成13x13x2048的特徵圖,與原生的深層特徵圖相鏈接,使模型有了細粒度特徵。此方法使得模型的性能得到了1%的提高。
Multi-Scale Training: 和YOLOv1訓練時網絡輸入的圖像尺寸固定不變不一樣,YOLOv2(在cfg文件中random=1時)每隔幾回迭代後就會微調網絡的輸入尺寸。訓練時每迭代10次,就會隨機選擇新的輸入圖像尺寸。由於YOLOv2的網絡使用的downsamples倍率爲32,因此使用32的倍數調整輸入圖像尺寸{320,352,…,608}。訓練使用的最小的圖像尺寸爲320 x 320,最大的圖像尺寸爲608 x 608。 這使得網絡能夠適應多種不一樣尺度的輸入.
YOLOv2對v1的基礎網絡作了更改.
分類網絡
YOLOv2提出了一種新的分類模型Darknet-19.借鑑了不少其它網絡的設計概念.主要使用3x3卷積並在pooling以後channel數加倍(VGG);global average pooling替代全鏈接作預測分類,並在3x3卷積之間使用1x1卷積壓縮特徵表示(Network in Network);使用 batch normalization 來提升穩定性,加速收斂,對模型正則化.
Darknet-19的結構以下表:
Darknet-19-arch
包含 19 conv + 5 maxpooling.
訓練:使用Darknet框架在ImageNet 1000類上訓練160 epochs,學習率初始爲0.1,以4級多項式衰減.weight decay=0.0005 , momentum=0.9.使用標準的數據增廣方法:random crops, rotations, (hue, saturation), exposure shifts.
以後將輸入從224放大至448,學習率調整爲0.001,迭代10 epochs.結果達到top-1 accuracy 76.5% , top-5 accuracy 93.3%.
檢測網絡
在分類網絡中移除最後一個1x1的層,在最後添加3個3x3x1024的卷積層,再接上輸出是類別個數的1x1卷積.
對於輸入圖像尺寸爲Si x Si
,最終3x3卷積層輸出的feature map是Oi x Oi
(Oi=Si/(2^5)),對應輸入圖像的Oi x Oi個柵格,每一個柵格預測#anchors
種boxes大小,每一個box包含4個座標值,1個置信度和#classes
個條件類別機率,因此輸出維度是Oi x Oi x #anchors x (5 + #classes)
。
添加跨層跳躍鏈接(借鑑ResNet等思想),融合粗細粒度的特徵:將前面最後一個3x3x512卷積的特徵圖,對於416x416的輸入,該層輸出26x26x512,直接鏈接到最後新加的三個3x3卷積層的最後一個的前邊.將26x26x512變形爲13x13x1024與後邊的13x13x1024特徵按channel堆起來獲得13x13x3072.從yolo-voc.cfg文件能夠看到,第25層爲route層,逆向9層拿到第16層26 * 26 * 512的輸出,並由第26層的reorg層把26 * 26 * 512 變形爲13 * 13 * 2048,再有第27層的route層鏈接24層和26層的輸出,堆疊爲13 * 13 * 3072,由最後一個卷積核爲3 * 3的卷積層進行跨通道的信息融合並把通道降維爲1024。
訓練:做者在VOC07+12以及COCO2014數據集上迭代了160 epochs,初始學習率0.001,在60和90 epochs分別減少爲0.1倍.
Darknet訓練VOC的參數以下:
learning_rate=0.0001 batch=64 max_batches = 45000 # 最大迭代batch數 policy=steps # 學習率衰減策略 steps=100,25000,35000 # 訓練到這些batch次數時learning_rate按scale縮放 scales=10,.1,.1 # 與steps對應
網絡結構以下(輸入416,5個類別,5個anchor box; 此結構信息由Darknet框架啓動時輸出):
提出了一種聯合訓練方法,可以允許同時使用目標檢測數據集和分類數據集。使用有標記的檢測數據集精肯定位,使用分類數據增長類別和魯棒性。
YOLOv3在Pascal Titan X上處理608x608圖像速度達到20FPS,在 COCO test-dev 上 mAP@0.5 達到 57.9%,與RetinaNet(FocalLoss論文所提出的單階段網絡)的結果相近,而且速度快4倍.
YOLO v3的模型比以前的模型複雜了很多,能夠經過改變模型結構的大小來權衡速度與精度。
速度對好比下:
改進之處:
分類器-類別預測:
YOLOv3不使用Softmax對每一個框進行分類,主要考慮因素有兩個:
Open Images
這種數據集,目標可能有重疊的類別標籤,所以Softmax不適用於多標籤分類。多尺度預測
每種尺度預測3個box, anchor的設計方式仍然使用聚類,獲得9個聚類中心,將其按照大小均分給3中尺度.
參見網絡結構定義文件yolov3.cfg
基礎網絡 Darknet-53
仿ResNet, 與ResNet-101或ResNet-152準確率接近,但速度更快.對好比下:
網絡結構以下:
YOLOv3在 mAP0.5mAP0.5 及小目標 APSAPS 上具備不錯的結果,但隨着IOU的增大,性能降低,說明YOLOv3不能很好地與ground truth切合.
邊框預測
做者嘗試了常規的預測方式(Faster R-CNN),然而並不奏效: x,y的偏移做爲box的長寬的線性變換.
\[ \begin{cases} \widehat{G_x}=P_wt_x(P)+P_x \\ \widehat{G_y}=P_ht_y(P)+P_y \\ \widehat{G_w}=P_we^{t_w(P)} \\ \widehat{G_h}=P_he^{t_h(P)} \end{cases} \]
仍採用以前的logistic方式:
\[ \begin{align} b_x &= σ(t_x)+c_x \\ b_y &= σ(t_y)+c_y \\ b_w &= p_we^{t_w} \\ b_h &= p_he^{t_h} \end{align} \]
其中\(c_x,c_y\)是網格的座標偏移量,\(p_w,p_h\)是預設的anchor box的邊長.最終獲得的邊框座標值是\(b_{x,y,w,h}\),而網絡學習目標是\(t_{x,y,w,h}\).
優勢
但相比RCNN系列物體檢測方法,YOLO具備如下缺點:
Darknet 由 C 語言和 CUDA 實現, 對GPU顯存利用效率較高(CPU速度差一些, 經過與SSD的Caffe程序對比發現存在CPU較慢,GPU較快的狀況). Darknet 對第三方庫的依賴較少,且僅使用了少許GNU linux平臺C接口,所以很容易移植到其它平臺,如Windows或嵌入式設備.
參考Windows 版 Darknet (YOLOv2) 移植, 代碼在此.
region層:參數anchors指定kmeans計算出來的anchor box的長寬的絕對值(與網絡輸入大小相關),num參數爲anchor box的數量,
另外還有bias_match,classes,coords等參數.在parser.c代碼中的parse_region函數中解析這些參數,並保存在region_layer.num參數保存在l.n變量中;anchors保存在l.biases數組中.region_layer的前向傳播中使用for(n = 0; n < l.n; ++n)這樣的語句,所以,若是在配置文件中anchors的數量大於num時,僅使用前num個,小於時內存越界.
region層的輸入和輸出大小與前一層(1x1 conv)的輸出大小和網絡的輸入大小相關.
Detection層: 座標及類別結果輸出層.
yolo層: 指定anchors等信息, 計算loss等. YOLOv3使用三個yolo層做爲輸出.
upsample層: 上採樣層, 進行2倍上採樣.
region層和Detection層均是YOLOv2模型所使用的層, upsample層和yolo層在YOLOv3中使用.
鑑於 Darknet 做者率性的代碼風格, 將它做爲咱們本身的開發框架並不是是一個好的選擇. 能夠在咱們更爲熟悉的Caffe等框架中復現YOLO網絡. 這裏有一份Caffe版YOLOv3實現(僅部署,不能訓練), 另可參照其它框架的可訓練代碼.
參考
原文: https://www.cnblogs.com/makefile/p/YOLOv3.html © 康行天下