Faster R-CNN 學習筆記

Lung-Ying Ling
19 min readJun 17, 2021

--

1. 大綱

RCNN系列目標檢測,大致分為兩個階段:一是獲取候選區域(region proposal 或 RoI),二是對候選區域進行分類判斷以及邊框回歸。 Faster R-CNN其實也是符合兩個階段,只是Faster R-CNN使用RPN網絡提取候選框,後面的分類和邊框回歸和R-CNN差不多。所以有時候我們可以將Faster R-CNN看成RPN部分和R-CNN部分。Faster R-CNN又包含了以下4重要的部分:

2. 架構圖

1. Conv layers

這裡應該理解為基本卷積網絡(base net),通過該網絡來提取原始圖片的feature map特徵,最後將這些特徵送入RPN網絡和RCNN網絡。

2. RPN網絡

RPN網絡用於生成region proposals(也可以說是RoI-region of interest)。該層通過sigmoid函數判斷anchors屬於foreground或者background,再利用bounding box regression修正anchors獲得修正後的RoI。

3. RoI Pooling

該層通過輸入feature maps和RoI,其中feature map就是base Net提取的,而RoI是RPN網絡提取的。通過該層pooling實現提取RoI的feature maps,送入後續全連接層判定目標類別。

4. Classifier

利用RoI feature maps計算RoI的類別,同時再次bounding box regression獲得檢測框最終的位置。

3. Conv layers

Conv layers包含了conv,pooling,relu三種層。以VGG16模型為例, Conv layers部分共有13個conv層,13個relu層,4個pooling層。這裡有一個非常容易被忽略但是又無比重要的信息,在Conv layers中:

所有的conv層都是:kernel_size=3,pad=1,stride=1

所有的pooling層都是:kernel_size=2,pad=0,stride=2

在Faster RCNN Conv layers中對所有的捲積都做了擴邊處理( pad=1,即填充一圈0),導致原圖變為(M+2)x(N+2)大小,再做3x3卷積後輸出MxN 。正是這種設置,導致Conv layers中的conv層不改變輸入和輸出矩陣大小。

Conv layers中的pooling層kernel_size=2,stride=2。這樣每個經過pooling層的MxN矩陣,都會變為(M/2)x(N/2)大小。綜上所述,在整個Conv layers中,conv和relu層不改變輸入輸出大小,只有pooling層使輸出長寬都變為輸入的1/2。

那麼,一個MxN大小的矩陣經過Conv layers固定變為(M/16)x(N/16)。這樣Conv layers生成的feature map中都可以和原圖對應起來。

4. Region Proposal Networks(RPN)

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

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

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

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

對多通道圖像做1x1卷積,其實就是將輸入圖像於每個通道乘以卷積係數後加在一起,即相當於把原圖像中本來各個獨立的通道"聯通"在了一起。

4.2 anchors

提到RPN網絡,就不能不說anchors。所謂anchors,實際上就是一組矩形。

其中每行的4個值(x1, y1, x2, y2) 表矩形左上和右下角點坐標。9個矩形共有3種形狀,長寬比為大約為with:height∈{1:1, 1:2, 2:1}三種。實際上通過anchors就引入了檢測中常用到的多尺度方法。

注:關於上面的anchors size,其實是根據檢測圖像設置的。在論文中,會把任意大小的輸入圖像reshape成800x600(即M=800,N=600)。再回頭來看anchors的大小,anchors中長寬1:2中最大為352x704,長寬2:1中最大736x384,基本是cover了800x600的各個尺度和形狀。

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

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不變(如圖中的紅框)。

3. 假設在conv5 feature map中每個點上有k個anchor(默認k=9),而每個anchor要分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進行訓練。

其實RPN最終就是在原圖尺度上,設置了密密麻麻的候選Anchor。然後用CNN去判斷哪些Anchor是裡面有目標的foreground anchor,哪些是沒目標的background。所以,僅僅是個二分類而已!

那麼Anchor一共有多少個?原圖800x600,VGG下採樣16倍,feature map每個點設置9個Anchor,所以:

其中ceil()表示向上取整,是因為VGG輸出的feature map size= 50*38。

4.3 softmax判定foreground與background

一個MxN大小的矩陣送入Faster RCNN網絡後,到RPN網絡變為(M/16)x(N/16),設W=M/16,H=N/16。在進入reshape與softmax之前,先做了1x1卷積。

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

