轉載請註明做者:夢裏茶git
Faster RCNN在Fast RCNN上更進一步,將Region Proposal也用神經網絡來作,若是說Fast RCNN的最大貢獻是ROI pooling layer和Multi task,那麼RPN(Region Proposal Networks)就是Faster RCNN的最大亮點了。使用RPN產生的proposals比selective search要少不少(300vs2000),所以也必定程度上減小了後面detection的計算量。github
Introduction
Fast RCNN以後,detection的計算瓶頸就卡在了Region Proposal上。一個重要緣由就是,Region Proposal是用CPU算的,可是直接將其用GPU實現一遍也有問題,許多提取規則實際上是能夠重用的,所以有必要找一種可以共享算力的GPU版Region Proposal。網絡
Faster RCNN則是專門訓練了一個卷積神經網絡來回歸bounding box,從而代替region proposal。這個網絡徹底由卷積操做實現,而且引入anchor以應對對象形狀尺寸各異的問題,測試速度與Fast RCNN相比速度極快。ide
這個網絡叫作region proposal layer.函數
RPN
![RPN](http://static.javashuo.com/static/loading.gif)
訓練數據就是圖片和bounding box學習
兩個FC在實現的時候是分別用兩個1x1卷積實現的
![FC](http://static.javashuo.com/static/loading.gif)
以橙色爲例,256向量和W1矩陣相乘,獲得長度爲18的向量,這樣的操做在51x39個feature都要作一遍,實現起來就很天然變成了用一個1x1的卷積核在feature map上作卷積啦,這樣也暗含了一個假設,不一樣位置的slide window對於anchor的偏好是相同的,是一個參數數量與精度的權衡問題。blog
- 因而咱們會獲得圖片上51x39x9≈20K個anchor爲前景的機率,以及修正後的位置
上面這個過程能夠徹底獨立地訓練,獲得一個很好的Region Proposal Network排序
理論上咱們能夠用上面這個流程去訓練RPN,但訓練RPN的時候,一個batch會直接跑20K個anchor開銷太大了。
- 所以每一個batch是採一張圖裏的256個anchor來訓練全鏈接層和卷積層;
- 這256個anchor里正負樣本比例爲1:1,正樣本128個,負樣本128個,
- 若是正樣本不足128個,用負樣本填充,這也意味着並不是全部的背景anchor都會拿來訓練RPN,由於前景的anchor會遠少於背景的anchor,丟掉一些背景anchor才能保證樣本平衡,丟背景anchor的時候
- 具體實現上,先算全部anchor,再算全部anchor與bounding box的重疊率,而後選擇batch中的256個anchor,參與訓練。同一張圖會屢次參與訓練,直到圖中的正anchor用完。
所以最終的一個mini batch的訓練損失函數爲:
![RPN Loss](http://static.javashuo.com/static/loading.gif)
其中,
- pi是一個batch中的多個anchor屬於前景/後景的預測機率向量,ti是一個batch中正anchor對應的bounding box位置向量
- Lcls是softmax二分類損失
- Lreg跟Fast RCNN中的bounding box regression loss同樣,乘一個pi*,意味着只有前景計算bounding box regression loss
- 論文中說Ncls爲256,也就是mini-batch size,Nreg約爲256*9=2304(論文中說約等於2400),這意味着一對p對應9個t,這種對應關係也體如今全鏈接層的輸出個數上,因爲兩個task輸出數量差異比較大,因此要作一下歸一化。
但這就意味着loss中的mini-batch size是以3x3的slide window爲單位的,由於只有slide window和anchor的個數纔有這種1:9的關係,而挑選訓練樣本講的mini-batch size倒是以anchor爲單位的,因此我猜實際操做是這樣的:
- 先選256個anchor,
- 而後找它們對應的256個slide window,
- 而後再算這256個slide window對應的256×9個anchor的loss,每一個slide window對應一個256特徵,有一個Lcls,同時對應9個anchor,有9個Lreg
論文這裏講得超級混亂:
![minibatch anchor](http://static.javashuo.com/static/loading.gif)
Proposal layer
其實這也能夠算是RPN的一部分,不過這部分不須要訓練,因此單獨拉出來說
- 接下來咱們會進入一個proposal layer,根據前面獲得的這些信息,挑選region給後面的fast rcnn訓練
- 圖片輸入RPN後,咱們手頭的信息:anchor,anchor score,anchor location to fix
- 用全鏈接層的位置修正結果修正anchor位置
- 將修正後的anchor按照前景機率從高到底排序,取前6000個
- 邊緣的anchor可能超出原圖的範圍,將嚴重超出邊緣的anchor過濾掉
![Anchor Filter](http://static.javashuo.com/static/loading.gif)
- 對anchor作非極大抑制,跟RCNN同樣的操做
- 再次將剩下的anchor按照anchor score從高到低排序(仍然可能有背景anchor的),取前300個做爲proposals輸出,若是不足300個就…也沒啥關係,好比只有100個就100個來用,其實不足300個的狀況不多的,你想Selective Search都有2000個。
Fast RCNN
接下來就是按照Fast RCNN的模式來訓練了,咱們能夠爲每張圖前向傳播從proposal_layer出來獲得300個proposals,而後
- 取一張圖的128個proposal做爲樣本,一張圖能夠取屢次,直到proposal用完
![](http://static.javashuo.com/static/loading.gif)
- 餵給Fast RCNN作分類和bounding box迴歸,這裏跟RPN很像,但又有所不一樣,
- BB regressor:擬合proposal和bounding box,而非擬合anchor和bounding box
- Classifier:Object多分類,而非前景背景二分類
迭代訓練
RPN和Fast RCNN實際上是很像的,所以能夠必定程度上共享初始權重,實際訓練順序以下(MATLAB版):
- 先用ImageNet pretrain ZF或VGG
- 訓練RPN
- 用RPN獲得的proposal去訓練Fast RCNN
- 用Fast RCNN訓練獲得的網絡去初始化RPN
- 凍結RPN與Fast RCNN共享的卷積層,Fine tune RPN
- 凍結RPN與Fast RCNN共享的卷積層,Fine tune Fast RCNN
論文中還簡單講了一下另外兩種方法:
- 將整個網絡合起來一塊訓練,而不分步,但因爲一開始訓練時RPN還不穩定,因此訓練Fast RCNN用的proposal是固定的anchor,最後效果差很少,訓練速度也快。
![Approximate joint training](http://static.javashuo.com/static/loading.gif)
- 整個網絡合起來一塊兒訓練,不分步,訓練Fast RCNN用的proposals是RPN修正後的anchor,但這種動態的proposal數量很差處理,用的是一種RoI warping layer來解決,這又是另外一篇論文的東西了。
SUMMARY
網絡結構和訓練過程都介紹完了,實驗效果也是依樣畫葫蘆,就再也不介紹了,總體來講,Faster RCNN這篇論文寫得很亂,不少重要的細節都要去看代碼才能知道是怎麼回事,得虧是效果好才能中NIPS。。