天天看點

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

文章剖析很全面,轉自厲害的樓主大大:https://zhuanlan.zhihu.com/p/31426458

經過R-CNN和Fast R-CNN的積澱,Ross B. Girshick在2016年提出了新的Faster R-CNN,在結構上,Faster R-CNN已經将特征抽取(feature extraction),proposal提取,bounding box regression(rect refine),classification都整合在了一個網絡中,使得綜合性能有較大提高,在檢測速度方面尤為明顯。

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

圖1 Faster CNN基本結構(來自原論文)

依作者看來,如圖1,Faster R-CNN其實可以分為4個主要内容:

  1. Conv layers。作為一種CNN網絡目标檢測方法,Faster R-CNN首先使用一組基礎的conv+relu+pooling層提取image的feature maps。該feature maps被共享用于後續RPN層和全連接配接層。
  2. Region Proposal Networks。RPN網絡用于生成region proposals。該層通過softmax判斷anchors屬于foreground或者background,再利用bounding box regression修正anchors獲得精确的proposals。
  3. Roi Pooling。該層收集輸入的feature maps和proposals,綜合這些資訊後提取proposal feature maps,送入後續全連接配接層判定目标類别。
  4. Classification。利用proposal feature maps計算proposal的類别,同時再次bounding box regression獲得檢測框最終的精确位置。

是以本文以上述4個内容作為切入點介紹Faster R-CNN網絡。

圖2展示了python版本中的VGG16模型中的faster_rcnn_test.pt的網絡結構,可以清晰的看到該網絡對于一副任意大小PxQ的圖像,首先縮放至固定大小

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

,然後将

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

圖像送入網絡;而Conv layers中包含了13個conv層+13個relu層+4個pooling層;RPN網絡首先經過

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

卷積,再分别生成foreground anchors與bounding box regression偏移量,然後計算出proposals;而Roi Pooling層則利用proposals從feature maps中提取proposal feature送入後續全連接配接和softmax網絡作classification(即分類proposal到底是什麼object)。

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

                                   圖2 faster_rcnn_test.pt網絡結構 (pascal_voc/VGG16/faster_rcnn_alt_opt/faster_rcnn_test.pt)

本文不會讨論任何關于R-CNN家族的曆史,分析清楚最新的Faster R-CNN就夠了,并不需要追溯到那麼久。實話說我也不了解R-CNN,更不關心。有空不如看看新算法。

1 Conv layers

Conv layers包含了conv,pooling,relu三種層。以python版本中的VGG16模型中的faster_rcnn_test.pt的網絡結構為例,如圖2,Conv layers部分共有13個conv層,13個relu層,4個pooling層。這裡有一個非常容易被忽略但是又無比重要的資訊,在Conv layers中:

  1. 所有的conv層都是:
    【深度學習Faster-RCNN】深刻解讀Faster R-CNN
    【深度學習Faster-RCNN】深刻解讀Faster R-CNN
    【深度學習Faster-RCNN】深刻解讀Faster R-CNN
  2. 所有的pooling層都是:
    【深度學習Faster-RCNN】深刻解讀Faster R-CNN
    【深度學習Faster-RCNN】深刻解讀Faster R-CNN
    【深度學習Faster-RCNN】深刻解讀Faster R-CNN

為何重要?在Faster RCNN Conv layers中對所有的卷積都做了擴邊處理(

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

,即填充一圈0),導緻原圖變為

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

大小,再做3x3卷積後輸出

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

。正是這種設定,導緻Conv layers中的conv層不改變輸入和輸出矩陣大小。如圖3:

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

                                                                                圖3 卷積示意圖

類似的是,Conv layers中的pooling層

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

。這樣每個經過pooling層的

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

矩陣,都會變為

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

大小。綜上所述,在整個Conv layers中,conv和relu層不改變輸入輸出大小,隻有pooling層使輸出長寬都變為輸入的1/2。

那麼,一個

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

大小的矩陣經過Conv layers固定變為

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

!這樣Conv layers生成的featuure map中都可以和原圖對應起來。

2 Region Proposal Networks(RPN)

經典的檢測方法生成檢測框都非常耗時,如OpenCV adaboost使用滑動視窗+圖像金字塔生成檢測框;或如R-CNN使用SS(Selective Search)方法生成檢測框。而Faster R-CNN則抛棄了傳統的滑動視窗和SS方法,直接使用RPN生成檢測框,這也是Faster R-CNN的巨大優勢,能極大提升檢測框的生成速度。

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

                                                                            圖4 RPN網絡結構