可以看到其num_output=18,也就是經過該卷積的輸出圖像為WxHx18大小。這也就剛好對應了feature maps每一個點都有9個anchors,同時每個anchors又有可能是foreground和background,所有這些信息都保存WxHx(9*2)大小的矩陣。為何這樣做?後面接softmax分類獲得foreground anchors,也就相當於初步提取了檢測目標候選區域box。那麼為何要在softmax前後都接一個reshape layer?其實只是為了便於softmax分類,至於具體原因這就要從caffe的實現形式說起了。在caffe基本數據結構blob中以如下形式保存數據:

對應至上面的保存bg/fg anchors的矩陣,其在caffe blob中的存儲形式為[1, 2x9, H, W]。而在softmax分類時需要進行fg/bg二分類,所以reshape layer會將其變為[1, 2, 9xH, W]大小,即單獨“騰空”出來一個維度以便softmax分類,之後再reshape回復原狀。貼一段caffe softmax_loss_layer.cpp的reshape函數的解釋,非常精闢:

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

4.4 bounding box regression原理

綠色框為飛機的Ground Truth(GT),紅色為提取的foreground anchors,即便紅色的框被分類器識別為飛機,但是由於紅色的框定位不准,這張圖相當於沒有正確的檢測出飛機。所以我們希望採用一種方法對紅色的框進行微調,使得foreground anchors和GT更加接近。

對於窗口一般使用四維向量(x, y, w, h)表示,分別表示窗口的中心點坐標和寬高。紅色的框A代表原始的Foreground Anchors,綠色的框G代表目標的GT,我們的目標是尋找一種關係,使得輸入原始的anchor A經過映射得到一個跟真實窗口G更接近的回歸窗口G’,即:

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

先做平移

再做縮放

4.5 對proposals進行bounding box regression

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

上圖中1x1卷積的caffe prototxt定義:

可以看到其num_output=36,即經過該卷積輸出圖像為WxHx36,在caffe blob存儲為[1, 4x9, H, W],這里相當於feature maps每個點都有9個anchors,每個anchors又都有4個用於回歸的[dx(A),dy(A),dw(A),dn(A)]變換量。

2.6 Proposal Layer

Proposal Layer負責綜合所有[dx(A),dy(A),dw(A),dn(A)]變換量和foreground anchors,計算出精準的proposal,送入後續RoI Pooling Layer。還是先來看看Proposal Layer的caffe prototxt定義:

Proposal Layer有3個輸入:fg/bg anchors分類器結果。rpn_cls_prob_reshape,對應的bbox reg的[dx(A),dy(A),dw(A),dn(A)]變換量rpn_bbox_pred,以及im_info;另外還有參數feat_stride=16。

首先解釋im_info。對於一副任意大小PxQ圖像,傳入Faster RCNN前首先reshape到固定MxN,im_info=[M, N, scale_factor]則保存了此次縮放的所有信息。然後經過Conv Layers,經過4次pooling變為WxH=(M/16)x(N/16)大小,其中feature_stride=16則保存了該信息,用於計算anchor偏移量。

Proposal Layer forward按照以下順序依次處理:

1. 生成anchors,利用[dx(A),dy(A),dw(A),dn(A)]對所有的anchors做bbox regression回歸

