深度剖析YOLO系列的原理

                      深度剖析YOLO系列的原理

                      本文系作者原創,轉載請註明出處:https://www.cnblogs.com/further-further-further/p/12072225.html

目錄

1. YOLO的作用

2. YOLO(v1,v2,v3)的技術演化

 


 

 

 

1. YOLO的作用

yolo是當前目標檢測最頂級的算法之一,v1版本是2016年提出來的,v2是2017年提出來的,v3是2018年提出的。

官網地址:https://pjreddie.com/darknet/yolo/

說它最牛掰,有兩點:

一是因爲它採用深層卷積神經網絡,吸收了當前很多經典卷積神經網絡架構的優秀思想,在位置檢測和對象的識別方面,

性能達到最優(準確率非常高的情況下還能達到實時檢測)。

二是因爲作者還將代碼開源了。真心爲作者這種大公無私的心胸點贊。

美中不足的是:作者雖然將代碼開源,但是在論文介紹架構原理的時候比較模糊,特別是對一些重要改進,基本上是一筆帶過。

現在在網絡上有很多關於YOLO原理的講解,個人感覺講得不是很清楚,總感覺有點知其然而不知其所以然。比如:

yolo是在什麼背景下出現的?

v1是在哪個經典網絡架構上發展起來的?解決了什麼問題?又存在什麼問題?

v2針對v1的缺點做了哪些改進?改進後效果怎麼樣?又存在什麼問題?

v3針對v2的缺點做了哪些改進?

這些問題不搞清楚,我覺得對yolo就談不上真正的理解。廢話不多說,下面就來介紹yolo的技術演進。

 

2. YOLO(v1,v2,v3)的技術演化

問題1:yolo v1是在什麼背景下出現的?

yolo v1是在 R-CNN 基礎上發展起來的。

R-CNN(region proposals + cnn),採用卷積神經網絡進行目標檢測的開山之作。

 

 

主要思想:對輸入圖片採用selective search 搜索查詢算法,提取出大約 2000 個人眼感興趣的候選邊框,然後每個邊框都通過一個獨立的

卷積神經網絡進行預測輸出,後面再加上一個SVM(支持向量機)預測分類。

優點:位置檢測與對象分類準確率非常高。

缺點:運算量大,檢測速度非常慢,在 GPU 加持下一幀檢測時間要 13s 左右,這在工程應用上是不可接受的。

造成速度慢的原因主要有 2 個:

> 用搜索查詢算法提取 2000 個候選邊框

> 每個候選邊框都採用一個獨立的CNN通道,這意味着卷積核的參數和全連接的參數都是不一樣的,總的參數個數是非常恐怖的。

針對這個缺點,yolo v1做了哪些改進呢。

 

 

上面的圖片是官網論文給出的結構圖,但是個人感覺畫得不太好,它容易讓人誤認爲對輸入圖片進行網格化處理,每個網格化的小窗口是 7*7。

真實情況是,由最終輸出是 7*7*30 大小代表的物理含義是:你可以把輸入圖片看成是經過了網格化(grid cell 7*7),每個網格化後的小窗口通過 CNN 預測出 1*30。

這裏可能有點不好理解。總之一句話,在真正網絡架構流程中,沒有對輸入圖片進行任何網格化處理。

 

v1 改進點:

> Backbone: googLeNet22 (採用googLeNet22層卷積結構)

> 輸入圖片只處理一次(yolo名稱的由來),通過多個卷積層提取不同的特徵,每次卷積的時候共享卷積核參數。

輸入圖片只處理一次:表示輸入圖片只在第一次卷積的時候作爲輸入進行卷積運算,第一次卷積後的輸出作爲第二次卷積的輸入,通過多個卷積層遞進的方式來提取不同的特徵。

並且這些特徵通過的CNN通道都是相同的,從而可以共享卷積核參數。

> 每個 3*3 卷積核前面引入了 1*1 卷積核,作用有兩個,一是提取更豐富的特徵,二是減少卷積核的參數個數。

大家可能對減少卷積核參數個數的作用比較難以理解,這裏舉個例子。