上圖4展示了RPN網絡的具體結構。可以看到RPN網絡實際分為2條線,上面一條通過softmax分類anchors獲得foreground和background(檢測目标是foreground),下面一條用于計算對于anchors的bounding box regression偏移量,以獲得精确的proposal。而最後的Proposal層則負責綜合foreground anchors和bounding box regression偏移量擷取proposals,同時剔除太小和超出邊界的proposals。其實整個網絡到了Proposal Layer這裡,就完成了相當于目标定位的功能。

2.1 多通道圖像卷積基礎知識介紹

在介紹RPN前,還要多解釋幾句基礎知識,已經懂的看官老爺跳過就好。

  1. 對于單通道圖像+單卷積核做卷積,第一章中的圖3已經展示了;
  2. 對于多通道圖像+多卷積核做卷積,計算方式如下:
【深度學習Faster-RCNN】深刻解讀Faster R-CNN

                                                              圖5 多通道卷積計算方式

如圖5,輸入有3個通道,同時有2個卷積核。對于每個卷積核,先在輸入3個通道分别作卷積,再将3個通道結果加起來得到卷積輸出。是以對于某個卷積層,無論輸入圖像有多少個通道,輸出圖像通道數總是等于卷積核數量!

對多通道圖像做

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

卷積,其實就是将輸入圖像于每個通道乘以卷積系數後加在一起,即相當于把原圖像中本來各個獨立的通道“聯通”在了一起。

2.2 anchors

提到RPN網絡,就不能不說anchors。所謂anchors,實際上就是一組由rpn/generate_anchors.py生成的矩形。直接運作作者demo中的generate_anchors.py可以得到以下輸出:

[[ -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.]]
           

其中每行的4個值

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

代表矩形左上和右下角點坐标。9個矩形共有3種形狀,長寬比為大約為

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

三種,如圖6。實際上通過anchors就引入了檢測中常用到的多尺度方法。

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

圖6 anchors示意圖

注:關于上面的anchors size,其實是根據檢測圖像設定的。在python demo中,會把任意大小的輸入圖像reshape成

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

(即圖2中的M=800,N=600)。再回頭來看anchors的大小,anchors中長寬

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

中最大為

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

,長寬

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

中最大

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

,基本是cover了

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

的各個尺度和形狀。

那麼這9個anchors是做什麼的呢?借用Faster RCNN論文中的原圖,如圖7,周遊Conv layers計算獲得的feature maps,為每一個點都配備這9種anchors作為初始的檢測框。這樣做獲得檢測框很不準确,不用擔心,後面還有2次bounding box regression可以修正檢測框位置。

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

圖7

解釋一下上面這張圖的數字。

  1. 在原文中使用的是ZF model中,其Conv Layers中最後的conv5層num_output=256,對應生成256張特征圖,是以相當于feature map每個點都是256-dimensions
  2. 在conv5之後,做了rpn_conv/3x3卷積且num_output=256,相當于每個點又融合了周圍3x3的空間資訊(猜測這樣做也許更魯棒?反正我沒測試),同時256-d不變(如圖4和圖7中的紅框)
  3. 假設在conv5 feature map中每個點上有k個anchor(預設k=9),而每個anhcor要分foreground和background,是以每個點由256d feature轉化為cls=2k scores;而每個anchor都有[x, y, w, h]對應4個偏移量,是以reg=4k coordinates
  4. 補充一點,全部anchors拿去訓練太多了,訓練程式會在合适的anchors中随機選取128個postive anchors+128個negative anchors進行訓練(什麼是合适的anchors下文5.1有解釋)

注意,在本文講解中使用的VGG conv5 num_output=512,是以是512d,其他類似.....

2.3 softmax判定foreground與background

一副MxN大小的矩陣送入Faster RCNN網絡後,到RPN網絡變為(M/16)x(N/16),不妨設

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

。在進入reshape與softmax之前,先做了1x1卷積,如圖8:

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

                                                        圖8 RPN中判定fg/bg網絡結構

該1x1卷積的caffe prototxt定義如下:

layer {
  name: "rpn_cls_score"
  type: "Convolution"
  bottom: "rpn/output"
  top: "rpn_cls_score"
  convolution_param {
    num_output: 18   # 2(bg/fg) * 9(anchors)
    kernel_size: 1 pad: 0 stride: 1
  }
}
           