2. 按照輸入的foreground softmax scores由大到小排序anchors,提取前pre_nms_topN(eg 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(eg 300)結果作為proposal輸出。

之後輸出proposal=[x1, y1, x2, y2],注意,由於在第三步中將anchors映射回原圖判斷是否超出邊界,所以這裡輸出的proposal是對應MxN輸入圖像尺度的,這點在後續網絡中有用。

RPN網絡結構總結:

1. 生成anchors

2. softmax分類器提取foreground anchors

3. bbox reg 回歸foreground anchors

4. proposal layer生成proposals

5. RoI Pooling

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

1. 原始的feature maps

2. RPN輸出的proposal boxes(大小各不相同)

5.1 RoI Pooling原理

RoI Pooling Layer的caffe prototxt的定義:

RoI Pooling layer forward過程:是對應MxN尺度的,所以首先使用spatial_scale參數將其映射回(M/16)x(N/16)大小的feature maps尺度;之後將每個proposal水平和豎直分為pooled_w和pooled_h份,對每一份都進行max pooling處理。這樣處理後,即使大小不同的proposal,輸出結果都是大小,實現了fixed-length output(固定長度輸出)。

6. Classification

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

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

1. 通過全連接和softmax對proposals進行分類。

2. 再次對proposals進行bounding box regression,獲取更高精度的rect box。

7. Faster R-CNN訓練

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

1. 在已經訓練好的model上,訓練RPN網絡

2. 利用步驟1中訓練好的RPN網絡,收集proposals

3. 第一次訓練Fast RCNN網絡

4. 第二訓練RPN網絡

5. 再次利用步驟4中訓練好的RPN網絡

6. 第二次訓練Fast RCNN網絡

可以看到訓練過程類似於一種"迭代"的過程,不過只循環了2次。

7.1 訓練RPN網路

首先讀取RBG提供的預訓練好的model(本文使用VGG),開始迭代訓練

使用Conv Layers提取feature maps。整個網絡使用的Loss如下:

上述公式中,i表示anchors index,pi表示foreground softmax probability,pi*代表對應的GT predict概率(即當第i個anchor與GT間IoU>0.7,認為是該anchor是foreground,pi*=1;反之IoU<0.3時,認為是該anchor是background,pi*=0;至於那些0.3<IoU<0.7的anchor則不參與訓練);t代表predict bounding box,t*代表對應foreground anchor對應的GT box。可以看到,整個Loss分為2部分:

回過來看架構圖:

1. 在RPN訓練階段,rpn-data層會按照和test階段Proposal層完全一樣的方式生成Anchors用於訓練。

2. 對於rpn_loss_cls,輸入的rpn_cls_scors_reshape和rpn_labels分別對應p與

參數隱含在p與

的caffe blob的大小中。

3. 對於rpn_loss_bbox,輸入的rpn_bbox_pred和rpn_bbox_targets分別對應t於

,rpn_bbox_inside_weigths對應

,rpn_bbox_outside_weigths未用到,而

同樣隱含在caffe blob大小中。回過來看架構圖:

1. 在RPN訓練階段,rpn-data層會按照和test階段Proposal層完全一樣的方式生成Anchors用於訓練。

2. 對於rpn_loss_cls,輸入的rpn_cls_scors_reshape和rpn_labels分別對應p與

p*,Ncls參數隱含在p與P*的caffe blob的大小中。

3. 對於rpn_loss_bbox,輸入的rpn_bbox_pred和rpn_bbox_targets分別對應t於t*,rpn_bbox_inside_weigths對應P*,rpn_bbox_outside_weigths未用到,而Nreg同樣隱含在caffe blob大小中。

7.2 通過訓練好的RPN網絡收集proposals(test)

在該步驟中,利用之前的RPN網絡獲取proposal RoIs,同時獲取foreground softmax probability,然後將獲取的信息保存在python pickle文件中。該網絡本質上和檢測中的RPN網絡一樣,沒有什麼區別。

7.3 訓練Faster RCNN網絡

讀取之前保存的pickle文件,獲取proposals與foreground probability。從data層輸入網絡。然後:

1. 將提取的proposals作為RoIs傳入網絡,如藍框。

2. 計算bbox_inside_weights+bbox_outside_weights,作用與RPN一樣,傳入soomth_L1_loss layer,如綠框。

這樣就可以訓練最後的識別softmax與最終的bounding box regression。

之後的stage2訓練都是大同小異。

8. 參考資料

l. Faster R-CNN原理详解(基于keras代码)(一)

https://cdn2.jianshu.io/p/71fbb3251cbf

2. Faster R-CNN原理详解(基于keras代码)(二)

https://www.jianshu.com/p/adc4679b25ff

3. 一文讀懂Faster RCNN

https://zhuanlan.zhihu.com/p/31426458

4. 像玩乐高一样拆解Faster R-CNN:详解目标检测的实现过程

https://www.jiqizhixin.com/articles/2018-02-23-3

5. Faster RCNN详解结构介绍

https://zhuanlan.zhihu.com/p/34110452

6. Faster R-CNN:詳解目標檢測的實現過程

https://hk.saowen.com/a/8761a413dea61b2638373745c2369938f3ab74c60c41c3e67015f50792de3ecf

7. Faster RCNN 關鍵點總結

https://hk.saowen.com/a/7701c0808917d9d48fb06bc5d85b069b4b26ce2f00e7d3a49a3abdf1cddfdb98

--

--