1. 程式人生 > >Faster rcnn程式碼解析

Faster rcnn程式碼解析

最近工作需要,對faster rcnn的程式碼進行了研究。faster rcnn中除開常規的神經網路部分之外,最終要的部分應該是資料的讀取和組織,論文中提到的anchor的生成,以及如何使用這些anchor去進行loss的計算,pooling layer也是一個custom layer,, 但並不是本文的創新,在fast rcnn中就有提到。

首先我們來看資料讀取和組織的部分。faster rcnn的訓練有幾種方法,這裡就說論文提到的第一種方法,它的訓練分成多個階段,在第一個階段中,首先對RPN網路進行訓練,然後是用第一部分產生的propasal對fast rcnn網路進行訓練。

在訓練RPN網路時,通過get_roidb()函式獲得roidb和imdb。imdb實際指的就是圖片資料,而roidb指的是圖片對應的ground_truth label。imdb通過get_imdb獲得,會返回一個pascal_voc物件。而roidb是通過roidb獲得。roidb擁有@property裝飾器,可以當做屬性使用。roidb函式會呼叫roidb_handler,而在之前,這個handler被為gt_roidb(),它會讀取所有圖片的annotation.

下面看一下讀取到的image和anotation是如何送到網路中去的

<span style="font-size:12px;">name: "ZF"</span>
layer {
  name: 'input-data'
  type: 'Python'
  top: 'data'
  top: 'im_info'
  top: 'gt_boxes'
  python_param {
    module: 'roi_data_layer.layer'
    layer: 'RoIDataLayer'
    param_str: "'num_classes': 21"
  }
}<span style="font-size:14px;">
</span>


這是caffe的網路定義的檔案有關input layer的描述,可以看到會輸出data,im_info和gt_boxes三個資料。這是一個定製的python實現的layer,下面看看這個layer做了些什麼。在這個layer的實現中,主要看forward()函式,它通過_get_next_minibatch()獲得一個batch中的資料。這其中組織資料的邏輯是,通過之前設定的roidb中圖片的index來獲得對應的imdb中對應的圖片資料,根據對圖片資料的縮放,會對相應的label也進行調整,最後生成一個blobs。blobs中裝著data, gt_boxes和im_info這三個資料。在訓練RPN net時,batchsize是1,也就是說每次只輸入一個ground truth label進行訓練。下圖展示input layer資料的流向。


接下來我們再來看anchor的生成以及如何用anchor來計算loss。從下圖可以看出,anchor是在rpn-data這一層中生成的,在AnchorTargetLayer的setup函式中,

<span style="font-size:12px;">anchor_scales = layer_params.get('scales', (8, 16, 32))</span>
首先設定anchor的縮放比例,之後來產生anchor。generate_anchors()函式產生9個不同的anchor, 對於一個大小為H*W的特徵層,它上面每一個畫素點對應9個anchor,這裡有一個重要的引數feat_stride = 16, 它表示特徵層上移動一個點,對應原圖移動16個畫素點(看一看網路中的stride就明白16的來歷了)。把這9個anchor的座標進行平移操作,獲得在原圖上的座標。之後根據ground truth label和這些anchor之間的關係生成rpn_lables,具體的方法論文中有提到,根據overlap來計算,這裡就不詳細說明了,生成的rpn_labels中,positive的位置被置為1,negative的位置被置為0,其他的為-1。box_target通過_compute_targets()函式生成,這個函式實際上是尋找每一個anchor最匹配的ground truth box, 然後進行論文中提到的box座標的轉化。


個人理解,這種設定anchor和計算box_targets的方式使網路能夠學習到不同anchor預測和它相近框的能力。