可以看到其num_output=18,也就是經過該卷積的輸出圖像為

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

大小(注意第二章開頭提到的卷積計算方式)。這也就剛好對應了feature maps每一個點都有9個anchors,同時每個anchors又有可能是foreground和background,所有這些資訊都儲存

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

大小的矩陣。為何這樣做?後面接softmax分類獲得foreground anchors,也就相當于初步提取了檢測目标候選區域box(一般認為目标在foreground anchors中)。

那麼為何要在softmax前後都接一個reshape layer?其實隻是為了便于softmax分類,至于具體原因這就要從caffe的實作形式說起了。在caffe基本資料結構blob中以如下形式儲存資料:

blob=[batch_size, channel,height,width]

對應至上面的儲存bg/fg anchors的矩陣,其在caffe blob中的存儲形式為

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

。而在softmax分類時需要進行fg/bg二分類,是以reshape layer會将其變為

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

大小,即單獨“騰空”出來一個次元以便softmax分類,之後再reshape回複原狀。貼一段caffe softmax_loss_layer.cpp的reshape函數的解釋,非常精辟:

"Number of labels must match number of predictions; "
"e.g., if softmax axis == 1 and prediction shape is (N, C, H, W), "
"label count (number of labels) must be N*H*W, "
"with integer values in {0, 1, ..., C-1}.";
           

綜上所述,RPN網絡中利用anchors和softmax初步提取出foreground anchors作為候選區域。

2.4 bounding box regression原理

介紹bounding box regression數學模型及原理。如圖9所示綠色框為飛機的Ground Truth(GT),紅色為提取的foreground anchors,那麼即便紅色的框被分類器識别為飛機,但是由于紅色的框定位不準,這張圖相當于沒有正确的檢測出飛機。是以我們希望采用一種方法對紅色的框進行微調,使得foreground anchors和GT更加接近。

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

圖9

對于視窗一般使用四維向量

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

表示,分别表示視窗的中心點坐标和寬高。對于圖 10,紅色的框A代表原始的Foreground Anchors,綠色的框G代表目标的GT,我們的目标是尋找一種關系,使得輸入原始的anchor A經過映射得到一個跟真實視窗G更接近的回歸視窗G',即:

  • 給定:anchor
    【深度學習Faster-RCNN】深刻解讀Faster R-CNN
    【深度學習Faster-RCNN】深刻解讀Faster R-CNN
  • 尋找一種變換F,使得:
    【深度學習Faster-RCNN】深刻解讀Faster R-CNN
    ,其中
    【深度學習Faster-RCNN】深刻解讀Faster R-CNN
【深度學習Faster-RCNN】深刻解讀Faster R-CNN

圖10

那麼經過何種變換F才能從圖10中的anchor A變為G'呢? 比較簡單的思路就是:

  • 先做平移
【深度學習Faster-RCNN】深刻解讀Faster R-CNN
  • 再做縮放
【深度學習Faster-RCNN】深刻解讀Faster R-CNN

觀察上面4個公式發現,需要學習的是

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

這四個變換。當輸入的anchor A與GT相差較小時,可以認為這種變換是一種線性變換, 那麼就可以用線性回歸來模組化對視窗進行微調(注意,隻有當anchors A和GT比較接近時,才能使用線性回歸模型,否則就是複雜的非線性問題了)。

接下來的問題就是如何通過線性回歸獲得

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

了。線性回歸就是給定輸入的特征向量X, 學習一組參數W, 使得經過線性回歸後的值跟真實值Y非常接近,即

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

。對于該問題,輸入X是一張經過卷積獲得的feature map,定義為Φ;同時還有訓練傳入的GT,即

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

。輸出是

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

四個變換。那麼目标函數可以表示為:

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

其中Φ(A)是對應anchor的feature map組成的特征向量,w是需要學習的參數,d(A)是得到的預測值(*表示 x,y,w,h,也就是每一個變換對應一個上述目标函數)。為了讓預測值

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

與真實值差距最小,設計損失函數:

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

函數優化目标為:

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

需要說明,隻有在GT與需要回歸框位置比較接近時,才可近似認為上述線性變換成立。

說完原理,對應于Faster RCNN原文,foreground anchor與ground truth之間的平移量

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

與尺度因子

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

如下:

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

對于訓練bouding box regression網絡回歸分支,輸入是cnn feature Φ,監督信号是Anchor與GT的差距

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

