Faster RCNN 學習筆記


下面的介紹都是基於VGG16 Faster RCNN網絡,各網絡的差異在於Conv layers層提取特征時有細微差異,至於后續的RPN層、Pooling層及全連接的分類和目標定位基本相同.

 

一)、整體框架

我們先整體的介紹下上圖中各層主要的功能

1)Conv layers提取特征圖:

作為一種CNN網絡目標檢測方法,Faster RCNN首先使用一組基礎的conv+relu+pooling層提取input imagefeature maps,feature maps會用於后續的RPN層和全連接層

2)RPN(Region Proposal Networks):

    RPN網絡主要用於生成region proposals,首先生成一堆Anchor box,對其進行裁剪過濾后通過softmax判斷anchors屬於前景(foreground)或者后景(background),即是物體or不是物體,所以這是一個二分類;同時,另一分支bounding box regression修正anchor box,形成較精確的proposal(注:這里的較精確是相對於后面全連接層的再一次box regression而言)

3)Roi Pooling

該層利用RPN生成的proposalsVGG16最后一層得到的feature map,得到固定大小的proposal feature map,進入到后面可利用全連接操作來進行目標識別和定位

4)Classifier

    會將Roi Pooling層形成固定大小的feature map進行全連接操作,利用Softmax進行具體類別的分類,同時,利用L1 Loss完成bounding box regression回歸操作獲得物體的精確位置.

 

)、網絡結構

現在,通過上圖開始逐層分析

1)Conv layers

Faster RCNN首先是支持輸入任意大小的圖片的,比如上圖中輸入的P*Q,進入網絡之前對圖片進行了規整化尺度的設定,如可設定圖像短邊不超過600,圖像長邊不超過1000,我們可以假定M*N=1000*600(如果圖片少於該尺寸,可以邊緣補0,即圖像會有黑色邊緣)

   13conv層:kernel_size=3,pad=1,stride=1;

卷積公式:

             所以,conv層不會改變圖片大小(即:輸入的圖片大小=輸出的圖片大小)

   13relu層:激活函數,不改變圖片大小

   4pooling層:kernel_size=2,stride=2;pooling層會讓輸出圖片是輸入圖片的1/2

       經過Conv layers,圖片大小變成(M/16)*(N/16),即:60*40(1000/1660,600/1640);則,Feature Map就是60*40*512-d(注:VGG16512-d,ZF256-d),表示特征圖的大小為60*40,數量為512

 

2)RPN(Region Proposal Networks):

Feature Map進入RPN后,先經過一次3*3的卷積,同樣,特征圖大小依然是60*40,數量512,這樣做的目的應該是進一步集中特征信息,接着看到兩個全卷積,kernel_size=1*1,p=0,stride=1;

如上圖中標識:

   rpn_cls60*40*512-d   1*1*512*18 ==> 60*40*9*2 

         逐像素對其9Anchor box進行二分類

   rpn_bbox60*40*512-d   1*1*512*36==>60*40*9*4

          逐像素得到其9Anchor box四個坐標信息(其實是偏移量,后面介紹)

  如下圖所示:

  

 (2.1)Anchors的生成規則

      前面提到經過Conv layers后,圖片大小變成了原來的1/16,令feat_stride=16,在生成Anchors時,我們先定義一個base_anchor,大小為16*16box(因為特征圖(60*40)上的一個點,可以對應到原圖(1000*600)上一個16*16大小的區域),源碼中轉化為[0,0,15,15]的數組,參數ratios=[0.512]scales=[8, 16, 32]

   先看[0,0,15,15],面積保持不變,長、寬比分別為[0.5, 1, 2]是產生的Anchors box

如果經過scales變化,即長、寬分別均為 (16*8=128)(16*16=256)(16*32=512),對應anchor box如圖

綜合以上兩種變換,最后生成9Anchor box

   所以,最終base_anchor=[0,0,15,15]生成的9Anchor box坐標如下:

1 [[ -84.  -40.   99.   55.]  
2 [-176.  -88.  191.  103.]  
3 [-360. -184.  375.  199.]  
4 [ -56.  -56.   71.   71.]  
5 [-120. -120.  135.  135.]  
6 [-248. -248.  263.  263.]  
7 [ -36.  -80.   51.   95.]  
8 [ -80. -168.   95.  183.]  
9 [-168. -344.  183.  359.]] 

    特征圖大小為60*40,所以會一共生成60*40*9=21600Anchor box

  源碼中,通過width:(0~60)*16,height(0~40)*16建立shift偏移量數組,再和base_ancho基准坐標數組累加,得到特征圖上所有像素對應的Anchors的坐標值,是一個[216000,4]的數組

 

 (2.2)RPN工作原理解析