比如輸入圖片大小是 56*56*256 最終轉化的目標大小是 28*28*512。

直接卷積:56*56*256 & 3*3*256*512 -> 56*56*512 & pooling -> 28*28*512 

卷積核參數:3*3*256*512 = 1179648

引入 1*1 卷積:56*56*256 & 1*1*256*128 -> 56*56*128 & 3*3*128*512 -> 56*56*512 & pooling -> 28*28*512

卷積核參數:1*1*256*128 + 3*3*128*512 = 622592

經過改進後,圖片檢測速度非常快,基本上可以達到實時。但是缺點是位置檢測準確度低,並且不能檢測出小對象物體。

針對 v1 的缺點,v2做了哪些改進呢?

v2 改進點:

 

 

 

 

> Backbone:darknet19 (採用darknet 19層卷積結構)

> 輸入圖片批歸一化處理(BN),作用是降低不是重要特徵的重要性。

這句話可能聽得有點暈,舉個例子,

你的樣本里有兩個特徵列,一個特徵列的數值在[1,10]範圍內,另一個特徵列的數值在[1000,10000]範圍內,

但是真實情況是,你的這兩個特徵列重要性可能是一樣的,只不過你拿到的數據就是這樣的,我們知道,

卷積神經網絡訓練,實質就是一系列數值運算的過程,如果你將這兩個特徵列直接通過卷積神經網絡進行訓練,

那最終生成的模型準確率肯定是不高的,所以需要進行歸一化處理,將數值歸一化到[0,1]範圍內,

從而是損失能量在收斂的時候更加平穩。

> 採用passthrough算法,解決池化信息丟失的問題,增加細粒度特徵的檢測(小對象)。

 

 

passthrough 算法主要是爲了解決 pooling(池化)的缺點,不管是最大值池化,還是平均值池化,都有一個很明顯的問題,

就是會造成信息丟失,passthrough 主要思想是在池化之前,將輸入信息進行拆分,一拆爲四,經過拆分後的大小就和池化後的輸出大小相同,

然後疊加,疊加後的結果主要就是維度變化,這樣就能解決池化會造成信息丟失的問題。

> 去掉全連接(FC),將輸入圖片拉伸(resize)到不同尺寸然後通過卷積神經網絡,這樣就得到了多尺寸的輸出,從而能提升對不同大小對象的預測準確度。

全連接其實就是矩陣乘法運算,矩陣乘法有一個前提,矩陣 A 的列必須與矩陣 B 的行個數相同,否則是不能進行矩陣乘法運算的。

全連接的參數大小是固定的,那麼你的輸入大小自然就固定了,這樣就無法實現多尺寸的輸出,所以這裏去掉了全連接層。

經過改進後,精度提升明顯,特別是對小對象的檢測,缺點是對小對象檢測準確度不高。

針對 v2 的缺點,v3 又做了哪些改進呢?

v3 改進點:

 

 

上面是 v3 的結構圖,是我跟蹤代碼,查找資料,繪製這張圖真心不容易,正確性絕對有保證,大家如果覺得這張圖對你理解 yolo 有幫助,麻煩點個贊。

輸入大小這裏是416*416,輸出13*13,26*26,52*52,這裏一般要求輸入圖片大小是 32 的倍數,因爲整個卷積神經網絡會將圖片縮小32倍,16倍,8倍,

這裏取最大公倍數32。 123 = 3*(邊框座標 4 + 置信度 1 + 類對象 36)。

> Backbone: darknet53 (採用darknet 53層卷積結構,實際是52層卷積,去掉了全連接層)

可以看出v3的卷積層數是v2的2.8倍,有個潛在的共識:增加模型準確率的一個直接做法是增加網絡的深度和厚度,

(深度是指卷積層數,厚度指卷積核的維度或者是種類數),這裏作用自然就是提升精度了。

> 用卷積取代池化

之前我們提到過池化的問題,會造成信息丟失,這裏用卷積來實現池化的功能(使圖片大小縮小2倍),同時不會造成信息的明顯丟失。

> 採用殘差網絡(resnet)防止梯度消失

