1. 程式人生 > >目標檢測:fasterRCNN和RFCN演算法的理解

目標檢測:fasterRCNN和RFCN演算法的理解

所有的two-stage detection 演算法大致都由兩部分組成:RPN生成proposal和對proposal的cls和reg。本科做畢設用了Faster RCNN,對此類演算法稍稍有點了解,但是還是很多迷惑。最近本人認真研讀了light head rcnn,對two stage演算法進行了比較,也解答了之前的一些疑惑。列舉: 

1. RPN網路中anchor和proposal的關係

以faster rcnn網路為例,假定輸入到RPN網路的feature map的size為13*13,現定義了3個scales和3個aspect radio,即為13*13feature map上的每個點考慮k=9個框,

anchor實際上就是一組由rpn/generate_anchors.py生成的矩形。RPN中的cls層會輸出(2*9)13*13個分類資訊,為了利用softmax對這麼多框進行背景前景分類,要對(2*9)*13*13進行reshape成2(9*13)*13的size,cls完成後再reshape回來;與此同時,reg層也會輸出(4*9)*13*13個位置偏移量,注意並不是直接輸出位置資訊喔,是通過論文中的公式計算得到位置資訊的。接下來在proposal layer 中,主要有以下幾步:利用[dx(A),dy(A),dw(A),dh(A)]對所有的框做bbox regression迴歸;提取前景pre_nms_topN(e.g. 1000)個框,即提取修正位置後的屬於前景的1000個框;限定超出影象邊界的框為影象邊界(防止後續roi pooling時proposal超出影象邊界);剔除非常小的框;再進行NMS,取出前300個框作為輸出,這些輸出的框就是proposal
.這些過程可以理解為predict過程。在訓練的時候,回傳18*13*13個anchor box,肯定是沒有必要的,具體怎麼做的呢?train的時候隨機選取256個postive anchors box+256個negative anchors box 進行訓練,postive 和negative的界定方法如下:當anchor box與GT間IoU>0.7,認為是該anchor box是foreground;反之IoU<0.3時,認為是該anchor box是background,至於IoU在0.3和0.7之間的anchorbox 則不參與訓練.(具體數字可能不準確,表達出意思即可。train的時候回傳的proposal數目會高於predict過程,且計算IOU是隻在train過程進行)。 

2. 為什麼roi pooling需要proposal 和 feature map兩個輸入

因為在proposal layer第三步中將框映射回原圖判斷是否超出邊界,所以這裡輸出的proposal是對應MxN輸入影象尺度的,所以要想進行後續的cls和reg就必須要把proposal再縮放到feature map的畫素極上,因此在feature上找到proposal對應的位置,進行pooling,所以需要兩個輸入,根本原因就是proposal是針對原圖的。 

對faster rcnn解釋的最清楚的一篇文章奉上:連結 。 

3. RFCN中提出了PSROIPooling的概念,引入了位置敏感的score map

說白了就是因為如果把roipooling層的輸入直接接全連線層用於cls和reg,會讓detection網路對位置不敏感,但是如果讓單個proposal都通過一些卷積層又會導致計算量太大,時間過長。R-FCN可以說是做到了兩全其美,首先對於backbone的最後一層feature map,又接了一層卷積層,幹什麼呢?就是用來處理位置敏感問題的。 

將每個ROI分為k*k個bin,那麼這層卷積層的輸出channel就是k*k*(c+1),怎麼理解這個channel呢? 考慮人這一類,對於檢測人來說top-center就是頭部,bottom-center就是腳。現在就通過對每個bin進行檢測來綜合得到這個roi的檢測結果。如果一個roi的top-center、bottom-center和其他bin都被檢測為頭、腳和人的其他特徵,那麼就都斷定這個roi是人。好,現在以檢測人頭為目標生成一張feature map(這個feature map就是檢測人的top-center),再以人腳為目標生成一張feature map,同理其他bin的特徵也生成對應的feature map,那麼對於人來說就生成k*k個feature map,總共c+1類就生成了k*k*(c+1)維feature map,即score map. 接下來用PSROIPooling的方法去得到每個roi的檢測結果。試想如果roi的位置稍微偏移了一點就意味著每個bins都有移動,那麼將每個bin的檢測結果結合起來,差別就大了,位置敏感性就不言而喻了。 
4. 對於一個network,如果想把roipooling換成PSROIPooling,必須要生成一個score map嗎?答案是否定的,如果使用PSROIPooling層,只需要注意輸入的channel和psroipooling層的output_dim*group_size^2一致即可,至於class相不相同不是很重要了,因為後面可以接一個fc來改變維度。這也就是light head rcnn的一個創新點了,thinner feature map,連結。此處的output_dim為pool後的channel,group_size為pool後的size。