為了進一步更清楚的看懂RPN的工作原理,將Caffe版本下的網絡圖貼出來,對照網絡圖進行講解會更清楚

主要看上圖中框住的‘RPN’部分的網絡圖,其中‘rpn_conv/3*3’是3*3的卷積,上面有提到過,接着是兩個1*1的全卷積,分別是圖中的‘rpn_cls_score’和‘rpn_bbox_pred’,在上面同樣有提到過。接下來,分析網絡圖中其他各部分的含義

2.2.1)rpn-data

1.     layer {  
2.      name: 'rpn-data'  
3.      type: 'Python'  
4.      bottom: 'rpn_cls_score'   #僅提供特征圖的height和width的參數大小
5.      bottom: 'gt_boxes'        #ground truth box
6.      bottom: 'im_info'         #包含圖片大小和縮放比例,可供過濾anchor box
7.      bottom: 'data'  
8.      top: 'rpn_labels'  
9.      top: 'rpn_bbox_targets'  
10.      top: 'rpn_bbox_inside_weights'  
11.      top: 'rpn_bbox_outside_weights'  
12.      python_param {  
13.        module: 'rpn.anchor_target_layer'  
14.        layer: 'AnchorTargetLayer'  
15.        param_str: "'feat_stride': 16 \n'scales': !!python/tuple [8, 16, 32]"  
16.      }  
17.    } 

這一層主要是為特征圖60*40上的每個像素生成9Anchor box,並且對生成的Anchor box進行過濾和標記,參照源碼,過濾和標記規則如下:

    去除掉超過1000*600這原圖的邊界的anchor box

    如果anchor boxground truthIoU值最大,標記為正樣本,label=1

    如果anchor boxground truthIoU>0.7,標記為正樣本,label=1

    如果anchor boxground truthIoU<0.3,標記為負樣本,label=0

     剩下的既不是正樣本也不是負樣本,不用於最終訓練,label=-1

     什么是IoU:

     

 

     除了對anchor box進行標記外,另一件事情就是計算anchor boxground truth之間的偏移量

   令:ground truth:標定的框也對應一個中心點位置坐標x*,y*和寬高w*,h*

    anchor box: 中心點位置坐標x_a,y_a和寬高w_a,h_a

    所以,偏移量:

    x=(x*-x_a)/w_a   y=(y*-y_a)/h_a 

   △w=log(w*/w_a)   h=log(h*/h_a)

    通過ground truth box與預測的anchor box之間的差異來進行學習,從而是RPN網絡中的權重能夠學習到預測box的能力

 

2.2.2) rpn_loss_clsrpn_loss_bboxrpn_cls_prob

下面集體看下這三個,其中‘rpn_loss_cls’、‘rpn_loss_bbox’是分別對應softmaxsmooth L1計算損失函數,‘rpn_cls_prob’計算概率值(可用於下一層的nms非最大值抑制操作)

補充:

     ①   Softmax公式計算各分類的概率值

      ② Softmax Loss公式RPN進行分類時,即尋找最小Loss

’rpn-data’中已經為預測框anchor box進行了標記,並且計算出與gt_boxes之間的偏移量,利用RPN網絡進行訓練。

RPN訓練設置:在訓練RPN時,一個Mini-batch是由一幅圖像中任意選取的256proposal組成的,其中正負樣本的比例為11。如果正樣本不足128,則多用一些負樣本以滿足有256Proposal可以用於訓練,反之亦然

 

2.2.3)proposal

1.    layer {  
2.      name: 'proposal'  
3.      type: 'Python'  
4.      bottom: 'rpn_cls_prob_reshape' #[1,18,40,60]==> [batch_size, channel,height,width]Caffe的數據格式,anchor box分類的概率
5.      bottom: 'rpn_bbox_pred'  # 記錄訓練好的四個回歸值△x, △y, △w, △h
6.      bottom: 'im_info'  
7.      top: 'rpn_rois'  
8.      python_param {  
9.        module: 'rpn.proposal_layer'  
10.        layer: 'ProposalLayer'  
11.        param_str: "'feat_stride': 16 \n'scales': !!python/tuple [4, 8, 16, 32]"
12.      }  
13.    } 

在輸入中我們看到’rpn_bbox_pred’,記錄着訓練好的四個回歸值△x, y, w, h