,即訓練目标是:輸入 Φ的情況下使網絡輸出與監督信号盡可能接近。

那麼當bouding box regression工作時,再輸入Φ時,回歸網絡分支的輸出就是每個Anchor的平移量和變換尺度

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

,顯然即可用來修正Anchor位置了。

2.5 對proposals進行bounding box regression

在了解bounding box regression後,再回頭來看RPN網絡第二條線路,如圖11。

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

                                                 圖11 RPN中的bbox reg

先來看一看上圖11中1x1卷積的caffe prototxt定義:

layer {
  name: "rpn_bbox_pred"
  type: "Convolution"
  bottom: "rpn/output"
  top: "rpn_bbox_pred"
  convolution_param {
    num_output: 36   # 4 * 9(anchors)
    kernel_size: 1 pad: 0 stride: 1
  }
}
           

可以看到其num_output=36,即經過該卷積輸出圖像為WxHx36,在caffe blob存儲為[1, 36, H, W],這裡相當于feature maps每個點都有9個anchors,每個anchors又都有4個用于回歸的

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

變換量。

2.6 Proposal Layer

Proposal Layer負責綜合所有

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

變換量和foreground anchors,計算出精準的proposal,送入後續RoI Pooling Layer。還是先來看看Proposal Layer的caffe prototxt定義:

layer {
  name: 'proposal'
  type: 'Python'
  bottom: 'rpn_cls_prob_reshape'
  bottom: 'rpn_bbox_pred'
  bottom: 'im_info'
  top: 'rois'
  python_param {
    module: 'rpn.proposal_layer'
    layer: 'ProposalLayer'
    param_str: "'feat_stride': 16"
  }
}
           

Proposal Layer有3個輸入:fg/bg anchors分類器結果rpn_cls_prob_reshape,對應的bbox reg的

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

變換量rpn_bbox_pred,以及im_info;另外還有參數feat_stride=16,這和圖4是對應的。

首先解釋im_info。對于一副任意大小PxQ圖像,傳入Faster RCNN前首先reshape到固定

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

,im_info=[M, N, scale_factor]則儲存了此次縮放的所有資訊。然後經過Conv Layers,經過4次pooling變為

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

大小,其中feature_stride=16則儲存了該資訊,用于計算anchor偏移量。

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

                                                                                 圖12

Proposal Layer forward(caffe layer的前傳函數)按照以下順序依次處理:

  1. 生成anchors,利用
    【深度學習Faster-RCNN】深刻解讀Faster R-CNN
    對所有的anchors做bbox regression回歸(這裡的anchors生成和訓練時完全一緻)
  2. 按照輸入的foreground softmax scores由大到小排序anchors,提取前pre_nms_topN(e.g. 6000)個anchors,即提取修正位置後的foreground anchors。
  3. 限定超出圖像邊界的foreground anchors為圖像邊界(防止後續roi pooling時proposal超出圖像邊界)
  4. 剔除非常小(width<threshold or height<threshold)的foreground anchors
  5. 進行nonmaximum suppression
  6. 再次按照nms後的foreground softmax scores由大到小排序fg anchors,提取前post_nms_topN(e.g. 300)結果作為proposal輸出。

之後輸出

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

,注意,由于在第三步中将anchors映射回原圖判斷是否超出邊界,是以這裡輸出的proposal是對應

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

輸入圖像尺度的,這點在後續網絡中有用。另外我認為,嚴格意義上的檢測應該到此就結束了,後續部分應該屬于識别了~

RPN網絡結構就介紹到這裡,總結起來就是:

生成anchors -> softmax分類器提取fg anchors -> bbox reg回歸fg anchors -> Proposal Layer生成proposals

3 RoI pooling

而RoI Pooling層則負責收集proposal,并計算出proposal feature maps,送入後續網絡。從圖2中可以看到Rol pooling層有2個輸入:

  1. 原始的feature maps
  2. RPN輸出的proposal boxes(大小各不相同)

3.1 為何需要RoI Pooling

先來看一個問題:對于傳統的CNN(如AlexNet,VGG),當網絡訓練好後輸入的圖像尺寸必須是固定值,同時網絡輸出也是固定大小的vector or matrix。如果輸入圖像大小不定,這個問題就變得比較麻煩。有2種解決辦法:

  1. 從圖像中crop一部分傳入網絡
  2. 将圖像warp成需要的大小後傳入網絡
