YOLOV3總結

Object Dedection一般分爲one stage和two stage兩種框架,one stage的代表有yolo系列、ssd等,two stage的代表有faster rcnn、light head rcnn、rfcn等,本系列會詳細介紹這兩種框架,會從yolov3 到 light head rcnn講起:

首先是yolov3,下圖貼出的是yolov3的框架圖:

上述是yolov3的示意圖,整個yolov3的完整可視化資源已上傳網站,下載地址爲https://download.csdn.net/download/weixin_41015185/10790747,如下載有問題請聯繫作者, 創建一個logdir文件夾,將下載內容放入,注意tensorflow版本是1.10,打開代碼如下:

tensorboard --logdir=logdir

部分graph如下:

output_node:1

output_node:2

output_node:3

final_output:也就是decode的過程,網絡輸出的三種結果經過nms(非極大值抑制)處理生成最終結果:

 

此圖是由pb文件生成,有了完整的graph我們就可以用c++做前向傳播調用了,yolov3的完整輸入輸出結構,丟進一張圖片,輸出最終結果,即目標位置和分類,屬於貓還是狗等,讀者可以根據yolov3的相關代碼結合此圖瞭解整個框架。

假設我們有一張圖片,如下所示:

 

模型訓練時要做 random preprocessing for real-time data augmentation,也就是resize iamge(416,416)維數、flip image、distort image、correct box position等相關操作,獲取如下圖片結果示意:

這是通過data augment生成的訓練數據。

如何從一張輸入的圖片得到用於訓練的y_true值呢,也就是說我們整個網絡三個output_node輸出的結果是(1,13,13,3,4,1,80)、(1,26,26,3,4,1,80)、(1,52,52,3,4,1,80),其中3代表每個維度上對應的三個anchors,一共三個維度輸出,一共9個anchors,4代表box座標值,1代表box置信度,80代表目標分類得分,coco數據集是80分類,那麼我們也要將輸入的圖片轉換成相應維度的真值,我們原始輸入是(416,416,3)維圖片,box爲(x1,y1,x2,y2,class)。那麼我們將原始圖產生的y_true(維度爲[1,13,13,3,85]、[1,26,26,3,85]、[1,52,52,3,85])與預測產生的值也就是網絡輸出的三個output_node結果做loss進行優化。

y_true生成的過程:

首先我們給出的圖片維度是(416,416,3),假設box的大小[241. 193. 275. 249.   0.],box的前四位數是box的座標值,最後一維是class類別索引值,假如我們要做三個分類,那麼輸出維度就是[1,13,13,3,4,1,3],其他輸出類似,比如這三個類別爲貓、狗、羊,我們分別給貓狗羊打上標籤爲0,1,2 , 那麼box的最後一個數就是代表那個分類。yolov3 給出了9個anchors,每三個anchors對應一個輸出維度,通俗點講,就是給除了9個大小不同的box,這9個box是根據給出的所有真值box聚類形成的,具體算法可以百度搜索k_means,這裏假設是[10,13 16,30 33,23 30,61 62,45 59,119 116,90 156,198 373,326],數值爲box的寬和高,這樣既能感受大的物體,也能感受小的物體,[1,13,13,3,8]對應[116,90 156,198 373,326]三個box,[1,26,26,3,8]對應[30,61 62,45 59,119]三個box,[1,52,52,3,8]對應[10,13 16,30 33,23]三個box。好了,原始數據有了,那麼我們怎麼知道這個box[241. 193. 275. 249.   0.]是在[1,13,13,3,8]、[1,26,26,3,8]、[1,52,52,3,8]這三個維度當中那個座標或者我們叫做索引值下呢,這裏我將分類改成3個,而不是80分類,以便於理解。

下圖爲如何求解box中心格子位置索引(這裏有個修正,2.5應該是2,以對應下面計算):

還有一個問題,我們一共由三個維度的輸出(13,13)(26,26)(52,52),那麼我們是如何知道這個box應該索引哪個維度呢,還記得嗎,我們給出了9和anchors,每個維度對應三個anchors,那麼最簡單的原理就是我原始box和這9個當中哪個anchor最像,那麼這個box的索引就是那個維度,同時我們也搞定了(1,13,13,3,8)(1,26,26,3,8)(1,52,52,3,8)的第三個數值3的位置,由此格子的位置和anchor的位置都有了。那麼如何表述最像這件事情呢,用到的一個算法就是IOU,交併比的概念,不熟悉的可以百度。

[[0.06827731 0.25210084 0.39863445 0.81791626 0.48356511 0.27118644  0.18237548 0.06164206 0.01565815]],這裏給出的是[241. 193. 275. 249.   0.]這個box和9個anchor求出的IOU值,在這裏我們可以看出第三個索引值最像,也就是和[30,61]這個anchor最像,而這個anchor屬於(1, 26, 26, 3, 8)這個anchor的第1個位置。

