1. 程式人生 > >Faster RCNN 學習筆記

Faster RCNN 學習筆記

rect 使用 博客 一個 lib pan nms 解析 ret

下面的介紹都是基於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*60*512-d 1*1*512*18 ==>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.5, 1, 2]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


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

以此,參照上述方法,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

作為一枚技術小白,寫這篇筆記的時候參考了很多博客論文,在這裏表示感謝,同時,轉載請註明出處....


Faster RCNN 學習筆記