源碼中,會重新生成60*40*9anchor box,然后累加上訓練好的△x, y, w, h,從而得到了相較於之前更加准確的預測框region proposal,進一步對預測框進行越界剔除和使用nms非最大值抑制,剔除掉重疊的框;比如,設定IoU0.7的閾值,即僅保留覆蓋率不超過0.7的局部最大分數的box(粗篩)。最后留下大約2000anchor,然后再取前Nbox(比如300個);這樣,進入到下一層ROI Poolingregion proposal大約只有300

用下圖一個案例來對NMS算法進行簡單介紹

如上圖所示,一共有6個識別為人的框,每一個框有一個置信率。 
現在需要消除多余的:

·     按置信率排序: 0.95, 0.9, 0.9, 0.8, 0.7, 0.7

·     取最大0.95的框為一個物體框

·     剩余5個框中,去掉與0.95框重疊率IoU大於0.6(可以另行設置),則保留0.9, 0.8, 0.7三個框

·     重復上面的步驟,直到沒有框了,0.9為一個框

·     選出來的為: 0.95, 0.9

所以,整個過程,可以用下圖形象的表示出來

其中,紅色的A框是生成的anchor box,而藍色的G’框就是經過RPN網絡訓練后得到的較精確的預測框,綠色的Gground truth box

 

2.2.4)roi_data

1.      layer {  
2.      name: 'roi-data'  
3.      type: 'Python'  
4.      bottom: 'rpn_rois'  
5.      bottom: 'gt_boxes'  
6.      top: 'rois'  
7.      top: 'labels'  
8.      top: 'bbox_targets'  
9.      top: 'bbox_inside_weights'  
10.      top: 'bbox_outside_weights'  
11.      python_param {  
12.        module: 'rpn.proposal_target_layer'  
13.        layer: 'ProposalTargetLayer'  
14.        param_str: "'num_classes': 81"  
15.      }  
16.    }  

為了避免定義上的誤解,我們將經過‘proposal’后的預測框稱為region proposal(其實,RPN層的任務其實已經完成,roi_data屬於為下一層准備數據)

主要作用:

       RPN層只是來確定region proposal是否是物體(/),這里根據region proposalground truth box的最大重疊指定具體的標簽(就不再是二分類問題了,參數中指定的是81)

       計算region proposalground truth boxes的偏移量,計算方法和之前的偏移量計算公式相同

經過這一步后的數據輸入到ROI Pooling層進行進一步的分類和定位.

 

3)ROI Pooling:

1.    layer {  
2.      name: "roi_pool5"  
3.      type: "ROIPooling"  
4.      bottom: "conv5_3"   #輸入特征圖大小
5.      bottom: "rois"      #輸入region proposal
6.      top: "pool5"     #輸出固定大小的feature map
7.      roi_pooling_param {  
8.        pooled_w: 7  
9.        pooled_h: 7  
10.        spatial_scale: 0.0625 # 1/16  
11.      }  
12.    }

從上述的Caffe代碼中可以看到,輸入的是RPN層產生的region proposal(假定有300region proposal box)VGG16最后一層產生的特征圖(60*40 512-d),遍歷每個region proposal,將其坐標值縮小16倍,這樣就可以將在原圖(1000*600)基礎上產生的region proposal映射到60*40的特征圖上,從而將在feature map上確定一個區域(定義為RB*)

feature map上確定的區域RB*,根據參數pooled_w:7,pooled_h:7,將這個RB*區域划分為7*7,即49個相同大小的小區域,對於每個小區域,使用max pooling方式從中選取最大的像素點作為輸出,這樣,就形成了一個7*7feature map

       細節可查看:https://www.cnblogs.com/wangyong/p/8523814.html

以此,參照上述方法,300region proposal遍歷完后,會產生很多個7*7大小的feature map,故而輸出的數組是:[300,512,7,7],作為下一層的全連接的輸入

 

4)、全連接層:

經過roi pooling層之后,batch_size=300, proposal feature map的大小是7*7,512-d,對特征圖進行全連接,參照下圖,最后同樣利用Softmax LossL1 Loss完成分類和定位

 

通過full connect層與softmax計算每個region proposal具體屬於哪個類別(如人,馬,車等),輸出cls_prob概率向量;同時再次利用bounding box regression獲得每個region proposal的位置偏移量bbox_pred,用於回歸獲得更加精確的目標檢測框

即從PoI Pooling獲取到7x7大小的proposal feature maps后,通過全連接主要做了:

4.1)通過全連接和softmaxregion proposals進行具體類別的分類

4.2)再次對region proposals進行bounding box regression,獲取更高精度的rectangle box

 

作為一枚技術小白,寫這篇筆記的時候參考了很多博客論文,在這里表示感謝,同時,未經同意,請勿轉載....


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM