Ⅰ 目標檢測 YOLO系列——YOLO v1
YOLO v1:You Only Look Once: Unified, Real-Time Object Detection
YOLO v2:YOLO9000:Better,Faster,Stronger
YOLO v3:YOLOv3: An Incremental Improvement
近幾年來,目標檢測演算法取得了很大的突破。比較流行的演算法可以分為兩類,一類是基於Region Proposal的R-CNN系演算法(R-CNN,Fast R-CNN, Faster R-CNN),它們是two-stage的,需要先使用啟發式方法(selective search)或者CNN網路(RPN)產生Region Proposal,然後再在Region Proposal上做分類與回歸。而另一類是Yolo,SSD這類one-stage演算法,其僅僅使用一個CNN網路直接預測不同目標的類別與位置。第一類方法是准確度高一些,但是速度慢,但是第二類演算法是速度快,但是准確性要低一些。這里我們談的是Yolo-v1版本演算法,其性能是差於後來的SSD演算法的,但是Yolo後來也繼續進行改進,產生了Yolo9000、YOLO v3演算法。
傳統方法常採用滑動窗口法,滑動窗口的目標檢測演算法思路非常簡單,它將檢測問題轉化為了圖像分類問題。其基本原理就是採用不同大小和比例(寬高比)的窗口在整張圖片上以一定的步長進行滑動,然後對這些窗口對應的區域做圖像分類,這樣就可以實現對整張圖片的檢測了,如 DPM 就是採用這種思路。但是這個方法有致命的缺點,就是你並不知道要檢測的目標大小是什麼規模,所以你要設置不同大小和比例的窗口去滑動,而且還要選取合適的步長。但是這樣會產生很多的子區域,並且都要經過分類器去做預測,這需要很大的計算量,所以你的分類器不能太復雜,因為要保證速度。解決思路之一就是減少要分類的子區域,這就是R-CNN的一個改進策略,其採用了 selective search 方法來找到最有可能包含目標的子區域(Region Proposal),其實可以看成採用啟發式方法過濾掉很多子區域,這會提升效率。
如果你使用的是CNN分類器,那麼滑動窗口是非常耗時的。但是結合卷積運算的特點,我們可以使用CNN實現更高效的滑動窗口方法。這里要介紹的是一種全卷積的方法,簡單來說就是網路中用卷積層代替了全連接層,如圖所示。輸入圖片大小是16x16,經過一系列卷積操作,提取了2x2的特徵圖,但是這個2x2的圖上每個元素都是和原圖是一一對應的,如圖上藍色的格子對應藍色的區域,這不就是相當於在原圖上做大小為14x14的窗口滑動,且步長為2,共產生4個字區域。最終輸出的通道數為4,可以看成4個類別的預測概率值,這樣一次CNN計算就可以實現窗口滑動的所有子區域的分類預測。這其實是overfeat演算法的思路。之所可以CNN可以實現這樣的效果是因為卷積操作的特性,就是圖片的空間位置信息的不變性,盡管卷積過程中圖片大小減少,但是位置對應關系還是保存的。這個思路也被R-CNN借鑒,從而誕生了Fast R-cNN演算法。
上面盡管可以減少滑動窗口的計算量,但是只是針對一個固定大小與步長的窗口,這是遠遠不夠的。Yolo演算法很好的解決了這個問題,它不再是窗口滑動了,而是直接將原始圖片分割成互不重合的小方塊,然後通過卷積最後生產這樣大小的特徵圖,基於上面的分析,可以認為特徵圖的每個元素也是對應原始圖片的一個小方塊,然後用每個元素來可以預測那些中心點在該小方格內的目標,這就是Yolo演算法的樸素思想。
整體來看,Yolo演算法採用一個單獨的CNN模型實現end-to-end的目標檢測,整個系統如圖所示:首先將輸入圖片resize到448x448,然後送入CNN網路,最後處理網路預測結果得到檢測的目標。相比R-CNN演算法,其是一個統一的框架,其速度更快,而且Yolo的訓練過程也是end-to-end的。
具體來說,Yolo的CNN網路將輸入的圖片分割成 網格,然後每個單元格負責去檢測那些中心點落在該格子內的目標,如圖所示,可以看到狗這個目標的中心落在左下角一個單元格內,那麼該單元格負責預測這個狗。每個單元格會預測B個邊界框(bounding box)以及邊界框的 置信度 (confidence score)。所謂置信度其實包含兩個方面,一是這個邊界框含有目標的可能性大小,二是這個邊界框的准確度。前者記為 ,當該邊界框是背景時(即不包含目標),此時 。而當該邊界框包含目標時, 。邊界框的准確度可以用預測框與實際框(ground truth)的 IOU (intersection over union,交並比)來表徵,記為 IOU 。因此置信度可以定義為 。
很多人可能將Yolo的置信度看成邊界框是否含有目標的概率,但是其實它是兩個因子的乘積,預測框的准確度也反映在裡面。邊界框的大小與位置可以用4個值來表徵:(x,y,h,w),其中(x,y)是邊界框的中心坐標,而w和h是邊界框的寬與高。還有一點要注意,中心坐標的預測值(x,y)是相對於每個單元格左上角坐標點的偏移值,並且單位是相對於單元格大小的,單元格的坐標定義如圖所示。而邊界框的w和h預測值是相對於整個圖片的寬與高的比例,這樣理論上4個元素的大小應該在[0,1]范圍。這樣,每個邊界框的預測值實際上包含5個元素:(x,y,w,h,c),其中前4個表徵邊界框的大小與位置,而最後一個值是置信度。
值得注意的是,不管一個單元格預測多少個邊界框,其只預測一組類別概率值,這是Yolo演算法的一個缺點,在後來的改進版本中,Yolo9000是把類別概率預測值與邊界框是綁定在一起的。同時,我們可以計算出各個邊界框類別置信度(class-specificconfidence scores):
邊界框類別置信度表徵的是該邊界框中目標屬於各個類別的可能性大小以及邊界框匹配目標的好壞。後面會說,一般會根據類別置信度來過濾網路的預測框。
總結一下,每個單元格需要預測 個值。如果將輸入圖片劃分為 網格,那麼最終預測值為 大小的張量。整個模型的預測值結構如下圖所示。對於PASCALVOC數據,其共有20個類別,如果使用S=7,B=2,那麼最終的預測結果就是 大小的張量。在下面的網路結構中我們會詳細講述每個單元格的預測值的分布位置。
Yolo採用卷積網路來提取特徵,然後使用全連接層來得到預測值。網路結構參考GooLeNet模型,包含24個卷積層和2個全連接層,如圖所示。對於卷積層,主要使用1x1卷積來做channle rection,然後緊跟3x3卷積。對於卷積層和全連接層,採用Leaky ReLU激活函數:max(x,0)。但是最後一層卻採用線性激活函數。除了上面這個結構,文章還提出了一個輕量級版本Fast Yolo,其僅使用9個卷積層,並且卷積層中使用更少的卷積核。
可以看到網路的最後輸出為 大小的張量。這和前面的討論是一致的。這個張量所代表的具體含義如圖所示。對於每一個單元格,前20個元素是類別概率值,然後2個元素是邊界框置信度,兩者相乘可以得到類別置信度,最後8個元素是邊界框的(x,y,w,h)。大家可能會感到奇怪,對於邊界框為什麼把置信度c和(x,y,w,h)都分開排列,而不是按照(x,y,w,h,c)這樣排列,其實純粹是為了計算方便,因為實際上這30個元素都是對應一個單元格,其排列是可以任意的。但是分離排布,可以方便地提取每一個部分。這里來解釋一下,首先網路的預測值是一個二維張量P,其shape為 。
採用切片,那麼 就是類別概率部分; 是置信度部分; 是邊界框的預測結果。這樣,提取每個部分是非常方便的,這會方面後面的訓練及預測時的計算。
在訓練之前,先在ImageNet上進行了預訓練,其預訓練的分類模型採用圖中前20個卷積層,然後添加一個average-pool層和全連接層。預訓練之後,在預訓練得到的20層卷積層之上加上隨機初始化的4個卷積層和2個全連接層。由於檢測任務一般需要更高清的圖片,所以將網路的輸入從224x224增加到了448x448。整個網路的流程如下圖所示:
損失函數計算如下:
其中第一項是邊界框中心坐標的誤差項, 指的是第i個單元格存在目標,且該單元格中的第j個邊界框負責預測該目標。第二項是邊界框的高與寬的誤差項。第三項是包含目標的邊界框的置信度誤差項。第四項是不包含目標的邊界框的置信度誤差項。而最後一項是包含目標的單元格的分類誤差項, 指的是第i個單元格存在目標。
在說明Yolo演算法的預測過程之前,這里先介紹一下非極大值抑制演算法(non maximum suppression, NMS),這個演算法不單單是針對Yolo演算法的,而是所有的檢測演算法中都會用到。NMS演算法主要解決的是一個目標被多次檢測的問題,如圖中人臉檢測,可以看到人臉被多次檢測,但是其實我們希望最後僅僅輸出其中一個最好的預測框,比如對於美女,只想要紅色那個檢測結果。那麼可以採用NMS演算法來實現這樣的效果:首先從所有的檢測框中找到置信度最大的那個框,然後挨個計算其與剩餘框的IOU,如果其值大於一定閾值(重合度過高),那麼就將該框剔除;然後對剩餘的檢測框重復上述過程,直到處理完所有的檢測框。
下面就來分析Yolo的預測過程,這里我們不考慮batch,認為只是預測一張輸入圖片。根據前面的分析,最終的網路輸出是 ,但是我們可以將其分割成三個部分:類別概率部分為 ,置信度部分為 ,而邊界框部分為 (對於這部分不要忘記根據原始圖片計算出其真實值)。然後將前兩項相乘可以得到 類別置信度值為 ,這里總共預測了 邊界框。
所有的准備數據已經得到了,那麼先說第一種策略來得到檢測框的結果。首先,對於每個預測框根據類別置信度選取置信度最大的那個類別作為其預測標簽,經過這層處理我們得到各個預測框的預測類別及對應的置信度值,其大小都是[7,7,2]。一般情況下,會設置置信度閾值,就是將置信度小於該閾值的box過濾掉,所以經過這層處理,剩餘的是置信度比較高的預測框。最後再對這些預測框使用NMS演算法,最後留下來的就是檢測結果。一個值得注意的點是NMS是對所有預測框一視同仁,還是區分每個類別,分別使用NMS。Ng在deeplearning.ai中講應該區分每個類別分別使用NMS,但是看了很多實現,其實還是同等對待所有的框,可能是不同類別的目標出現在相同位置這種概率很低吧。
上面的預測方法應該非常簡單明了,但是對於Yolo演算法,其卻採用了另外一個不同的處理思路(至少從C源碼看是這樣的),其區別就是先使用NMS,然後再確定各個box的類別。其基本過程如圖所示。對於98個boxes,首先將小於置信度閾值的值歸0,然後分類別地對置信度值採用NMS,這里NMS處理結果不是剔除,而是將其置信度值歸為0。最後才是確定各個box的類別,當其置信度值不為0時才做出檢測結果輸出。這個策略不是很直接,但是貌似Yolo源碼就是這樣做的。Yolo論文裡面說NMS演算法對Yolo的性能是影響很大的,所以可能這種策略對Yolo更好。
總結一下Yolo的優缺點。首先是優點,Yolo採用一個CNN網路來實現檢測,是單管道策略,其訓練與預測都是end-to-end,所以Yolo演算法比較簡潔且速度快。第二點由於Yolo是對整張圖片做卷積,所以其在檢測目標有更大的視野,它不容易對背景誤判。另外,Yolo的泛化能力強,在做遷移時,模型魯棒性高。
Yolo的缺點,首先Yolo各個單元格僅僅預測兩個邊界框,而且屬於一個類別。對於小物體,Yolo的表現會不如人意。這方面的改進可以看SSD,其採用多尺度單元格。也可以看Faster R-CNN,其採用了anchor boxes。Yolo對於在物體的寬高比方面泛化率低,就是無法定位不尋常比例的物體。當然Yolo的定位不準確也是很大的問題。
參考鏈接
YOLO演算法的原理與實現
https://cloud.tencent.com/developer/article/1058057
Ⅱ 淺談Yolo
學號:20021210654
姓名:潘文欣
原文鏈接: https://blog.csdn.net/xiaohu2022/article/details/79211732
https://blog.csdn.net/qq_30815237/article/details/91949543
【嵌牛導讀】
當我們談起計算機視覺時,首先想到的就是圖像分類,沒錯,圖像分類是計算機視覺最基本的任務之一,但是在圖像分類的基礎上,還有更復雜和有意思的任務,如目標檢測,物體定位,圖像分割等。其中目標檢測是一件比較實際的且具有挑戰性的計算機視覺任務,其可以看成圖像分類與定位的結合,給定一張圖片,目標檢測系統要能夠識別出圖片的目標並給出其位置,由於圖片中目標數是不定的,且要給出目標的精確位置,目標檢測相比分類任務更復雜。
近幾年來,目標檢測演算法取得了很大的突破。比較流行的演算法可以分為兩類,一類是基於Region Proposal的R-CNN系演算法(R-CNN,Fast R-CNN, Faster R-CNN),它們是two-stage的,需要先使用啟發式方法(selective search)或者CNN網路(RPN)產生Region Proposal,然後再在Region Proposal上做分類與回歸。而另一類是Yolo,SSD這類one-stage演算法,其僅僅使用一個CNN網路直接預測不同目標的類別與位置。第一類方法是准確度高一些,但是速度慢,但是第二類演算法是速度快,但是准確性要低一些。
【嵌牛鼻子】 計算機視覺 目標檢測 YOLO演算法
【嵌牛正文】
目標檢測演算法有很多,本文介紹的是Yolo演算法,其全稱是You Only Look Once: Unified, Real-Time Object Detection,其中,You Only Look Once說的是只需要一次CNN運算,Unified指的是這是一個統一的框架,提供end-to-end的預測,而Real-Time體現是Yolo演算法速度快。
如下圖是YOLO的檢測系統,整體來看,首先將輸入圖片resize到448x448,然後送入CNN網路,最後處理網路預測結果得到檢測的目標。相比R-CNN演算法,其是一個統一的框架,其速度更快,而且Yolo的訓練過程也是end-to-end的。
具體來說,Yolo的CNN網路將輸入的圖片分割成S S網格,,然後每個單元格負責去檢測那些中心點落在該格子內的目標,如下圖,可以看到狗這個目標的中心落在左下角一個單元格內,那麼該單元格負責預測這個狗。每個單元格會預測B個邊界框(bounding box)以及邊界框的置信度(confidence score)。所謂置信度其實包含兩個方面,一是這個邊界框含有目標的可能性大小,二是這個邊界框的准確度。前者記為Pr(object),當該邊界框是背景時(即不包含目標),此時Pr(object)=0。而當該邊界框包含目標時,Pr(object)=1。邊界框的准確度可以用預測框與實際框(ground truth)的IOU(intersection over union,交並比)來表徵,記為 。因此置信度可以定義為Pr(object)∗ 。很多人可能將Yolo的置信度看成邊界框是否含有目標的概率,但是其實它是兩個因子的乘積,預測框的准確度也反映在裡面。邊界框的大小與位置可以用4個值來表徵:(x,y,w,h),其中(x,y)是邊界框的中心坐標,而w和h是邊界框的寬與高。還有一點要注意,中心坐標的預測值(x,y)是相對於每個單元格左上角坐標點的偏移值,並且單位是相對於單元格大小的,單元格的坐標定義如圖6所示。而邊界框的w和h預測值是相對於整個圖片的寬與高的比例,這樣理論上4個元素的大小應該在[0,1]范圍。這樣,每個邊界框的預測值實際上包含5個元素:(x,y,w,h,c),其中前4個表徵邊界框的大小與位置,而最後一個值是置信度。
還有分類問題,對於每一個單元格其還要給出預測出C個類別概率值,其表徵的是由該單元格負責預測的邊界框其目標屬於各個類別的概率。但是這些概率值其實是在各個邊界框置信度下的條件概率,即 。值得注意的是,不管一個單元格預測多少個邊界框,其只預測一組類別概率值,這是Yolo演算法的一個缺點,在後來的改進版本中,Yolo9000是把類別概率預測值與邊界框是綁定在一起的。同時,我們可以計算出各個邊界框類別置信度(class-specific confidence scores): 。邊界框類別置信度表徵的是該邊界框中目標屬於各個類別的可能性大小以及邊界框匹配目標的好壞。後面會說,一般會根據類別置信度來過濾網路的預測框。
總結一下,每個單元格需要預測(B∗5+C)個值。如果將輸入圖片劃分為S×S網格,那麼最終預測值為S×S×(B∗5+C)大小的張量。整個模型的預測值結構如下圖所示。對於PASCAL VOC數據,其共有20個類別,如果使用S=7,B=2,那麼最終的預測結果就是7×7×30大小的張量。在下面的網路結構中我們會詳細講述每個單元格的預測值的分布位置。
Yolo採用卷積網路來提取特徵,然後使用全連接層來得到預測值。網路結構參考GooLeNet模型,包含24個卷積層和2個全連接層,如下圖所示。對於卷積層,主要使用1x1卷積來做channle rection,然後緊跟3x3卷積。對於卷積層和全連接層,採用Leaky ReLU激活函數。但是最後一層卻採用線性激活函數。
可以看到網路的最後輸出為7×7×30大小的張量。這和前面的討論是一致的。對於每一個單元格,前20個元素是類別概率值,然後2個元素是邊界框置信度,兩者相乘可以得到類別置信度,最後8個元素是邊界框的(x,y,w,h)。
在訓練之前,先在ImageNet上進行了預訓練,其預訓練的分類模型採用圖8中前20個卷積層,然後添加一個average-pool層和全連接層。預訓練之後,在預訓練得到的20層卷積層之上加上隨機初始化的4個卷積層和2個全連接層。由於檢測任務一般需要更高清的圖片,所以將網路的輸入從224x224增加到了448x448。整個網路的流程如下圖所示:
下面是訓練損失函數的分析,Yolo演算法將目標檢測看成回歸問題,所以採用的是均方差損失函數。但是對不同的部分採用了不同的權重值。首先區分定位誤差和分類誤差。對於定位誤差,即邊界框坐標預測誤差,採用較大的權重 。然後其區分不包含目標的邊界框與含有目標的邊界框的置信度,對於前者,採用較小的權重值 。其它權重值均設為1。然後採用均方誤差,其同等對待大小不同的邊界框,但是實際上較小的邊界框的坐標誤差應該要比較大的邊界框要更敏感。為了保證這一點,將網路的邊界框的寬與高預測改為對其平方根的預測,即預測值變為 。
另外一點時,由於每個單元格預測多個邊界框。但是其對應類別只有一個。那麼在訓練時,如果該單元格內確實存在目標,那麼只選擇與ground truth的IOU最大的那個邊界框來負責預測該目標,而其它邊界框認為不存在目標。這樣設置的一個結果將會使一個單元格對應的邊界框更加專業化,其可以分別適用不同大小,不同高寬比的目標,從而提升模型性能。大家可能會想如果一個單元格內存在多個目標怎麼辦,其實這時候Yolo演算法就只能選擇其中一個來訓練,這也是Yolo演算法的缺點之一。要注意的一點時,對於不存在對應目標的邊界框,其誤差項就是只有置信度,左標項誤差是沒法計算的。而只有當一個單元格內確實存在目標時,才計算分類誤差項,否則該項也是無法計算的。
綜上討論,最終的損失函數計算如下:
其中第一項是邊界框中心坐標的誤差項, 指的是第ii個單元格存在目標,且該單元格中的第j個邊界框負責預測該目標。第二項是邊界框的高與寬的誤差項。第三項是包含目標的邊界框的置信度誤差項。第四項是不包含目標的邊界框的置信度誤差項。而最後一項是包含目標的單元格的分類誤差項, 指的是第i個單元格存在目標。
NMS演算法(非極大值抑制演算法):選擇得分(Confidence Score)最高的作為輸出,與該輸出重疊的 去掉,不斷重復這一過程直到所有備選處理完。
YOLO的NMS演算法中, Confidence Score的值如下: , 。 代表著某個對象 存在於第j個邊界框的可能性。每個網格有:20個對象的概率*2個邊界框的置信度,共40個得分。49個網格共1960個得分。對每種對象分別進行NMS,那麼每種對象有1960/20=98個得分。
YOLO演算法的NMS步驟如下:
1)設置一個Score的閾值,低於該閾值的候選對象排除掉(將該Score設為0)
2)遍歷每一個對象類別
2.1)遍歷該對象的98個得分
2.1.1)找到Score最大的那個對象及其邊界框,添加到輸出列表
2.1.2)對每個Score不為0的候選對象,計算其與上面2.1.1輸出對象的邊界框的IOU
2.1.3)根據預先設置的IOU閾值,所有高於該閾值(重疊度較高)的候選對象排除掉(將Score設為0)
2.1.4)如果所有邊界框要麼在輸出列表中,要麼Score=0,則該對象類別的NMS完成,返回步驟2處理下一種對象
3)輸出列表即為預測的對象
這篇長文詳細介紹了Yolo演算法的原理及實現,當然Yolo-v1還是有很多問題的,所以後續可以讀讀Yolo9000演算法,看看其如何改進的。
Ⅲ 【目標檢測演算法解讀】yolo系列演算法二
https://blog.csdn.net/Gentleman_Qin/article/details/84349144
|聲明:遵循CC 4.0 BY-SA版權協議
建立在YOLOv1的基礎上,經過Joseph Redmon等的改進,YOLOv2和YOLO9000演算法在2017年CVPR上被提出,並獲得最佳論文提名,重點解決YOLOv1召回率和定位精度方面的誤差。在提出時,YOLOv2在多種監測數據集中都要快過其他檢測系統,並可以在速度與精確度上進行權衡。
YOLOv2採用Darknet-19作為特徵提取網路,增加了批量標准化(Batch Normalization)的預處理,並使用224×224和448×448兩階段訓練ImageNet,得到預訓練模型後fine-tuning。
相比於YOLOv1是利用FC層直接預測Bounding Box的坐標,YOLOv2借鑒了FSR-CNN的思想,引入Anchor機制,利用K-Means聚類的方式在訓練集中聚類計算出更好的Anchor模板,在卷積層使用Anchor Boxes操作,增加Region Proposal的預測,同時採用較強約束的定位方法,大大提高演算法召回率。同時結合圖像細粒度特徵,將淺層特徵與深層特徵相連,有助於對小尺寸目標的檢測。
下圖所示是YOLOv2採取的各項改進帶了的檢測性能上的提升:
YOLO9000 的主要檢測網路也是YOLO v2,同時使用WordTree來混合來自不同的資源的訓練數據,並使用聯合優化技術同時在ImageNet和COCO數據集上進行訓練,目的是利用數量較大的分類數據集來幫助訓練檢測模型,因此,YOLO 9000的網路結構允許實時地檢測超過9000種物體分類,進一步縮小了檢測數據集與分類數據集之間的大小代溝。
下面將具體分析YOLOv2的各個創新點:
BN概述:
對數據進行預處理(統一格式、均衡化、去噪等)能夠大大提高訓練速度,提升訓練效果。BN正是基於這個假設的實踐,對每一層輸入的數據進行加工。
BN是2015年Google研究員在論文《Batch Normalization: Accelerating Deep Network Training by Recing Internal Covariate Shift》一文中提出的,同時也將BN應用到了2014年的GoogLeNet上,也就是Inception-v2。
BN層簡單講就是對網路的每一層的輸入都做了歸一化,這樣網路就不需要每層都去學數據的分布,收斂會更快。YOLOv1演算法(採用的是GoogleNet網路提取特徵)是沒有BN層的,而在YOLOv2中作者為每個卷積層都添加了BN層。
使用BN對網路進行優化,讓網路提高了收斂性,同時還消除了對其他形式的正則化(regularization)的依賴,因此使用BN後可以從模型中去掉Dropout,而不會產生過擬合。
BN優點:
神經網路每層輸入的分布總是發生變化,加入BN,通過標准化上層輸出,均衡輸入數據分布,加快訓練速度,因此可以設置較大的學習率(Learning Rate)和衰減(Decay);
通過標准化輸入,降低激活函數(Activation Function)在特定輸入區間達到飽和狀態的概率,避免梯度彌散(Gradient Vanishing)問題;
輸入標准化對應樣本正則化,BN在一定程度上可以替代 Dropout解決過擬合問題。
BN演算法:
在卷積或池化之後,激活函數之前,對每個數據輸出進行標准化,方式如下圖所示:
公式很簡單,前三行是 Batch內數據歸一化(假設一個Batch中有每個數據),同一Batch內數據近似代表了整體訓練數據。第四行引入了附加參數 γ 和 β,此二者的取值演算法可以參考BN論文,在此不再贅述。
fine-tuning:用已經訓練好的模型,加上自己的數據集,來訓練新的模型。即使用別人的模型的前幾層,來提取淺層特徵,而非完全重新訓練模型,從而提高效率。一般新訓練模型准確率都會從很低的值開始慢慢上升,但是fine-tuning能夠讓我們在比較少的迭代次數之後得到一個比較好的效果。
YOLO模型分為兩部分,分類模型和檢測模型,前者使用在ImageNet上預訓練好的模型,後者在檢測數據集上fine-tuning。
YOLOv1在預訓練時採用的是224*224的輸入(在ImageNet數據集上進行),然後在檢測的時候採用448*448的輸入,這會導致從分類模型切換到檢測模型的時候,模型還要適應圖像解析度的改變。
YOLOv2則將預訓練分成兩步:先用224*224的輸入在ImageNet數據集訓練分類網路,大概160個epoch(將所有訓練數據循環跑160次)後將輸入調整到448*448,再訓練10個epoch(這兩步都是在ImageNet數據集上操作)。然後利用預訓練得到的模型在檢測數據集上fine-tuning。這樣訓練得到的模型,在檢測時用448*448的圖像作為輸入可以順利檢測。
YOLOv1將輸入圖像分成7*7的網格,每個網格預測2個Bounding Box,因此一共有98個Box,同時YOLOv1包含有全連接層,從而能直接預測Bounding Boxes的坐標值,但也導致丟失較多的空間信息,定位不準。
YOLOv2首先將YOLOv1網路的FC層和最後一個Pooling層去掉,使得最後的卷積層可以有更高解析度的特徵,然後縮減網路,用416*416大小的輸入代替原來的448*448,使得網路輸出的特徵圖有奇數大小的寬和高,進而使得每個特徵圖在劃分單元格(Cell)的時候只有一個中心單元格(Center Cell)。
為什麼希望只有一個中心單元格呢?由於圖片中的物體都傾向於出現在圖片的中心位置,特別是比較大的物體,所以有一個單元格單獨位於物體中心的位置用於預測這些物體。
YOLOv2通過引入Anchor Boxes,通過預測Anchor Box的偏移值與置信度,而不是直接預測坐標值。YOLOv2的卷積層採用32這個值來下采樣圖片,所以通過選擇416*416用作輸入尺寸最終能輸出一個13*13的特徵圖。若採用FSRCNN中的方式,每個Cell可預測出9個Anchor Box,共13*13*9=1521個(YOLOv2確定Anchor Boxes的方法見是維度聚類,每個Cell選擇5個Anchor Box)。
在FSRCNN中,以一個51*39大小的特徵圖為例,其可以看做一個尺度為51*39的圖像,對於該圖像的每一個位置,考慮9個可能的候選窗口:3種面積3種比例。這些候選窗口稱為Anchor Boxes。下圖示出的是51*39個Anchor Box中心,以及9種Anchor Box示例。
YOLOv1和YOLOv2特徵圖數據結構:
YOLOv1:S*S* (B*5 + C) => 7*7(2*5+20)
其中B對應Box數量,5對應邊界框的定位信息(w,y,w,h)和邊界框置信度(Confidience)。解析度是7*7,每個Cell預測2個Box,這2個Box共用1套條件類別概率(1*20)。
YOLOv2:S*S*K* (5 + C) => 13*13*9(5+20)
解析度提升至13*13,對小目標適應性更好,借鑒了FSRCNN的思想,每個Cell對應K個Anchor box(YOLOv2中K=5),每個Anchor box對應1組條件類別概率(1*20)。
聚類:聚類是指事先沒有「標簽」而通過某種成團分析找出事物之間存在聚集性原因的過程。即在沒有劃分類別的情況下,根據數據相似度進行樣本分組。
在FSR-CNN中Anchor Box的大小和比例是按經驗設定的,然後網路會在訓練過程中調整Anchor Box的尺寸,最終得到准確的Anchor Boxes。若一開始就選擇了更好的、更有代表性的先驗Anchor Boxes,那麼網路就更容易學到准確的預測位置。
YOLOv2使用K-means聚類方法類訓練Bounding Boxes,可以自動找到更好的寬高維度的值用於一開始的初始化。傳統的K-means聚類方法使用的是歐氏距離函數,意味著較大的Anchor Boxes會比較小的Anchor Boxes產生更多的錯誤,聚類結果可能會偏離。由於聚類目的是確定更精準的初始Anchor Box參數,即提高IOU值,這應與Box大小無關,因此YOLOv2採用IOU值為評判標准,即K-means 採用的距離函數(度量標准) 為:
d(box,centroid) = 1 - IOU(box,centroid)
如下圖,左邊是聚類的簇個數和IOU的關系,兩條曲線分別代表兩個不同的數據集。分析聚類結果並權衡模型復雜度與IOU值後,YOLOv2選擇K=5,即選擇了5種大小的Box 維度來進行定位預測。
其中紫色和灰色也是分別表示兩個不同的數據集,可以看出其基本形狀是類似的。更重要的是,可以看出聚類的結果和手動設置的Anchor Box位置和大小差別顯著——結果中扁長的框較少,而瘦高的框更多(更符合行人的特徵)。
YOLOv2採用的5種Anchor的Avg IOU是61,而採用9種Anchor Boxes的Faster RCNN的Avg IOU是60.9,也就是說本文僅選取5種box就能達到Faster RCNN的9中box的效果。選擇值為9的時候,AVG IOU更有顯著提高。說明K-means方法的生成的boxes更具有代表性。
直接對Bounding Boxes求回歸會導致模型不穩定,其中心點可能會出現在圖像任何位置,有可能導致回歸過程震盪,甚至無法收斂,尤其是在最開始的幾次迭代的時候。大多數不穩定因素產生自預測Bounding Box的中心坐標(x,y)位置的時候。
YOLOv2的網路在特徵圖(13*13)的每一個單元格中預測出5個Bounding Boxes(對應5個Anchor Boxes),每個Bounding Box預測出5個值(tx,ty,tw,th,t0),其中前4個是坐標偏移值,t0是置信度結果(類似YOLOv1中的邊界框置信度Confidence)。YOLOv2借鑒了如下的預測方式,即當Anchor Box的中心坐標和寬高分別是(xa,ya)和(wa,wh)時,Bounding Box坐標的預測偏移值(tx,ty,tw,th)與其坐標寬高(x,y,w,h)的關系如下:
tx = (x-xa)/wa
ty= (y-ya)/ha
tw = log(w/wa)
th = log(h/ha)
基於這種思想,YOLOv2在預測Bounding Box的位置參數時採用了如下強約束方法:
上圖中,黑色虛線框是Anchor Box,藍色矩形框就是預測的Bounding Box結果,預測出的Bounding Box的坐標和寬高為(bx,by)和(bw,bh),計算方式如圖中所示,其中:對每個Bounding Box預測出5個值(tx,ty,tw,th,t0),Cell與圖像左上角的橫縱坐標距離為(cx,cy),σ定義為sigmoid激活函數(將函數值約束到[0,1]),該Cell對應的Anchor Box對應的寬高為(pw,ph)。
簡而言之,(bx,by)就是(cx,cy)這個Cell附近的Anchor Box針對預測值(tx,ty)得到的Bounding Box的坐標預測結果,同時可以發現這種方式對於較遠距離的Bounding Box預測值(tx,ty)能夠得到很大的限制。
YOLOv2通過添加一個轉移層,把高解析度的淺層特徵連接到低解析度的深層特徵(把特徵堆積在不同Channel中)而後進行融合和檢測。具體操作是先獲取前層的26*26的特徵圖,將其同最後輸出的13*13的特徵圖進行連接,而後輸入檢測器進行檢測(檢測器的FC層起到了全局特徵融合的作用),以此來提高對小目標的檢測能力。
為了適應不同尺度下的檢測任務,YOLOv2在訓練網路時,其在檢測數據集上fine-tuning時候採用的輸入圖像的size是動態變化的。具體來講,每訓練10個Batch,網路就會隨機選擇另一種size的輸入圖像。因為YOLOv2用到了參數是32的下采樣,因此也採用32的倍數作為輸入的size,即採用{320,352,…,608}的輸入尺寸(網路會自動改變尺寸,並繼續訓練的過程)。
這一策略讓網路在不同的輸入尺寸上都能達到較好的預測效果,使同一網路能在不同解析度上進行檢測。輸入圖片較大時,檢測速度較慢,輸入圖片較小時,檢測速度較快,總體上提高了准確率,因此多尺度訓練算是在准確率和速度上達到一個平衡。
上表反映的是在檢測時,不同大小的輸入圖片情況下的YOLOv2和其他目標檢測演算法的對比。可以看出通過多尺度訓練的檢測模型,在測試的時候,輸入圖像在尺寸變化范圍較大的情況下也能取得mAP和FPS的平衡。
YOLOv1採用的訓練網路是GoogleNet,YOLOv2採用了新的分類網路Darknet-19作為基礎網路,它使用了較多的3*3卷積核,並把1*1的卷積核置於3*3的卷積核之間,用來壓縮特徵,同時在每一次池化操作後把通道(Channels)數翻倍(借鑒VGG網路)。
YOLOv1採用的GooleNet包含24個卷積層和2個全連接層,而Darknet-19包含19個卷積層和5個最大池化層(Max Pooling Layers),後面添加Average Pooling層(代替v1中FC層),而Softmax分類器作為激活被用在網路最後一層,用來進行分類和歸一化。
在ImageNet數據集上進行預訓練,主要分兩步(採用隨機梯度下降法):
輸入圖像大小是224*224,初始學習率(Learning Rate)為0.1,訓練160個epoch,權值衰減(Weight Decay)為0.0005,動量(Momentum)為0.9,同時在訓練時採用標準的數據增強(Data Augmentation)方式如隨機裁剪、旋轉以及色度、亮度的調整。
fine-tuning:第1步結束後,改用448*448輸入(高解析度模型),學習率改為0.001,訓練10個epoch,其他參數不變。結果表明:fine-tuning後的top-1准確率為76.5%,top-5准確率為93.3%,若按照原來的訓練方式,Darknet-19的top-1准確率是72.9%,top-5准確率為91.2%。可以看出,兩步分別從網路結構和訓練方式方面入手提高了網路分類准確率。
預訓練之後,開始基於檢測的數據集再進行fine-tuning。
首先,先把最後一個卷積層去掉,然後添加3個3*3的卷積層,每個卷積層有1024個卷積核,並且後面都連接一個1*1的卷積層,卷積核個數(特徵維度)根據需要檢測的類數量決定。(比如對VOC數據,每個Cell需要預測5個Boungding Box,每個Bounding Box有4個坐標值、1個置信度值和20個條件類別概率值,所以每個單元格對應125個數據,此時卷積核個數應該取125。)
然後,將最後一個3*3*512的卷積層和倒數第2個卷積層相連(提取細粒度特徵),最後在檢測數據集上fine-tuning預訓練模型160個epoch,學習率採用0.001,並且在第60和90個epoch的時候將學習率除以10,權值衰減、動量和數據增強方法與預訓練相同。
YOLO9000通過結合分類和檢測數據集,使得訓練得到的模型可以檢測約9000類物體,利用帶標注的分類數據集量比較大的特點,解決了帶標注的檢測數據集量比較少的問題。具體方法是:一方面採用WordTree融合數據集,另一方面聯合訓練分類數據集和檢測數據集。
分類數據集和檢測數據集存在較大差別:檢測數據集只有粗粒度的標記信息,如「貓」、「狗」,而分類數據集的標簽信息則更細粒度,更豐富。比如「狗」就包括「哈士奇」、「金毛狗」等等。所以如果想同時在檢測數據集與分類數據集上進行訓練,那麼就要用一種一致性的方法融合這些標簽信息。
用於分類的方法,常用Softmax(比如v2),Softmax意味著分類的類別之間要互相獨立的,而ImageNet和COCO這兩種數據集之間的分類信息不相互獨立(ImageNet對應分類有9000種,而COCO僅提供80種目標檢測),所以使用一種多標簽模型來混合數據集,即假定一張圖片可以有多個標簽,並且不要求標簽之間獨立,而後進行Softmax分類。
由於ImageNet的類別是從WordNet選取的,作者採用以下策略重建了一個樹形結構(稱為WordTree):
遍歷ImageNet的標簽,然後在WordNet中尋找該標簽到根節點(所有的根節點為實體對象)的路徑;
如果路徑只有一條,將該路徑直接加入到WordTree結構中;
否則,從可選路徑中選擇一條最短路徑,加入到WordTree結構中。
WordTree的作用就在於將兩種數據集按照層級進行結合。
如此,在WordTree的某個節點上就可以計算該節點的一些條件概率值,比如在terrier這個節點,可以得到如下條件概率值:
進而,如果要預測此節點的概率(即圖片中目標是Norfolk terrier的概率),可以根據WordTree將該節點到根節點的條件概率依次相乘得到,如下式:
其中:
YOLO9000在WordTree1k(用有1000類別的ImageNet1k創建)上訓練了Darknet-19模型。為了創建WordTree1k作者添加了很多中間節點(中間詞彙),把標簽由1000擴展到1369。
訓練過程中GroundTruth標簽要順著向根節點的路徑傳播:為了計算條件概率,模型預測了一個包含1369個元素的向量,而且基於所有「同義詞集」計算Softmax,其中「同義詞集」是同一概念下的所屬詞。
現在一張圖片是多標記的,標記之間不需要相互獨立。在訓練過程中,如果有一個圖片的標簽是「Norfolk terrier」,那麼這個圖片還會獲得「狗」以及「哺乳動物」等標簽。
如上圖所示,之前的ImageNet分類是使用一個大Softmax進行分類,而現在WordTree只需要對同一概念下的同義詞進行Softmax分類。然後作者分別兩個數據集上用相同訓練方法訓練Darknet-19模型,最後在ImageNet數據集上的top-1准確率為72.9%,top-5准確率為91.2%;在WordTree數據集上的top-1准確率為71.9%,top-5准確率為90.4%。
這種方法的好處是有「退而求其次」的餘地:在對未知或者新的物體進行分類時,性能損失更低,比如看到一個狗的照片,但不知道是哪種種類的狗,那麼就預測其為「狗」。
以上是構造WordTree的原理,下圖是融合COCO數據集和ImageNet數據集以及生成它們的WordTree的示意圖(用顏色區分了COCO數據集和ImageNet數據集的標簽節點), 混合後的數據集對應的WordTree有9418個類。另一方面,由於ImageNet數據集太大,YOLO9000為了平衡兩個數據集之間的數據量,通過過采樣(Oversampling)COCO數據集中的數據,使COCO數據集與ImageNet數據集之間的數據量比例達到1:4。
對YOLO9000進行評估,發現其mAP比DPM高,而且YOLO有更多先進的特徵,YOLO9000是用部分監督的方式在不同訓練集上進行訓練,同時還能檢測9000個物體類別,並保證實時運行。雖然YOLO9000對動物的識別性能很好,但是對衣服或者裝備的識別性能不是很好(這跟數據集的數據組成有關)。
YOLO9000的網路結構和YOLOv2類似,區別是每個單元格只採用3個Anchor Boxes。
YOLO9000提出了一種在分類數據集和檢測數據集上聯合訓練的機制,即使用檢測數據集(COCO)的圖片去學習檢測相關的信息即查找對象(例如預測邊界框坐標、邊界框是否包含目標及目標屬於各個類別的概率),使用僅有類別標簽的分類數據集(ImageNet)中的圖片去擴展檢測到的對象的可識別種類。
具體方法是:當網路遇到一個來自檢測數據集的圖片與標記信息,就把這些數據用完整的損失函數(v2和9000均沿用了v1網路的損失函數)反向傳播,而當網路遇到一個來自分類數據集的圖片和分類標記信息,只用代表分類誤差部分的損失函數反向傳播這個圖片。
YOLO v2 在大尺寸圖片上能夠實現高精度,在小尺寸圖片上運行更快,可以說在速度和精度上達到了平衡,具體性能表現如下所示。
coco數據集
voc2012數據集
Ⅳ SSD與yolov1的對比
yolo系列和ssd發表的時間順序是yolov1,ssd,yolov2,yolov3,當然現在yolov4也出現了。這個是我之前在看完yolov1之後閱讀ssd論文的時候記錄的筆記,因此會涉及到很多和yolov1實現的對比。
fast rcnn系列的模型的套路:
1.使用事先設定的bounding boxes,
和fasterRCNN區別是沒有使用RPN和Pooling操作
論文的貢獻:
1. 引入了一種單階段的檢測器,比以前的演算法YOLOv1更准更快,並沒有使用RPN和Pooling操作;
2. 使用一個小的卷積濾波器應用在不同的feature map層從而預測BB的類別的BB偏差;
3. 可以在更小的輸入圖片中得到更好的檢測效果(相比Faster-rcnn);
4. 在多個數據集(PASCAL、VOC、COCO、ILSVRC)上面的測試結果表明,它可以獲得更高的mAp值;
整個是一個基於前向反饋的卷積網路,SSD模型最終提供一個固定大小的bounding boxes集合以及這些bounding boxes是否存在分類物品的得分的集合,通常在模型之後,添加了一個非極大抑制步驟來提供最終的檢測結果。
主幹網路backbone network
主幹網路是基於VGG的, 是一個高質量的分類網路,把這個基礎模型作為ssd的前面層,用於給後面的層提供高質量的圖片分類,我們稱這個層為基礎網路,注意這個基礎模型在使用的時候,需要截去最後面的分類層。在這里使用的VGG16網路。然後添加輔助的結構來 提供最終的檢測功能。
主幹網對VGG16的修改:
1.將VGG16的FC6和FC7層轉化為卷積層,如圖1上的Conv6和Conv7;
2.去掉所有的Dropout層和FC8層;
3.添加了Atrous演算法(hole演算法),參考該鏈接;
4.將Pool5從2x2-S2變換到3x3-S1;
最終的檢測功能的實現依賴於下面提到的關鍵技術:
在基礎網路之後,添加了很多個卷積層,卷積層不斷的減小特徵圖的寬高尺寸,比如從8 8經過一層卷積之後就變成4 4了。然後在這些特徵圖上都應用目標檢測演算法。正如上面那張圖所示,對於前面一層來說,相當於是在一個比較小的8 8的尺度上,對每個位置檢測4個固定橫縱比的bounding box,而對於後面一層來說,就是在一個相對較大的4 4尺寸上對每個位置檢測4個固定橫縱比的bounding box。這樣就實現了在多尺度特徵圖上檢測的目的。
圖中的所有信道的對應位置的像素點集合被認為是一個anchor,那麼對於每個anchor就會有N個比率的bounding box,需要注意的是,每一層的bounding box數量不一定是一樣的。
我們從feature layer或者說feature map上抽取特徵。feature layer可能是基礎網路上面的某一層,也可以是在基礎網路後面添加的卷積層。對於一個 m x nxc的feature layer,使用一個3x3xp的核過濾器(small kernel),那麼對於每一個輸出的pixel,都可以得到一個channel數為p大小的檢測結果,一般p=4 (|Classes|+4)大小,最終可以得到m n p大小的檢測結果。這個檢測結果中包含了每個位置的分類物品出現的置信度以及四個表示位置和偏移的(cx,cy,w,h)。因為設置了bounding box的數量為4,所以結果是4 (|Classes|+4).
需要注意到這里使用的卷積預測器而不是全連接層(yolov1使用的是全連接層)。
這里的bounding box的概念類似於Faster R-CNN中的anchor boxes.但是這里不同的feature map層可以安排不同形狀和數量的bounding box。,這樣可以有效的離散化可能的輸出box的空間(想像一下,如果每個feature map的bounding box長的差不多,那麼得到的可能差異只在大小上,我們需要的是不同大小和形狀的box來擬合真實的物品的坐標,因此box越多樣越好。
The key difference between training SSD and training a typical detector that uses region proposals, is that ground truth information needs to be assigned to specific outputs in the fixed set of detector outputs.
把真實的物品坐標框稱為ground truth,對於一張圖片,在經過SSD模型的各層檢測,會有8732個prior box(也就是檢測結果),需要標記這些檢測結果中,哪些是正樣本,那些是負樣本。 這些標記過程都是在訓練之前做好的;不同層的default box的數量和大小也是在訓練錢都確定好的;還需要准備好難負例挖掘的策略。
對於打標的真實框GT,需要選擇哪個預測框是與真實框對應的。這里選擇是jaccard overlap>0.5的所有默認框。這樣正負樣本就不會很懸殊。Multibox論文中則只會選擇jaccard overlap最高的一個框框。
個人理解中,這里的預測框是指沒有偏移變化的預測框prior box,也叫先驗框(prior box)。在GT確定、輸入圖像尺寸固定、prior box確定之後,就可以得到jaccard overlap>0.5的所有先驗框。然後學習的時候,這些正例需要根據ground truth進行偏移和長寬比縮放的學習。而其他負例則不需要學習位置參數。
為圖像的面積的交並比.
在訓練過程中,首先要確定訓練圖片中的ground truth(真實目標)與哪個先驗框來進行匹配,與之匹配的先驗框所對應的邊界框將負責預測它。
在Yolov1中,ground truth的中心落在哪個單元格,該單元格中與其IOU最大的邊界框負責預測它。但是在SSD中卻完全不一樣,SSD的先驗框與ground truth的匹配原則主要有兩點。
首先,對於圖片中每個ground truth,找到與其IOU最大的先驗框,該先驗框與其匹配,這樣,可以保證每個ground truth一定與某個先驗框匹配。通常稱與ground truth匹配的先驗框為正樣本(其實應該是先驗框對應的預測box,不過由於是一一對應的就這樣稱呼了),反之,若一個先驗框沒有與任何ground truth進行匹配,那麼該先驗框只能與背景匹配,就是負樣本。一個圖片中ground truth是非常少的, 而先驗框卻很多,如果僅按第一個原則匹配,很多先驗框會是負樣本,正負樣本極其不平衡,所以需要第二個原則。
第二個原則是:對於剩餘的未匹配先驗框,若某個ground truth的 IOU 大於某個閾值(一般是0.5),那麼該先驗框也與這個ground truth進行匹配。這意味著某個ground truth可能與多個先驗框匹配,這是可以的。但是反過來卻不可以,因為一個先驗框只能匹配一個ground truth,如果多個ground truth與某個先驗框IOU大於閾值,那麼先驗框只與IOU最大的那個先驗框進行匹配。第二個原則一定在第一個原則之後進行,仔細考慮一下這種情況,如果某個ground truth所對應最大IOU小於閾值,並且所匹配的先驗框卻與另外一個ground truth的IOU大於閾值,那麼該先驗框應該匹配誰,答案應該是前者,首先要確保某個ground truth一定有一個先驗框與之匹配。
損失函數是回歸損失和置信度損失的加權平均
下面是位置回歸損失函數的介紹,看著就很暈。
N表示匹配的框,應該可以理解為正樣本框。首先g表示是ground truth box的各個指標,d是先驗框的各個指標,l是預測結果的各個指標。g^ 這個是根據g和d得到的可以和預測結果匹配計算損失函數的指標。比如g^cx 這個指標,是歸一化的橫坐標偏移指標,因為先驗框的中心不會完全和ground truth的中心重合,因此計算實際的偏移量。這個值就是我們希望模型學習到的值。同理,先驗框的寬度也不會完全重合ground truth的寬度,我們用log函數來計算g^w,這也意味著我們希望學習到的寬度也是這種變換的。
smoothL1損失函數長這樣:
分類的置信度損失函數如下,正樣本的softmax loss函數以及負樣本的背景置信度損失.
在某些論文的方法中,為了獲得不同縮放的圖片的結果,通過現將圖片縮放在不同的尺度然後在最後將每個縮放尺度的結果組合起來。而在這篇論文中使用的方式是使用同一個網路中的不同層上抽取的feature map來獲得和上面的縮放效果一樣的結果。
我覺得這個idea真的很贊,超級贊。這樣不僅僅可以利用參數共享,而且很方便。已經有研究表明使用前面層的feature map可以優化語義分段質量semantic segmentation quality,因為前面的層可以獲得更多的細節的優質的關於輸入的信息。
這張圖上有兩個feature map。我們知道網路的不同層有不同的感受野。在SSD中,bounding box的大小不需要匹配對應層的感受野。我們設計了bounding box的尺寸規則,這樣每個feature map就可以自己計算。
如果我們使用m個feature map,其中1表示較低層,m表示叫高層。bounding box的默認尺度按照如下的計算公式計算
bounding box的橫縱比尺度為
什麼是hard negative mining:
【1】對於目標檢測中我們會事先標記處ground truth,然後再演算法中會生成一系列proposal,這些proposal有跟標記的ground truth重合的也有沒重合的,那麼重合度(IOU)超過一定閾值(通常0.5)的則認定為是正樣本,以下的則是負樣本。
【2】然後扔進網路中訓練。However,這也許會出現一個問題那就是正樣本的數量遠遠小於負樣本,這樣訓練出來的分類器的效果總是有限的,會出現許多false positive,把其中得分較高的這些false positive當做所謂的Hard negative,既然mining出了這些Hard negative,就把這些扔進網路得到類別的損失函數,將這些難負樣本的損失函數作為背景損失函數,從而加強分類器判別假陽性的能力。
絕大部分的bounding box最後匹配出來是沒有物品的,這樣會導致負樣本和正樣本嚴重失衡。SSD這里沒有使用全部的負樣本,而是對每個負樣本的bounding box根據其confidence loss排序,然後選擇最大的一批作為負樣本,這樣是的負樣本和正樣本的比率穩定在3:1。實踐證明,這樣的方式是的優化的碎度更快,訓練也更加穩定。
數據的擴充策略中數據來自於以下三種之一
base netowrk是VGG16。SSD300的模型就是上面那張結構圖所示。新的層的初始化使用xavier方式( https://zhuanlan.hu.com/p/22028079 , https://zhuanlan.hu.com/p/22044472 )。實驗認為和RCNN相比,SSD在定位localization上更加優秀,因為在神經網路模型中直接學習回歸了物品的形狀。但是SSD很容易有分類錯誤問題,尤其是類似的類別(比如動物)。SSD對bounding box的大小很敏感,也就是說,小物體的表現不如大物體。結合模型來看,因為小物體的預測使用的是網路的前面的層,而前面的層並沒有很多的信息。雖然存在上面的問題,但是SSD在大物體上的表現很好,二千對於不同橫縱比的物體的性能魯棒。
下面這張圖展示了ssd中的哪些技術使得性能得到了提升。
性能提升的貢獻:
SSD是如何提升小物體的檢測准確率的:通過數據擴充
SSD用的是VGG16(但去掉了fc層加速)而YOLO普通版有24個卷積層。
SSD的輸入尺寸較小(300 300),而YOLO是448 448,即使網路結構類似計算量差距還是挺明顯的,速度快一點正常。
ssd全靠卷積完成,而yolo里還有全連接,用上gpu的話肯定是ssd快
在ssd中,首先每個真實物品都先選擇一個負責它的bounding box,在沒有訓練指之前,因為prior bounding box的位置都是確定的,所以選擇IOU最大的為正樣本。為平衡正負樣本的比率,將IOU大於0.5的prior bounding box都設置為正樣本。這樣模型就更加穩定了。
SSD演算法思想和結構詳解 : https://www..com/link?url=2XF6E5J1_qxJuzgq&wd=&eqid=
SSD詳解 https://blog.csdn.net/WZZ18191171661/article/details/79444217
https://zhuanlan.hu.com/p/57440670
Ⅳ yoloV1要訓練多久
2小時左右。
①首先經過一個VGG主幹網路提取特徵,這里的主幹網路可以自己選擇,使用resnet也可以。②reshape為一維,然後進行全連接,in_dim=25088,out_dim=4096,需要注意的是
這里的25088是由51277得到的,而不同大小的圖像經過主幹網路提取特徵後的大小也是不一樣的,所以如果輸入的圖像大小不是448的話,就需要修改這里的in_dim。③第二個全連接層,in_dim=4096,out_dim=1470,這里的out_dim是由7730得到的,是為了reshape成7x7×30的向量,至於為什麼yolov1的輸出是一
個7×7×30的向量,而不是r-cnn系列的具體的框坐標等信息,後面會解釋。
Ⅵ YOLOv1網路
YOLO意思是You Only Look Once,創造性的將候選區和對象識別這兩個階段合二為一,看一眼圖片(不用看兩眼哦)就能知道有哪些對象以及它們的位置。其最大的特點是運行速度很快,可以用於實時系統。
實際上,YOLO並沒有真正去掉候選區,而是採用了預定義的候選區(准確點說應該是預測區,因為並不是Faster RCNN所採用的Anchor)。也就是將圖片劃分為 7 * 7=49 個網格(grid),每個網格允許預測出2個邊框(bounding box,包含某個對象的矩形框),總共 49 * 2=98 個bounding box。可以理解為98個候選區,它們很粗略的覆蓋了圖片的整個區域。
RCNN雖然會找到一些候選區,但畢竟只是候選,等真正識別出其中的對象以後,還要對候選區進行微調,使之更接近真實的bounding box。這個過程就是邊框回歸:將候選區bounding box調整到更接近真實的bounding box。
既然反正最後都是要調整的,幹嘛還要先費勁去尋找候選區呢,大致有個區域范圍就行了,所以YOLO就這么幹了。
去掉候選區這個步驟以後,YOLO的結構非常簡單,就是單純的卷積、池化最後加了兩層全連接。單看網路結構的話,和普通的CNN對象分類網路幾乎沒有本質的區別, 最大的差異是最後輸出層用線性函數做激活函數,因為需要預測bounding box的位置(數值型),而不僅僅是對象的概率。 所以粗略來說,YOLO的整個結構就是輸入圖片經過神經網路的變換得到一個輸出的張量,如下圖所示。
因為只是一些常規的神經網路結構,所以,理解YOLO的設計的時候,重要的是理解輸入和輸出的映射關系。
輸入就是原始圖像,唯一的要求是縮放到448 * 448的大小。主要是因為YOLO的網路中,卷積層最後接了兩個全連接層,全連接層是要求固定大小的向量作為輸入,所以倒推回去也就要求原始圖像有固定的尺寸。那麼YOLO設計的尺寸就是448*448。
輸出是一個 7 7 30 的張量(tensor)。
1) 7 * 7網格
根據YOLO的設計,輸入圖像被劃分為 7 * 7 的網格(grid),輸出張量中的 7 * 7 就對應著輸入圖像的 7 * 7 網格。或者我們把 7 * 7 * 30 的張量看作 7 * 7=49個30維的向量,也就是輸入圖像中的每個網格對應輸出一個30維的向量。參考上圖,比如輸入圖像左上角的網格對應到輸出張量中左上角的向量。
要注意的是,並不是說僅僅網格內的信息被映射到一個30維向量。經過神經網路對輸入圖像信息的提取和變換,網格周邊的信息也會被識別和整理,最後編碼到那個30維向量中。
2)30維向量
具體來看每個網格對應的30維向量中包含了哪些信息。
因為YOLO支持識別20種不同的對象(人、鳥、貓、汽車、椅子等),所以這里有20個值表示該網格位置存在任一種對象的概率。可以記為 ,之所以寫成條件概率,意思是如果該網格存在一個對象Object,那麼它是 的概率是 。記不清條件概率的同學可以參考一下 理解貝葉斯定理 )
每個bounding box需要4個數值來表示其位置,(Center_x,Center_y,width,height),即(bounding box的中心點的x坐標,y坐標,bounding box的寬度,高度),2個bounding box共需要8個數值來表示其位置。
bounding box的置信度 = 該bounding box內存在對象的概率 * 該bounding box與該對象實際bounding box的IOU,用公式來表示就是
是bounding box內存在對象的概率,區別於上面的 , 並不管是哪個對象,它體現的是 有或沒有 對象的概率;上面的 意思是假設已經有一個對象在網格中了,這個對象具體是哪一個。
是 bounding box 與 對象真實bounding box 的IOU(Intersection over Union,交並比)。要注意的是,現在討論的30維向量中的bounding box是YOLO網路的輸出,也就是預測的bounding box。所以 體現了預測的bounding box與真實bounding box的接近程度。
還要說明的是,雖然有時說"預測"的bounding box,但這個IOU是在訓練階段計算的。等到了測試階段(Inference),這時並不知道真實對象在哪裡,只能完全依賴於網路的輸出,這時已經不需要(也無法)計算IOU了。
綜合來說,一個bounding box的置信度Confidence意味著它 是否包含對象且位置准確的程度。置信度高表示這里存在一個對象且位置比較准確,置信度低表示可能沒有對象 或者 即便有對象也存在較大的位置偏差。
簡單解釋一下IOU。下圖來自Andrew Ng的深度學習課程,IOU=交集部分面積/並集部分面積,2個box完全重合時IOU=1,不相交時IOU=0。
總的來說,30維向量 = 20個對象的概率 + 2個bounding box * 4個坐標 + 2個bounding box的置信度。
3)討論
每個30維向量中只有一組(20個)對象分類的概率,也就只能預測出一個對象。所以輸出的 7 * 7=49個 30維向量,最多表示出49個對象。
每個30維向量中有2組bounding box,所以總共是98個候選區。
Faster RCNN等一些演算法採用每個grid中手工設置n個Anchor(先驗框,預先設置好位置的bounding box)的設計,每個Anchor有不同的大小和寬高比。YOLO的bounding box看起來很像一個grid中2個Anchor,但它們不是。YOLO並沒有預先設置2個bounding box的大小和形狀,也沒有對每個bounding box分別輸出一個對象的預測。它的意思僅僅是對一個對象預測出2個bounding box,選擇預測得相對比較準的那個。
這里採用2個bounding box,有點不完全算監督演算法,而是像進化演算法。如果是監督演算法,我們需要事先根據樣本就能給出一個正確的bounding box作為回歸的目標。但YOLO的2個bounding box事先並不知道會在什麼位置,只有經過前向計算,網路會輸出2個bounding box,這兩個bounding box與樣本中對象實際的bounding box計算IOU。這時才能確定,IOU值大的那個bounding box,作為負責預測該對象的bounding box。
訓練開始階段,網路預測的bounding box可能都是亂來的,但總是選擇IOU相對好一些的那個,隨著訓練的進行,每個bounding box會逐漸擅長對某些情況的預測(可能是對象大小、寬高比、不同類型的對象等)。所以,這是一種進化或者非監督學習的思想。
另外論文中經常提到responsible。比如:Our system divides the input image into an S*S grid. If the center of an object falls into a grid cell, that grid cell is responsible for detecting that object. 這個 responsible 有點讓人疑惑,對預測"負責"是啥意思。其實沒啥特別意思,就是一個Object只由一個grid來進行預測,不要多個grid都搶著預測同一個Object。更具體一點說,就是在設置訓練樣本的時候,樣本中的每個Object歸屬到且僅歸屬到一個grid,即便有時Object跨越了幾個grid,也僅指定其中一個。具體就是計算出該Object的bounding box的中心位置,這個中心位置落在哪個grid,該grid對應的輸出向量中該對象的類別概率是1(該gird負責預測該對象),所有其它grid對該Object的預測概率設為0(不負責預測該對象)。
還有:YOLO predicts multiple bounding boxes per grid cell. At training time we only want one bounding box predictor to be responsible for each object. 同樣,雖然一個grid中會產生2個bounding box,但我們會選擇其中一個作為預測結果,另一個會被忽略。下面構造訓練樣本的部分會看的更清楚。
7 * 7網格,每個網格2個bounding box,對448 * 448輸入圖像來說覆蓋粒度有點粗。我們也可以設置更多的網格以及更多的bounding box。設網格數量為 S * S,每個網格產生B個邊框,網路支持識別C個不同的對象。這時,輸出的向量長度為: ,整個輸出的tensor就是: 。
YOLO選擇的參數是 7 7網格,2個bounding box,20種對象,因此 輸出向量長度 = 20 + 2 * (4+1) = 30。整個輸出的tensor就是 7 7*30。
因為網格和bounding box設置的比較稀疏,所以這個版本的YOLO訓練出來後預測的准確率和召回率都不是很理想,後續的v2、v3版本還會改進。當然,因為其速度能夠滿足實時處理的要求,所以對工業界還是挺有吸引力的。
作為監督學習,我們需要先構造好訓練樣本,才能讓模型從中學習。
對於一張輸入圖片,其對應輸出的7 7 30張量(也就是通常監督學習所說的標簽y或者label)應該填寫什麼數據呢。
首先,輸出的 7 7維度 對應於輸入的 7 7 網格。 然後具體看下30維向量的填寫(請對照上面圖6)。
對於輸入圖像中的每個對象,先找到其中心點。比如上圖中的自行車,其中心點在黃色圓點位置,中心點落在黃色網格內,所以這個黃色網格對應的30維向量中,自行車的概率是1,其它對象的概率是0。所有其它48個網格的30維向量中,該自行車的概率都是0。這就是所謂的"中心點所在的網格對預測該對象負責"。狗和汽車的分類概率也是同樣的方法填寫。
訓練樣本的bounding box位置應該填寫對象實際的bounding box,但一個對象對應了2個bounding box,該填哪一個呢?上面討論過,需要根據網路輸出的bounding box與對象實際bounding box的IOU來選擇,所以要在訓練過程中動態決定到底填哪一個bounding box。
上面討論過置信度公式 , 可以直接計算出來,就是用網路輸出的2個bounding box與對象真實bounding box一起計算出IOU。
然後看2個bounding box的IOU,哪個比較大(更接近對象實際的bounding box),就由哪個bounding box來負責預測該對象是否存在,即該bounding box的 ,同時對象真實bounding box的位置也就填入該bounding box。另一個不負責預測的bounding box的 。
總的來說就是,與對象實際bounding box最接近的那個bounding box,其 ,該網格的其它bounding box的 。
舉個例子,比如上圖中自行車的中心點位於4行3列網格中,所以輸出tensor中4行3列位置的30維向量如下圖所示。
翻譯成人話就是:4行3列網格位置有一輛自行車,它的中心點在這個網格內,它的位置邊框是bounding box1所填寫的自行車實際邊框。
注意,圖中將自行車的位置放在bounding box1,但實際上是在訓練過程中等網路輸出以後,比較兩個bounding box與自行車實際位置的IOU,自行車的位置(實際bounding box)放置在IOU比較大的那個bounding box(圖中假設是bounding box1),且該bounding box的置信度設為1。
損失就是網路實際輸出值與樣本標簽值之間的偏差。
YOLO給出的損失函數如下:
其中,
是指網格i存在對象;
是指網格i的第j個bounding box中存在對象;
是指網格i的第j個bounding box中不存在對象。
總的來說,就是用網路輸出與樣本標簽的各項內容的誤差平方和作為一個樣本的整體誤差。 損失函數中的幾個項是與輸出的30維向量中的內容相對應的。
公式第5行,注意 意味著存在對象的網格才計入誤差。
公式第1行和第2行。
a) 都帶有 意味著只有"負責"(IOU比較大)預測的那個bounding box的數據才會計入誤差;
b) 第2行寬度和高度先取了平方根,因為如果直接取差值的話,大的對象對差值的敏感度較低,小的對象對差值的敏感度較高,所以取平方根可以降低這種敏感度的差異,使得較大的對象和較小的對象在尺寸誤差上有相似的權重。
c) 乘以 調節bounding box位置誤差的權重(相對分類誤差和置信度誤差)。YOLO設置 ,即調高位置誤差的權重。
公式第3行和第4行。
a) 第3行是存在對象的bounding box的置信度誤差。帶有 意味著只有"負責"(IOU比較大)預測的那個bounding box的置信度才會計入誤差。
b) 第4行是不存在對象的bounding box的置信度誤差。因為不存在對象的bounding box應該老老實實的說"我這里沒有對象",也就是輸出盡量低的置信度。如果它不恰當的輸出較高的置信度,會與真正"負責"該對象預測的那個bounding box產生混淆。其實就像對象分類一樣,正確的對象概率最好是1,所有其它對象的概率最好是0。
c) 第4行乘以 調節不存在對象的bounding box 的置信度的權重(相對其他誤差)。YOLO設置 ,即調低不存在對象的bounding box的置信度誤差的權重。
YOLO先使用ImageNet數據集對前20層卷積網路進行預訓練,然後使用完整的網路,在PASCAL VOC數據集上進行對象識別和定位的訓練和預測。YOLO的網路結構如下圖所示:
YOLO的最後一層採用線性激活函數,其它層都是Leaky ReLU。訓練中採用了dropout和數據增強(data augmentation)來防止過擬合。更多細節請參考原論文。
訓練好的YOLO網路,輸入一張圖片,將輸出一個 7 7 30 的張量(tensor)來表示圖片中所有網格包含的對象(概率)以及該對象可能的2個位置(bounding box)和可信程度(置信度)。 為了從中提取出最有可能的那些對象和位置,YOLO採用NMS(Non-maximal suppression,非極大值抑制)演算法。
NMS方法並不復雜,其核心思想是:選擇得分最高的作為輸出,與該輸出重疊的去掉,不斷重復這一過程直到所有備選處理完。
YOLO的NMS計算方法如下。
網路輸出的7 * 7 * 30的張量,在每一個網格中,對象 位於第j個bounding box的得分: ,它代表著某個對象 存在第j個bounding box的可能性。
每個網格有:20個對象的概率*2個bounding box的置信度,共40個得分(候選對象)。49個網格共1960個得分。Andrew Ng建議每種對象分別進行NMS,那麼每種對象有 1960/20=98 個得分。
NMS步驟如下:
1)設置一個Score的閾值,低於該閾值的候選對象排除掉(將該Score設為0)
2)遍歷每一個對象類別
2.1)遍歷該對象的98個得分
2.1.1)找到Score最大的那個對象及其bounding box,添加到輸出列表
2.1.2)對每個Score不為0的候選對象,計算其與上面2.1.1輸出對象的bounding box的IOU
2.1.3)根據預先設置的IOU閾值,所有高於該閾值(重疊度較高)的候選對象排除掉(將Score設為0)
2.1.4)如果所有bounding box要麼在輸出列表中,要麼Score=0,則該對象類別的NMS完成,返回步驟2處理下一種對象
3)輸出列表即為預測的對象
YOLO以速度見長,處理速度可以達到45fps,其快速版本(網路較小)甚至可以達到155fps。這得益於其識別和定位合二為一的網路設計,而且這種統一的設計也使得訓練和預測可以端到端的進行,非常簡便。
不足之處是小對象檢測效果不太好(尤其是一些聚集在一起的小對象),對邊框的預測准確度不是很高,總體預測精度略低於Fast RCNN。主要是因為網格設置比較稀疏,而且每個網格只預測兩個邊框,另外Pooling層會丟失一些細節信息,對定位存在影響。