【深度學習Faster-RCNN】深刻解讀Faster R-CNN

                                                                     圖13 crop與warp破壞圖像原有結構資訊

兩種辦法的示意圖如圖13,可以看到無論采取那種辦法都不好,要麼crop後破壞了圖像的完整結構,要麼warp破壞了圖像原始形狀資訊。

回憶RPN網絡生成的proposals的方法:對foreground anchors進行bounding box regression,那麼這樣獲得的proposals也是大小形狀各不相同,即也存在上述問題。是以Faster R-CNN中提出了RoI Pooling解決這個問題。

不過RoI Pooling确實是從Spatial Pyramid Pooling發展而來,但是限于篇幅這裡略去不講,有興趣的讀者可以自行查閱相關論文。

3.2 RoI Pooling原理

分析之前先來看看RoI Pooling Layer的caffe prototxt的定義:

layer {
  name: "roi_pool5"
  type: "ROIPooling"
  bottom: "conv5_3"
  bottom: "rois"
  top: "pool5"
  roi_pooling_param {
    pooled_w: 7
    pooled_h: 7
    spatial_scale: 0.0625 # 1/16
  }
}
           

其中有新參數

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

,另外一個參數

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

認真閱讀的讀者肯定已經知道知道用途。

RoI Pooling layer forward過程:在之前有明确提到:

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

是對應MxN尺度的,是以首先使用spatial_scale參數将其映射回

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

大小的feature maps尺度;之後将每個proposal水準和豎直分為pooled_w和pooled_h份,對每一份都進行max pooling處理。這樣處理後,即使大小不同的proposal,輸出結果都是

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

大小,實作了fixed-length output(固定長度輸出)。

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

                                                            圖14 proposal示意圖

4 Classification

Classification部分利用已經獲得的proposal feature maps,通過full connect層與softmax計算每個proposal具體屬于那個類别(如人,車,電視等),輸出cls_prob機率向量;同時再次利用bounding box regression獲得每個proposal的位置偏移量bbox_pred,用于回歸更加精确的目标檢測框。Classification部分網絡結構如圖15。

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

                                                     圖15 Classification部分網絡結構圖

從PoI Pooling擷取到7x7=49大小的proposal feature maps後,送入後續網絡,可以看到做了如下2件事:

  1. 通過全連接配接和softmax對proposals進行分類,這實際上已經是識别的範疇了
  2. 再次對proposals進行bounding box regression,擷取更高精度的rect box

這裡來看看全連接配接層InnerProduct layers,簡單的示意圖如圖16,

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

圖16 全連接配接層示意圖

其計算公式如下:

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

其中W和bias B都是預先訓練好的,即大小是固定的,當然輸入X和輸出Y也就是固定大小。是以,這也就印證了之前Roi Pooling的必要性。到這裡,我想其他内容已經很容易了解,不在贅述了。

5 Faster R-CNN訓練

Faster R-CNN的訓練,是在已經訓練好的model(如VGG_CNN_M_1024,VGG,ZF)的基礎上繼續進行訓練。實際中訓練過程分為6個步驟:

  1. 在已經訓練好的model上,訓練RPN網絡,對應stage1_rpn_train.pt
  2. 利用步驟1中訓練好的RPN網絡,收集proposals,對應rpn_test.pt
  3. 第一次訓練Fast RCNN網絡,對應stage1_fast_rcnn_train.pt
  4. 第二訓練RPN網絡,對應stage2_rpn_train.pt
  5. 再次利用步驟4中訓練好的RPN網絡,收集proposals,對應rpn_test.pt
  6. 第二次訓練Fast RCNN網絡,對應stage2_fast_rcnn_train.pt

可以看到訓練過程類似于一種“疊代”的過程,不過隻循環了2次。至于隻循環了2次的原因是應為作者提到:"A similar alternating training can be run for more iterations, but we have observed negligible improvements",即循環更多次沒有提升了。接下來本章以上述6個步驟講解訓練過程。

5.1 訓練RPN網絡

在該步驟中,首先讀取RBG提供的預訓練好的model(本文使用VGG),開始疊代訓練。來看看stage1_rpn_train.pt網絡結構,如圖17。

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

圖17 stage1_rpn_train.pt(考慮圖檔大小,Conv Layers中所有的層都畫在一起了,如紅圈所示,後續圖都如此處理)

與檢測網絡類似的是,依然使用Conv Layers提取feature maps。整個網絡使用的Loss如下:

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

上述公式中,i表示anchors index,

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

表示foreground softmax predict機率,

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

代表對應的GT predict機率(即當第i個anchor與GT間

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

,認為是該anchor是foreground,

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

;反之

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

時,認為是該anchor是background,

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

;至于那些

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

的anchor則不參與訓練);

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

代表predict bounding box,

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

代表對應foreground anchor對應的GT box。可以看到,整個Loss分為2部分:

  1. cls loss,即rpn_cls_loss層計算的softmax loss,用于分類anchors為forground與background的網絡訓練
  2. reg loss,即rpn_loss_bbox層計算的soomth L1 loss,用于bounding box regression網絡訓練。注意在該loss中乘了
    【深度學習Faster-RCNN】深刻解讀Faster R-CNN
    ,相當于隻關心foreground anchors的回歸(其實在回歸中也完全沒必要去關心background)。

由于在實際過程中,

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

差距過大,用參數λ平衡二者(如

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

時設定

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

),使總的網絡Loss計算過程中能夠均勻考慮2種Loss。這裡比較重要是Lreg使用的soomth L1 loss,計算公式如下:

【深度學習Faster-RCNN】深刻解讀Faster R-CNN
【深度學習Faster-RCNN】深刻解讀Faster R-CNN

了解數學原理後,反過來看圖17:

  1. 在RPN訓練階段,rpn-data(python AnchorTargetLayer)層會按照和test階段Proposal層完全一樣的方式生成Anchors用于訓練
  2. 對于rpn_loss_cls,輸入的rpn_cls_scors_reshape和rpn_labels分别對應
    【深度學習Faster-RCNN】深刻解讀Faster R-CNN
    【深度學習Faster-RCNN】深刻解讀Faster R-CNN
    【深度學習Faster-RCNN】深刻解讀Faster R-CNN
    參數隐含在
    【深度學習Faster-RCNN】深刻解讀Faster R-CNN
    【深度學習Faster-RCNN】深刻解讀Faster R-CNN
    的caffe blob的大小中
  3. 對于rpn_loss_bbox,輸入的rpn_bbox_pred和rpn_bbox_targets分别對應
    【深度學習Faster-RCNN】深刻解讀Faster R-CNN
    【深度學習Faster-RCNN】深刻解讀Faster R-CNN
    ,rpn_bbox_inside_weigths對應
    【深度學習Faster-RCNN】深刻解讀Faster R-CNN
    ,rpn_bbox_outside_weigths未用到(從soomth_L1_Loss layer代碼中可以看到),而
    【深度學習Faster-RCNN】深刻解讀Faster R-CNN
    同樣隐含在caffe blob大小中

這樣,公式與代碼就完全對應了。特别需要注意的是,在訓練和檢測階段生成和存儲anchors的順序完全一樣,這樣訓練結果才能被用于檢測!

5.2 通過訓練好的RPN網絡收集proposals

在該步驟中,利用之前的RPN網絡,擷取proposal rois,同時擷取foreground softmax probability,如圖18,然後将擷取的資訊儲存在python pickle檔案中。該網絡本質上和檢測中的RPN網絡一樣,沒有什麼差別。

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

圖18 rpn_test.pt

5.3 訓練Faster RCNN網絡

讀取之前儲存的pickle檔案,擷取proposals與foreground probability。從data層輸入網絡。然後:

  1. 将提取的proposals作為rois傳入網絡,如圖19藍框
  2. 計算bbox_inside_weights+bbox_outside_weights,作用與RPN一樣,傳入soomth_L1_loss layer,如圖19綠框

這樣就可以訓練最後的識别softmax與最終的bounding box regression了,如圖19。

【深度學習Faster-RCNN】深刻解讀Faster R-CNN

圖19 stage1_fast_rcnn_train.pt

之後的stage2訓練都是大同小異,不再贅述了。

Faster R-CNN還有一種end-to-end的訓練方式,可以一次完成train,有興趣請自己看作者GitHub吧。

Faster R-CNN github

Faster R-CNN paper

PS:我知道你們想問,畫圖工具:netscope

這篇文章是我2年前寫的,當時都沒有tensorflow。

還有,經過這麼長時間,原作者rbg的github repo也已經改了很多東西。

是以拒絕回答一切類似“怎麼xxx參數和xxx的版本不一樣“的問題。

建議多關心新算法吧,别再沉迷于古董級的Faster R-CNN了。

繼續閱讀