Faster RCNN 學習筆記
一)、整體框架
我們先整體的介紹下上圖中各層主要的功能
1)、Conv layers提取特征圖:
作為一種CNN網絡目標檢測方法,Faster RCNN首先使用一組基礎的conv+relu+pooling層提取input image的feature maps,該feature maps會用於後續的RPN層和全連接層
2)、RPN(Region Proposal Networks):
RPN網絡主要用於生成region proposals,首先生成一堆
3)、Roi Pooling:
該層利用RPN生成的proposals和VGG16最後一層得到的feature map,得到固定大小的proposal feature map,進入到後面可利用全連接操作來進行目標識別和定位
4)、
會將Roi Pooling層形成固定大小的feature map進行全連接操作,利用Softmax進行具體類別的分類,同時,利用L1 Loss完成bounding box regression回歸操作獲得物體的精確位置.
二)、網絡結構
現在,通過上圖開始逐層分析
1)、Conv layers
Faster RCNN首先是支持輸入任意大小的圖片的,比如上圖中輸入的P*Q,進入網絡之前對圖片進行了規整化尺度的設定,如可設定圖像短邊不超過600,圖像長邊不超過1000,我們可以假定M*N=1000*600(如果圖片少於該尺寸,可以邊緣補0,即圖像會有黑色邊緣)
① 13個conv層:kernel_size=3,pad=1,stride=1;
卷積公式:
所以,conv層不會改變圖片大小(即:輸入的圖片大小=輸出的圖片大小)
② 13個relu層:激活函數,不改變圖片大小
③ 4個pooling層:kernel_size=2,stride=2;pooling層會讓輸出圖片是輸入圖片的1/2
經過Conv layers,圖片大小變成(M/16)*(N/16),即:60*40(1000/16≈60,600/16≈40);則,Feature Map就是60*40*512-d(註:VGG16是512-d,ZF是256-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_cls:60*40*512-d ⊕ 1*1*512*18 ==> 60*40*9*2
逐像素對其9個Anchor box進行二分類
② rpn_bbox:60*60*512-d ⊕ 1*1*512*18 ==>60*40*9*4
逐像素得到其9個Anchor box四個坐標信息(其實是偏移量,後面介紹)
如下圖所示:
(2.1)、Anchors的生成規則
前面提到經過Conv layers後,圖片大小變成了原來的1/16,令feat_stride=16,在生成Anchors時,我們先定義一個base_anchor,大小為16*16的box(因為特征圖(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如圖
綜合以上兩種變換,最後生成9個Anchor box
所以,最終base_anchor=[0,0,15,15]生成的9個Anchor 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=21600個Anchor 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上的每個像素生成9個Anchor box,並且對生成的Anchor box進行過濾和標記,參照源碼,過濾和標記規則如下:
① 去除掉超過1000*600這原圖的邊界的anchor box
② 如果anchor box與ground truth的IoU值最大,標記為正樣本,label=1
③ 如果anchor box與ground truth的IoU>0.7,標記為正樣本,label=1
④ 如果anchor box與ground truth的IoU<0.3,標記為負樣本,label=0
剩下的既不是正樣本也不是負樣本,不用於最終訓練,label=-1
什麽是IoU:
除了對anchor box進行標記外,另一件事情就是計算anchor box與ground 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_cls、rpn_loss_bbox、rpn_cls_prob
下面集體看下這三個,其中‘rpn_loss_cls’、‘rpn_loss_bbox’是分別對應softmax,smooth L1計算損失函數,‘rpn_cls_prob’計算概率值(可用於下一層的nms非最大值抑制操作)
補充:
① Softmax公式,計算各分類的概率值
② Softmax Loss公式,RPN進行分類時,即尋找最小Loss值
在’rpn-data’中已經為預測框anchor box進行了標記,並且計算出與gt_boxes之間的偏移量,利用RPN網絡進行訓練。
RPN訓練設置:在訓練RPN時,一個Mini-batch是由一幅圖像中任意選取的256個proposal組成的,其中正負樣本的比例為1:1。如果正樣本不足128,則多用一些負樣本以滿足有256個Proposal可以用於訓練,反之亦然
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*9個anchor box,然後累加上訓練好的△x, △y, △w, △h,從而得到了相較於之前更加準確的預測框region proposal,進一步對預測框進行越界剔除和使用nms非最大值抑制,剔除掉重疊的框;比如,設定IoU為0.7的閾值,即僅保留覆蓋率不超過0.7的局部最大分數的box(粗篩)。最後留下大約2000個anchor,然後再取前N個box(比如300個);這樣,進入到下一層ROI Pooling時region 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網絡訓練後得到的較精確的預測框,綠色的G是ground 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 proposal和ground truth box的最大重疊指定具體的標簽(就不再是二分類問題了,參數中指定的是81類)
② 計算region proposal與ground 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(假定有300個region 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*7的feature map
以此,參照上述方法,300個region proposal遍歷完後,會產生很多個7*7大小的feature map,故而輸出的數組是:[300,512,7,7],作為下一層的全連接的輸入
4)、全連接層:
經過roi pooling層之後,batch_size=300, proposal feature map的大小是7*7,512-d,對特征圖進行全連接,參照下圖,最後同樣利用Softmax Loss和L1 Loss完成分類和定位
通過full connect層與softmax計算每個region proposal具體屬於哪個類別(如人,馬,車等),輸出cls_prob概率向量;同時再次利用bounding box regression獲得每個region proposal的位置偏移量bbox_pred,用於回歸獲得更加精確的目標檢測框
即從PoI Pooling獲取到7x7大小的proposal feature maps後,通過全連接主要做了:
4.1)通過全連接和softmax對region proposals進行具體類別的分類
4.2)再次對region proposals進行bounding box regression,獲取更高精度的rectangle box
作為一枚技術小白,寫這篇筆記的時候參考了很多博客論文,在這裏表示感謝,同時,轉載請註明出處....
Faster RCNN 學習筆記