下面是對應的求解位置,讀者可以自行驗算:

box:[241. 193. 275. 249.   0.]

1.首先將box中心座標和寬高歸一化:[ 0.6201923   0.53125     0.08173077  0.13461539  0.       ]  中心座標計算(x2 + x1)/ 2 /416;(y2 + y1)/ 2/416;

2.屬於(26,26)這個維度的第1個anchor位置;

3. (26,26)位置計算,0.6201923 × 26 = 16,0.53125 x 26 = 13;

4.那麼將歸一化的box填進y_true值,這裏我們先前假設定義爲(1,26,26,3,8)的零向量;y_true[1, 16, 13, 1, 0.6201923,   0.53125 ,   0.08173077,  0.13461539, 1, 1, 0 ,0] ,因爲我們box的最後一維是0,也就是屬於貓類,做one_hot,也就是[1 0 0]代表貓,[0 1 0]代表狗[0 0 1]代表羊,第8個維度是1,代表box的置信度。

5.自此除了[1, 16, 13, 1]這個位置有值以外,其他位置全部爲0,那麼我們真實的y_true就這樣產生了。

神經網絡架構:

darknet採用了類似FPN的upsample和融合做法,最後融合了三個scale,這麼做的目的是爲了加強對小目標的檢測,下面就主要說下這個是怎麼實現的,也就是scale1,scale2和scale3之後的部分,之前的部分在很多博客中都有了,其實如果你下載了我給出的可視化資源鏈接,用tensorboard打開看一下,很清楚的就瞭解了darknet的整個網絡架構了。如下圖所示:

這是整個網絡的基本結構。

loss函數及框的預測:

這裏先將以下RCNN的框的預測,以便於好理解一點,看圖:

其中tx = (Gx - Px)/ Pw; ty = (Gy - Px) / Ph; tw = log(Gw/Pw); th = log(Gh/Ph)。

關於Bounding-Box Regression論文中是這麼說的,用一個分類檢測器SVM(支持向量機)給每一個選擇性搜索區域打分之後,用一個指定分類bounding box 迴歸器預測一個新的bounding box,輸入到CNN裏面的訓練數據時{(Pi,Gi)},Pi定義爲(Pxi,Pyi,Pwi,Phi),同樣G也是如此定義,目的就是學習一種變換,將框P映射到真值G上。用四個公式dx(p),dy(P),dw(P),dh(P),來定義這種變換,前兩個參數指定了P中心座標的尺度不變變換,後兩個參數指定了P的高和寬在log空間的變換,當學習完這些參數後,那麼我們就可以將P變換成G^,如平移公式和縮放公式,最終到公式3。在預測框時,定義IOU值爲大於0.6的進行迴歸,這樣做是爲了滿足近似線性轉換條件,想一下,如果P跟G離得很遠,就是複雜非線性問題了,這樣會導致訓練的模型不work,爲什麼IOU較大時認爲是近似線性變換呢,看公式1和公式2就大體瞭解了,那麼問題就有答案了,看公式4和公式5,我們有了真正tx,ty,tw,th,我們學習一組參數Wi,,經過學習之後loss降到最低,現在Wi的值有了,我們丟進去一張proposal的圖像,那麼我們是否就預測出了tx,ty,tw,th的值了呢,有了這些值,是否就是可以計算最終迴歸的框了呢,答案是肯定的。

好了,RCNN的bounding box regressiogn的故事就講完了,如果有誤示,請指正,迴歸到YOLOV3本身上來,我們看下YOLOV3是怎麼做的迴歸的。

同樣是先把這個圖和公式給貼上來:

公式1

 

公式2

 

先做真實值,還記得RCNN嗎,我們是怎麼做的,由RCNN我們可以想到在訓練的時候bx,by,bw,bh就是我們的ground truth,注意,我這裏的說的訓練的過程,而不是預測過程,不能混淆,那麼先前我們已經定義了y_true了,我在這裏在寫一此,它的值爲[1, 26, 26, 3, 8],那麼就這麼定義tw =log(y_true[..., 2:3] / anchors * 416),後先搞清楚一點bw是什麼,因爲y_true是我們歸一化的框的值,那麼我們是不是應該還原回去,乘以個416,所以bw = y_true[..., 2:3]*416,這是bw代表的ground truth是不是就有了呢,似曾相識的感覺,對了這就是RCNN的概念,這也是我要把RCNN貼出來做例子了,同樣的道理,th也是這樣計算的,那麼在看tx和ty,因爲這裏有區別與RCNN,直接寫,sigmoid(tx) = y_true[..., 0:1]*26 - grid,這裏說下grid也就是論文中的cell,那麼bx = y_true[..., 0:1]*26,很好理解嗎,中心座標也是歸一化的,我要知道它在那個格子裏面,是不是也要乘以26,這個前面已經提到了,到此位置我們用y_true產生的tx,ty,tw,th就產生了,這也就是anchor在這裏的作用。

 

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