Faster RCNN交替訓練法詳解

對Faster RCNN的詳解類文章實在是數都數不過來,這些詳解類的文章大多是從網絡結構角度出發,對於Faster RCNN的訓練流程介紹的比較少。從我個人的經歷來看,感覺單純的理解網絡結構對Faster RCNN理解的還不夠透徹,尤其是生成有效anchor這一塊。因此本文從Faster RCNN的訓練流程這個角度出發,對Faster RCNN進行詳解,重點對anchor相關的操作進行細緻分支。

本文采用的訓練流程不是基於某個實現,而是基於原論文中3.2小節中給出的“4-Step Alternating Training”(四步交替訓練流程)。

“4-Step Alternating Training”,四步交替訓練流程如下:

  • 訓練RPN

RPN的詳細訓練方法在3.1.3節有詳細介紹:從每幅圖片中生成訓練所需的每組mini-batch數據。每組mini-batch包括若干的正樣本與負樣本,考慮到正負樣本平衡的問題,每組mini-batch不是使用所有的樣本,而是隨機採集256個樣本構成一組mini-batch,正樣本與負樣本數量儘量保持1:1,如果達不到的話,也即正樣本數量不足128的話,就使用負樣本補齊。對於損失函數在此不做分析。

至此RPN的訓練方法已經非常清楚了,接下來就是搞清楚什麼是正負樣本。在本文中正負樣本被稱爲anchor,對於正負anchor的定義在文章的3.1.2節,正anchor的定義包括兩種情況:與groundtruth的IoU最大的anchor,與任何groundtruth的IoU大於0.7anchor。以上兩種情況都被作爲正anchor,其實只有第二種情況基本已經足夠,但爲了保證不會出現一幅圖片一個正anchor都沒有的情況,所以又添加了第一種情況。負樣本是指與groundtruth的IoU的小於0.3的。IoU大於0.3小於0.7的,或者不是正樣本的感覺就不參與訓練。

但是問題又來了,這個anchor不是在最後一層feature map上滑窗獲得的嗎,怎麼和groundtruth算IoU?其實理解這個問題需要理解一個關鍵概念“ROI Projection”,這個概念不是我自己造的,是在SPPnet這篇文章的最後附錄裏提到的一個概念:

有興趣可以仔細的研讀這一段。給大家總結一下,Feature map與原圖的座標可以相互轉化,轉化公式如下,定義xy爲原圖上的點,x{}'y{}'爲該圖經過卷積與池化操作後得到的feature map:

Feature map To origin image

\left ( x \right y) = \left ( Sx{}' \right Sy{}')

其中S是經過卷積與池化操作後得到的縮放倍數。由這裏還有一個重要前提,這個公式成立的前提是做卷積操作時需要對圖做kernel size/2向下取整的padding操作。之所以要做這樣一步,是爲了經過卷積操作後原圖大小保持不變,而經過池化操作後原圖大小變爲原來的1/4,經過幾次池化,就變爲原圖大小的\frac{1}{2^{^{n}}}

至此已經分析完了,一個anchor與原圖上一個點的對應關係,這還不夠,僅靠一個anchor還無法學習不同尺度的物體特徵,因此本文中一個anchor對的是原圖上9個不同大小的採樣框。具體來說就是3種不同的大小與3種不同的長寬比,原文中給出的三種不同大小是128*128,256*256,512*512,三種不同的長寬比是1:1,1:2和2:1。

以128*128大小舉個例子,1:1大小非常好理解,就是128*128大小的採樣框,以這個大小爲滑窗在原圖上滑動,在每個滑動位置查看是否有groundtruth爲正樣本,或者是負樣本。好了滑窗大小我們已經有了,滑窗位置我們就可以根據上面的公式算出在原圖上的位置。比如對於feature map上的(0,0)點,其在原圖上的座標還是(0,0),滑窗就是應該是(-64,-64,64,64)以上四個值分別爲(left_top_x,left_top_y,right_buttom_x,right_buttom_y)。這個計算方法對不對?可以通過作者給出的實現的示例進行驗證(從我看到的一些資料上看,有一個generate_anchor.py可以生成(0,0)點處的anchor,我沒有跑這個程序,直接把結果貼出來):