梯度消失或者梯度爆炸是在深層的卷積神經網絡中才有可能出現的,梯度的計算是通過鏈式求導得到的,隨着網絡層的增加,鏈式求導項就會越來越長,

因爲在每一層卷積後的輸出都做了歸一化處理,所以梯度只會越來越小,有可能爲0,而0在後面模塊運算中都爲0,這樣導致的直接後果是:

損失能量在收斂到某一階段後就停止收斂,最後生成模型的精度自然就不高。而這裏採用殘差網絡就能防止梯度消失,v3結構圖裏左下角就是殘差網絡的結構圖。

殘差網絡的思想:每次卷積後的輸出當做殘差,將卷積前的輸入與殘差融合,作爲整個輸出,即使殘差爲0,整個輸出也不會爲0。

從殘差網絡結構圖可以看出,每個3*3卷積核前都引入了1*1卷積,這裏沿用了v1的思想。

從v3的結構圖可以看出,darknet53網絡骨架裏大量的引入了殘差網絡的思想。

> 使用空間金字塔池化網絡算法(sppnet spatial pyramid pooling)實現多尺寸的輸出

空間金字塔池化網絡算法主要思想:不同尺寸的輸入通過sppnet模塊後生成一個固定尺寸的輸出。

在v3結構圖裏,有兩個地方用到這個思想:

一個是 13*13*512 經過 1*1 卷積,改變特徵維度,變成 13*13*256,經過上採樣(upsample,這裏採用相鄰像素插入算法),

改變特徵尺寸,變成 26*26*256,然後與 26*26*512 疊加,生成 26*26*768。

另一個是 26*26*256 與 52*52*256 疊加後生成 52*52*384。

v3的多尺寸輸出與v2的多尺寸輸出有本質不同,v2多尺寸輸出是對輸入圖片拉伸到不同的尺寸,然後通過卷積神經網絡得到不同的輸出,

但是這樣就存在一個圖片失真的問題,因爲你是對圖片進行的拉伸處理。而v3通過sppnet實現的多尺寸輸出,就能有效避免圖片失真的問題。

> 13*13*123,26*26*123,52*52*123物理意義

 

 

這裏用v1版本論文圖片來解釋,物理意義:

表示將輸入圖片網格化,有 13*13,26*26,52*52 大小,每個網格化的小窗口(grid cell)預測 3 個邊框(bounding box),

每個邊框包含 4 個位置座標,1個置信度,36個對象種類。

123 = 3 *(4 + 1 + 36)

這裏就存在一個問題:預測輸出如此之多,直接用於損失能量的計算,運算量豈不是很恐怖?

確實是這樣,所以這裏先經過下面的兩個步驟的處理:

(1)每個小窗口只取置信度最大的邊框,因爲yolo規定,只能有一個真實的對象中心座標屬於每個小窗口。

    這樣,就得出 13*13*3*41 => 13*13*41,26*26*3*41 => 26*26*41,52*52*3*41 => 52*52*41

    13*13*41,26*26*41,52*52*41 表示一個真實對象有很多預測重疊邊框,比如說上面圖裏屬於狗的預測邊框非常多,

    但是我們只需要預測最準確的邊框,去掉其他屬於狗的重疊邊框。

(2)採用NMS(非極大值抑制算法)去除重疊邊框。

     這樣 13*13*41,26*26*41,52*52*41 => N*41 (N表示不同對象預測數目,比如說上面圖理想情況下,N = 3)。

> 損失能量(採用交叉熵)

     

 

 

損失能量的計算是v1版本提出來的,這裏放到了v3來說,有3個改進點:

(1)將位置檢測與對象識別作爲一個整體,進行訓練預測,這從損失能量的計算可以直接反應出來。

(2)位置的寬度和高度先開根號,與歸一化的作用相同,降低不是重要特徵的重要性。

(3)增加權重參數  ,當邊框預測出含有對象時,增大它的權重值,當邊框預測出不含有對象時,減小它的權重值,這樣就能使損失能量計算更準確。

 

 

不要讓懶惰佔據你的大腦,不要讓妥協拖垮了你的人生。青春就是一張票,能不能趕上時代的快車,你的步伐就掌握在你的腳下。

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