[[ -84.  -40.   99.   55.]
 [-176.  -88.  191.  103.]
 [-360. -184.  375.  199.]
 [ -56.  -56.   71.   71.]
 [-120. -120.  135.  135.]
 [-248. -248.  263.  263.]
 [ -36.  -80.   51.   95.]
 [ -80. -168.   95.  183.]
 [-168. -344.  183.  359.]]

通過對比可以發現,第四行的結果就是大小爲128*128,長寬比爲1:1,中心點座標爲(0,0)處的採樣框。

通過以上過程就可以大約生成共20000個採樣框,此處以文中給出的例子爲例,原圖大小爲1000*600,經過4次卷積與池化操作後,生成的feature map大小約爲60*40(1000/16=62.5,600/16=37.5),每個feature map像素對應有9個anchor,所以共有約60*40*9,共20000個採樣框,去除掉出圖的採樣框還剩約6000個。

至此所有的採樣框已經生成完畢,從6000個anchor中隨機採樣選出256個候選框用於訓練RPN網絡,至此RPN網絡的訓練流程就分析完了。其實Faster RCNN的核心內容至此已經分析的差不多了。

總結一下:訓練RPN送入網絡的是256個候選框,groundtruth是與之配對的boundingbox,對於負樣本就沒有boundingbox就沒有迴歸框任務,只有分類任務。我們可以發現爲了選擇候選框,一共進行了3次選擇:

1)首先是生成了大約20000個候選框。

2)去除掉其中與邊緣相交的,選擇其中大約6000個。

3)最後在6000箇中選擇其中256個用於訓練。

特別注意:訓練RPN的過程是沒有“generate proposal”的過程的,也就是不會有NMS的過程。以何爲證:stage1_rpn_train.pt文件中就沒有“ProposalLayer”層。先說stage1_rpn_train.pt文件,這個文件是FasterRCNN原版實現中交替訓練法的prototext文件,“ProposalLayer”層的定義位於“proposal_layer.py”文件中,其功能是根據RPN生成的候選框應用NMS算法進行過濾,生成最終的候選框。“generate proposal”其實是在RPN訓練之後,Fast RCNN訓練之前,其結果全部寫到硬盤中。

  • 訓練Fast RCNN

此時使用RPN產生的候選框互相之間交疊會比較大,也即冗餘非常多,所以要對RPN產生的候選框執行進一步執行NMS操作,這正是“ProposalLayer”層的作用。

ProposalLayer的作用不僅限於應用NMS,在應用NMS前首先對RPN的結果進行過濾。首先對大約20000個anchor的迴歸框結果進行過濾,過濾的標準是proposal的height與width均需要大於RPN_MIN_SIZE。

然後應用NMS。NMS的排序標準是分類的分數(此處是正負候選框的分數),NMS閾值是0.7,經過這一步操作後大約還剩2000個候選框,選擇其中top-N個框訓練Fast RCNN網絡。

其中有兩個重要的參數:RPN_PRE_NMS_TOP_N、RPN_POST_NMS_TOP_N又分爲train、test,train的值分別爲12000,2000,也即在訓練Fast RCNN過程中,使用已經訓練好的RPN網絡生成proposal,在對框進行過濾後、應用NMS前保留其分數最高的前12000個框,應用NMS後保留正類樣本的2000個框。test的值分別爲6000,300。應用方式相同。

有了NMS的結果,就可以用於替代原來Fast RCNN中使用的Selective Search算法生成候選。這一步不再訓練RPN而是利用RPN產生region proposal,將region proposal送入Fast RCNN進行訓練。此時Fast RCNN與RPN還不共享卷積層參數,是兩個完全獨立的網絡。

  • finetune RPN

爲了finetune RPN首先,使用Fast RCNN的參數初始化RPN,同時保持RPN與Fast RCNN共享的參數保持不變,僅finetune RPN自己的層,通過以上操作,RPN就與Fast RCNN共享卷積層參數。

  • finetune Fast RCNN

保持共享的卷積層參數保持不變,僅finetune Fast-RCNN自己的層。

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