【轉(zhuǎn)載】一文讀懂Faster RCNN

原文鏈接:https://zhuanlan.zhihu.com/p/31426458


經(jīng)過R-CNN和Fast RCNN的積淀,Ross B. Girshick在2016年提出了新的Faster RCNN,在結(jié)構(gòu)上,F(xiàn)aster RCNN已經(jīng)將特征抽取(feature extraction),proposal提取,bounding box regression(rect refine),classification都整合在了一個(gè)網(wǎng)絡(luò)中,使得綜合性能有較大提高,在檢測(cè)速度方面尤為明顯。

目錄

1 Conv layers

2 Region Proposal Networks(RPN)

- 2.1 多通道圖像卷積基礎(chǔ)知識(shí)介紹

- 2.2 anchors

- 2.3 softmax判定positive與negative

- 2.4 bounding box regression原理

- 2.5 對(duì)proposals進(jìn)行bounding box regression

- 2.6 Proposal Layer

3 RoI pooling

- 3.1 為何需要RoI Pooling

- 3.2 RoI Pooling原理

4 Classification

5 Faster RCNN訓(xùn)練

- 5.1 訓(xùn)練RPN網(wǎng)絡(luò)

- 5.2 通過訓(xùn)練好的RPN網(wǎng)絡(luò)收集proposals

- 5.3 訓(xùn)練Faster RCNN網(wǎng)絡(luò)

Questions and Answer

圖1 Faster RCNN基本結(jié)構(gòu)(來自原論文)

依作者看來,如圖1,F(xiàn)aster RCNN其實(shí)可以分為4個(gè)主要內(nèi)容:

Conv layers。作為一種CNN網(wǎng)絡(luò)目標(biāo)檢測(cè)方法,F(xiàn)aster RCNN首先使用一組基礎(chǔ)的conv+relu+pooling層提取image的feature maps。該feature maps被共享用于后續(xù)RPN層和全連接層。

Region Proposal Networks。RPN網(wǎng)絡(luò)用于生成region proposals。該層通過softmax判斷anchors屬于positive或者negative,再利用bounding box regression修正anchors獲得精確的proposals。

Roi Pooling。該層收集輸入的feature maps和proposals,綜合這些信息后提取proposal feature maps,送入后續(xù)全連接層判定目標(biāo)類別。

Classification。利用proposal feature maps計(jì)算proposal的類別,同時(shí)再次bounding box regression獲得檢測(cè)框最終的精確位置。

所以本文以上述4個(gè)內(nèi)容作為切入點(diǎn)介紹Faster R-CNN網(wǎng)絡(luò)。

圖2展示了python版本中的VGG16模型中的faster_rcnn_test.pt的網(wǎng)絡(luò)結(jié)構(gòu),可以清晰的看到該網(wǎng)絡(luò)對(duì)于一副任意大小PxQ的圖像,首先縮放至固定大小MxN,然后將MxN圖像送入網(wǎng)絡(luò);而Conv layers中包含了13個(gè)conv層+13個(gè)relu層+4個(gè)pooling層;RPN網(wǎng)絡(luò)首先經(jīng)過3x3卷積,再分別生成positive anchors和對(duì)應(yīng)bounding box regression偏移量,然后計(jì)算出proposals;而Roi Pooling層則利用proposals從feature maps中提取proposal feature送入后續(xù)全連接和softmax網(wǎng)絡(luò)作classification(即分類proposal到底是什么object)。

圖2 faster_rcnn_test.pt網(wǎng)絡(luò)結(jié)構(gòu) (pascal_voc/VGG16/faster_rcnn_alt_opt/faster_rcnn_test.pt)

本文不會(huì)討論任何關(guān)于R-CNN家族的歷史,分析清楚最新的Faster R-CNN就夠了,并不需要追溯到那么久。實(shí)話說我也不了解R-CNN,更不關(guān)心。有空不如看看新算法。

1 Conv layers

Conv layers包含了conv,pooling,relu三種層。以python版本中的VGG16模型中的faster_rcnn_test.pt的網(wǎng)絡(luò)結(jié)構(gòu)為例,如圖2,Conv layers部分共有13個(gè)conv層,13個(gè)relu層,4個(gè)pooling層。這里有一個(gè)非常容易被忽略但是又無比重要的信息,在Conv layers中:

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

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

?,?

?,?

為何重要?在Faster RCNN Conv layers中對(duì)所有的卷積都做了擴(kuò)邊處理( pad=1,即填充一圈0),導(dǎo)致原圖變?yōu)?(M+2)x(N+2)大小,再做3x3卷積后輸出MxN 。正是這種設(shè)置,導(dǎo)致Conv layers中的conv層不改變輸入和輸出矩陣大小。如圖3:

圖3 卷積示意圖

類似的是,Conv layers中的pooling層kernel_size=2,stride=2。這樣每個(gè)經(jīng)過pooling層的MxN矩陣,都會(huì)變?yōu)?M/2)x(N/2)大小。綜上所述,在整個(gè)Conv layers中,conv和relu層不改變輸入輸出大小,只有pooling層使輸出長(zhǎng)寬都變?yōu)檩斎氲?/2。

那么,一個(gè)MxN大小的矩陣經(jīng)過Conv layers固定變?yōu)?M/16)x(N/16)!這樣Conv layers生成的feature map中都可以和原圖對(duì)應(yīng)起來。

2 Region Proposal Networks(RPN)

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

圖4 RPN網(wǎng)絡(luò)結(jié)構(gòu)

上圖4展示了RPN網(wǎng)絡(luò)的具體結(jié)構(gòu)。可以看到RPN網(wǎng)絡(luò)實(shí)際分為2條線,上面一條通過softmax分類anchors獲得positive和negative分類,下面一條用于計(jì)算對(duì)于anchors的bounding box regression偏移量,以獲得精確的proposal。而最后的Proposal層則負(fù)責(zé)綜合positive anchors和對(duì)應(yīng)bounding box regression偏移量獲取proposals,同時(shí)剔除太小和超出邊界的proposals。其實(shí)整個(gè)網(wǎng)絡(luò)到了Proposal Layer這里,就完成了相當(dāng)于目標(biāo)定位的功能。

2.1 多通道圖像卷積基礎(chǔ)知識(shí)介紹

在介紹RPN前,還要多解釋幾句基礎(chǔ)知識(shí),已經(jīng)懂的看官老爺跳過就好。

對(duì)于單通道圖像+單卷積核做卷積,第一章中的圖3已經(jīng)展示了;

對(duì)于多通道圖像+多卷積核做卷積,計(jì)算方式如下:

圖5 多通道卷積計(jì)算方式

如圖5,輸入有3個(gè)通道,同時(shí)有2個(gè)卷積核。對(duì)于每個(gè)卷積核,先在輸入3個(gè)通道分別作卷積,再將3個(gè)通道結(jié)果加起來得到卷積輸出。所以對(duì)于某個(gè)卷積層,無論輸入圖像有多少個(gè)通道,輸出圖像通道數(shù)總是等于卷積核數(shù)量!

對(duì)多通道圖像做1x1卷積,其實(shí)就是將輸入圖像于每個(gè)通道乘以卷積系數(shù)后加在一起,即相當(dāng)于把原圖像中本來各個(gè)獨(dú)立的通道“聯(lián)通”在了一起。

2.2 anchors

提到RPN網(wǎng)絡(luò),就不能不說anchors。所謂anchors,實(shí)際上就是一組由rpn/generate_anchors.py生成的矩形。直接運(yùn)行作者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個(gè)值?

?表矩形左上和右下角點(diǎn)坐標(biāo)。9個(gè)矩形共有3種形狀,長(zhǎng)寬比為大約為?

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

圖6 anchors示意圖

注:關(guān)于上面的anchors size,其實(shí)是根據(jù)檢測(cè)圖像設(shè)置的。在python demo中,會(huì)把任意大小的輸入圖像reshape成800x600(即圖2中的M=800,N=600)。再回頭來看anchors的大小,anchors中長(zhǎng)寬1:2中最大為352x704,長(zhǎng)寬2:1中最大736x384,基本是cover了800x600的各個(gè)尺度和形狀。

那么這9個(gè)anchors是做什么的呢?借用Faster RCNN論文中的原圖,如圖7,遍歷Conv layers計(jì)算獲得的feature maps,為每一個(gè)點(diǎn)都配備這9種anchors作為初始的檢測(cè)框。這樣做獲得檢測(cè)框很不準(zhǔn)確,不用擔(dān)心,后面還有2次bounding box regression可以修正檢測(cè)框位置。

圖7

解釋一下上面這張圖的數(shù)字。

在原文中使用的是ZF model中,其Conv Layers中最后的conv5層num_output=256,對(duì)應(yīng)生成256張?zhí)卣鲌D,所以相當(dāng)于feature map每個(gè)點(diǎn)都是256-dimensions

在conv5之后,做了rpn_conv/3x3卷積且num_output=256,相當(dāng)于每個(gè)點(diǎn)又融合了周圍3x3的空間信息(猜測(cè)這樣做也許更魯棒?反正我沒測(cè)試),同時(shí)256-d不變(如圖4和圖7中的紅框)

假設(shè)在conv5 feature map中每個(gè)點(diǎn)上有k個(gè)anchor(默認(rèn)k=9),而每個(gè)anhcor要分positive和negative,所以每個(gè)點(diǎn)由256d feature轉(zhuǎn)化為cls=2k scores;而每個(gè)anchor都有(x, y, w, h)對(duì)應(yīng)4個(gè)偏移量,所以reg=4k coordinates

補(bǔ)充一點(diǎn),全部anchors拿去訓(xùn)練太多了,訓(xùn)練程序會(huì)在合適的anchors中隨機(jī)選取128個(gè)postive anchors+128個(gè)negative anchors進(jìn)行訓(xùn)練(什么是合適的anchors下文5.1有解釋)

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

其實(shí)RPN最終就是在原圖尺度上,設(shè)置了密密麻麻的候選Anchor。然后用cnn去判斷哪些Anchor是里面有目標(biāo)的positive anchor,哪些是沒目標(biāo)的negative anchor。所以,僅僅是個(gè)二分類而已!

那么Anchor一共有多少個(gè)?原圖800x600,VGG下采樣16倍,feature map每個(gè)點(diǎn)設(shè)置9個(gè)Anchor,所以:

其中ceil()表示向上取整,是因?yàn)閂GG輸出的feature map size= 50*38。

圖8 Gernerate Anchors

2.3 softmax判定positive與negative

一副MxN大小的矩陣送入Faster RCNN網(wǎng)絡(luò)后,到RPN網(wǎng)絡(luò)變?yōu)?M/16)x(N/16),不妨設(shè) W=M/16,H=N/16。在進(jìn)入reshape與softmax之前,先做了1x1卷積,如圖9:

圖9 RPN中判定positive/negative網(wǎng)絡(luò)結(jié)構(gòu)

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

layer {

? name: "rpn_cls_score"

? type: "Convolution"

? bottom: "rpn/output"

? top: "rpn_cls_score"

? convolution_param {

? ? num_output: 18? # 2(positive/negative) * 9(anchors)

? ? kernel_size: 1 pad: 0 stride: 1

? }

}

可以看到其num_output=18,也就是經(jīng)過該卷積的輸出圖像為WxHx18大?。ㄗ⒁獾诙麻_頭提到的卷積計(jì)算方式)。這也就剛好對(duì)應(yīng)了feature maps每一個(gè)點(diǎn)都有9個(gè)anchors,同時(shí)每個(gè)anchors又有可能是positive和negative,所有這些信息都保存WxHx(9*2)大小的矩陣。為何這樣做?后面接softmax分類獲得positive anchors,也就相當(dāng)于初步提取了檢測(cè)目標(biāo)候選區(qū)域box(一般認(rèn)為目標(biāo)在positive anchors中)。

那么為何要在softmax前后都接一個(gè)reshape layer?其實(shí)只是為了便于softmax分類,至于具體原因這就要從caffe的實(shí)現(xiàn)形式說起了。在caffe基本數(shù)據(jù)結(jié)構(gòu)blob中以如下形式保存數(shù)據(jù):

blob=[batch_size, channel,height,width]

對(duì)應(yīng)至上面的保存positive/negative anchors的矩陣,其在caffe blob中的存儲(chǔ)形式為[1, 2x9, H, W]。而在softmax分類時(shí)需要進(jìn)行positive/negative二分類,所以reshape layer會(huì)將其變?yōu)閇1, 2, 9xH, W]大小,即單獨(dú)“騰空”出來一個(gè)維度以便softmax分類,之后再reshape回復(fù)原狀。貼一段caffe softmax_loss_layer.cpp的reshape函數(shù)的解釋,非常精辟:

"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網(wǎng)絡(luò)中利用anchors和softmax初步提取出positive anchors作為候選區(qū)域(另外也有實(shí)現(xiàn)用sigmoid代替softmax,原理類似)。

2.4 bounding box regression原理

如圖9所示綠色框?yàn)轱w機(jī)的Ground Truth(GT),紅色為提取的positive anchors,即便紅色的框被分類器識(shí)別為飛機(jī),但是由于紅色的框定位不準(zhǔn),這張圖相當(dāng)于沒有正確的檢測(cè)出飛機(jī)。所以我們希望采用一種方法對(duì)紅色的框進(jìn)行微調(diào),使得positive anchors和GT更加接近。

圖10

對(duì)于窗口一般使用四維向量?

?表示,分別表示窗口的中心點(diǎn)坐標(biāo)和寬高。對(duì)于圖 11,紅色的框A代表原始的positive Anchors,綠色的框G代表目標(biāo)的GT,我們的目標(biāo)是尋找一種關(guān)系,使得輸入原始的anchor A經(jīng)過映射得到一個(gè)跟真實(shí)窗口G更接近的回歸窗口G',即:

給定anchor?

?和?

尋找一種變換F,使得:

,其中

圖11

那么經(jīng)過何種變換F才能從圖10中的anchor A變?yōu)镚'呢? 比較簡(jiǎn)單的思路就是:

先做平移

再做縮放

觀察上面4個(gè)公式發(fā)現(xiàn),需要學(xué)習(xí)的是?

?這四個(gè)變換。當(dāng)輸入的anchor A與GT相差較小時(shí),可以認(rèn)為這種變換是一種線性變換, 那么就可以用線性回歸來建模對(duì)窗口進(jìn)行微調(diào)(注意,只有當(dāng)anchors A和GT比較接近時(shí),才能使用線性回歸模型,否則就是復(fù)雜的非線性問題了)。

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

?了。線性回歸就是給定輸入的特征向量X, 學(xué)習(xí)一組參數(shù)W, 使得經(jīng)過線性回歸后的值跟真實(shí)值Y非常接近,即

。對(duì)于該問題,輸入X是cnn feature map,定義為Φ;同時(shí)還有訓(xùn)練傳入A與GT之間的變換量,即

。輸出是

四個(gè)變換。那么目標(biāo)函數(shù)可以表示為:

其中?

?是對(duì)應(yīng)anchor的feature map組成的特征向量,?

?是需要學(xué)習(xí)的參數(shù),?

?是得到的預(yù)測(cè)值(*表示 x,y,w,h,也就是每一個(gè)變換對(duì)應(yīng)一個(gè)上述目標(biāo)函數(shù))。為了讓預(yù)測(cè)值?

?與真實(shí)值?

?差距最小,設(shè)計(jì)L1損失函數(shù):

函數(shù)優(yōu)化目標(biāo)為:

為了方便描述,這里以L1損失為例介紹,而真實(shí)情況中一般使用soomth-L1損失。

需要說明,只有在GT與需要回歸框位置比較接近時(shí),才可近似認(rèn)為上述線性變換成立。

說完原理,對(duì)應(yīng)于Faster RCNN原文,positive anchor與ground truth之間的平移量?

?與尺度因子?

?如下:

對(duì)于訓(xùn)練bouding box regression網(wǎng)絡(luò)回歸分支,輸入是cnn feature Φ,監(jiān)督信號(hào)是Anchor與GT的差距?

,即訓(xùn)練目標(biāo)是:輸入 Φ的情況下使網(wǎng)絡(luò)輸出與監(jiān)督信號(hào)盡可能接近。那么當(dāng)bouding box regression工作時(shí),再輸入Φ時(shí),回歸網(wǎng)絡(luò)分支的輸出就是每個(gè)Anchor的平移量和變換尺度?

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

2.5 對(duì)proposals進(jìn)行bounding box regression

在了解bounding box regression后,再回頭來看RPN網(wǎng)絡(luò)第二條線路,如圖12。

圖12 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,即經(jīng)過該卷積輸出圖像為WxHx36,在caffe blob存儲(chǔ)為[1, 4x9, H, W],這里相當(dāng)于feature maps每個(gè)點(diǎn)都有9個(gè)anchors,每個(gè)anchors又都有4個(gè)用于回歸的

變換量。

回到圖8,VGG輸出?

?的特征,對(duì)應(yīng)設(shè)置?

?個(gè)anchors,而RPN輸出:

大小為

?的positive/negative softmax分類特征矩陣

大小為?

?的regression坐標(biāo)回歸特征矩陣

恰好滿足RPN完成positive/negative分類+bounding box regression坐標(biāo)回歸.

2.6 Proposal Layer

Proposal Layer負(fù)責(zé)綜合所有?

?變換量和positive anchors,計(jì)算出精準(zhǔn)的proposal,送入后續(xù)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個(gè)輸入:positive vs negative anchors分類器結(jié)果rpn_cls_prob_reshape,對(duì)應(yīng)的bbox reg的?

?變換量rpn_bbox_pred,以及im_info;另外還有參數(shù)feat_stride=16,這和圖4是對(duì)應(yīng)的。

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

圖13

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

生成anchors,利用

對(duì)所有的anchors做bbox regression回歸(這里的anchors生成和訓(xùn)練時(shí)完全一致)

按照輸入的positive softmax scores由大到小排序anchors,提取前pre_nms_topN(e.g. 6000)個(gè)anchors,即提取修正位置后的positive anchors。

限定超出圖像邊界的positive anchors為圖像邊界(防止后續(xù)roi pooling時(shí)proposal超出圖像邊界)

剔除非常小(width<threshold or height<threshold)的positive anchors

對(duì)剩余的positive anchors進(jìn)行NMS(nonmaximum suppression)

Proposal Layer有3個(gè)輸入:positive和negative anchors分類器結(jié)果rpn_cls_prob_reshape,對(duì)應(yīng)的bbox reg的(e.g. 300)結(jié)果作為proposal輸出。

之后輸出proposal=[x1, y1, x2, y2],注意,由于在第三步中將anchors映射回原圖判斷是否超出邊界,所以這里輸出的proposal是對(duì)應(yīng)MxN輸入圖像尺度的,這點(diǎn)在后續(xù)網(wǎng)絡(luò)中有用。另外我認(rèn)為,嚴(yán)格意義上的檢測(cè)應(yīng)該到此就結(jié)束了,后續(xù)部分應(yīng)該屬于識(shí)別了。

RPN網(wǎng)絡(luò)結(jié)構(gòu)就介紹到這里,總結(jié)起來就是:

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

3 RoI pooling

而RoI Pooling層則負(fù)責(zé)收集proposal,并計(jì)算出proposal feature maps,送入后續(xù)網(wǎng)絡(luò)。從圖2中可以看到Rol pooling層有2個(gè)輸入:

原始的feature maps

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

3.1 為何需要RoI Pooling

先來看一個(gè)問題:對(duì)于傳統(tǒng)的CNN(如AlexNet和VGG),當(dāng)網(wǎng)絡(luò)訓(xùn)練好后輸入的圖像尺寸必須是固定值,同時(shí)網(wǎng)絡(luò)輸出也是固定大小的vector or matrix。如果輸入圖像大小不定,這個(gè)問題就變得比較麻煩。有2種解決辦法:

從圖像中crop一部分傳入網(wǎng)絡(luò)

將圖像warp成需要的大小后傳入網(wǎng)絡(luò)

圖14 crop與warp破壞圖像原有結(jié)構(gòu)信息

兩種辦法的示意圖如圖14,可以看到無論采取那種辦法都不好,要么crop后破壞了圖像的完整結(jié)構(gòu),要么warp破壞了圖像原始形狀信息。

回憶RPN網(wǎng)絡(luò)生成的proposals的方法:對(duì)positive anchors進(jìn)行bounding box regression,那么這樣獲得的proposals也是大小形狀各不相同,即也存在上述問題。所以Faster R-CNN中提出了RoI Pooling解決這個(gè)問題。不過RoI Pooling確實(shí)是從Spatial Pyramid Pooling發(fā)展而來,但是限于篇幅這里略去不講,有興趣的讀者可以自行查閱相關(guān)論文。

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

? }

}

其中有新參數(shù)pooled_w和pooled_h,另外一個(gè)參數(shù)spatial_scale認(rèn)真閱讀的讀者肯定已經(jīng)知道知道用途。RoI Pooling layer forward過程:

由于proposal是對(duì)應(yīng)MXN尺度的,所以首先使用spatial_scale參數(shù)將其映射回(M/16)X(N/16)大小的feature map尺度;

再將每個(gè)proposal對(duì)應(yīng)的feature map區(qū)域水平分為?

?的網(wǎng)格;

對(duì)網(wǎng)格的每一份都進(jìn)行max pooling處理。

這樣處理后,即使大小不同的proposal輸出結(jié)果都是?

?固定大小,實(shí)現(xiàn)了固定長(zhǎng)度輸出。

圖15 proposal示意圖

4 Classification

Classification部分利用已經(jīng)獲得的proposal feature maps,通過full connect層與softmax計(jì)算每個(gè)proposal具體屬于那個(gè)類別(如人,車,電視等),輸出cls_prob概率向量;同時(shí)再次利用bounding box regression獲得每個(gè)proposal的位置偏移量bbox_pred,用于回歸更加精確的目標(biāo)檢測(cè)框。Classification部分網(wǎng)絡(luò)結(jié)構(gòu)如圖16。

圖16 Classification部分網(wǎng)絡(luò)結(jié)構(gòu)圖

從RoI Pooling獲取到7x7=49大小的proposal feature maps后,送入后續(xù)網(wǎng)絡(luò),可以看到做了如下2件事:

通過全連接和softmax對(duì)proposals進(jìn)行分類,這實(shí)際上已經(jīng)是識(shí)別的范疇了

再次對(duì)proposals進(jìn)行bounding box regression,獲取更高精度的rect box

這里來看看全連接層InnerProduct layers,簡(jiǎn)單的示意圖如圖17,

圖17 全連接層示意圖

其計(jì)算公式如下:

其中W和bias B都是預(yù)先訓(xùn)練好的,即大小是固定的,當(dāng)然輸入X和輸出Y也就是固定大小。所以,這也就印證了之前Roi Pooling的必要性。到這里,我想其他內(nèi)容已經(jīng)很容易理解,不在贅述了。

5 Faster RCNN訓(xùn)練

Faster R-CNN的訓(xùn)練,是在已經(jīng)訓(xùn)練好的model(如VGG_CNN_M_1024,VGG,ZF)的基礎(chǔ)上繼續(xù)進(jìn)行訓(xùn)練。實(shí)際中訓(xùn)練過程分為6個(gè)步驟:

在已經(jīng)訓(xùn)練好的model上,訓(xùn)練RPN網(wǎng)絡(luò),對(duì)應(yīng)stage1_rpn_train.pt

利用步驟1中訓(xùn)練好的RPN網(wǎng)絡(luò),收集proposals,對(duì)應(yīng)rpn_test.pt

第一次訓(xùn)練Fast RCNN網(wǎng)絡(luò),對(duì)應(yīng)stage1_fast_rcnn_train.pt

第二訓(xùn)練RPN網(wǎng)絡(luò),對(duì)應(yīng)stage2_rpn_train.pt

再次利用步驟4中訓(xùn)練好的RPN網(wǎng)絡(luò),收集proposals,對(duì)應(yīng)rpn_test.pt

第二次訓(xùn)練Fast RCNN網(wǎng)絡(luò),對(duì)應(yīng)stage2_fast_rcnn_train.pt

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

下面是一張訓(xùn)練過程流程圖,應(yīng)該更加清晰(圖來源)。

圖18 Faster RCNN訓(xùn)練步驟

5.1 訓(xùn)練RPN網(wǎng)絡(luò)

在該步驟中,首先讀取RBG提供的預(yù)訓(xùn)練好的model(本文使用VGG),開始迭代訓(xùn)練。來看看stage1_rpn_train.pt網(wǎng)絡(luò)結(jié)構(gòu),如圖19。

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

與檢測(cè)網(wǎng)絡(luò)類似的是,依然使用Conv Layers提取feature maps。整個(gè)網(wǎng)絡(luò)使用的Loss如下:

上述公式中?

?表示anchors index,?

?表示positive softmax probability,

代表對(duì)應(yīng)的GT predict概率(即當(dāng)?shù)趇個(gè)anchor與GT間IoU>0.7,認(rèn)為是該anchor是positive,

;反之IoU<0.3時(shí),認(rèn)為是該anchor是negative,

;至于那些0.3

代表predict bounding box,

代表對(duì)應(yīng)positive anchor對(duì)應(yīng)的GT box??梢钥吹剑麄€(gè)Loss分為2部分:

cls loss,即rpn_cls_loss層計(jì)算的softmax loss,用于分類anchors為positive與negative的網(wǎng)絡(luò)訓(xùn)練

reg loss,即rpn_loss_bbox層計(jì)算的soomth L1 loss,用于bounding box regression網(wǎng)絡(luò)訓(xùn)練。注意在該loss中乘了?

?,相當(dāng)于只關(guān)心positive anchors的回歸(其實(shí)在回歸中也完全沒必要去關(guān)心negative)。

由于在實(shí)際過程中,

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

,

時(shí)設(shè)置?

?),使總的網(wǎng)絡(luò)Loss計(jì)算過程中能夠均勻考慮2種Loss。這里比較重要是?

?使用的soomth L1 loss,計(jì)算公式如下:

了解數(shù)學(xué)原理后,反過來看圖18:

在RPN訓(xùn)練階段,rpn-data(python AnchorTargetLayer)層會(huì)按照和test階段Proposal層完全一樣的方式生成Anchors用于訓(xùn)練

對(duì)于rpn_loss_cls,輸入的rpn_cls_scors_reshape和rpn_labels分別對(duì)應(yīng)?

?與?

?,?

?參數(shù)隱含在

的caffe blob的大小中

對(duì)于rpn_loss_bbox,輸入的rpn_bbox_pred和rpn_bbox_targets分別對(duì)應(yīng)?

?與?

?,rpn_bbox_inside_weigths對(duì)應(yīng)?

,rpn_bbox_outside_weigths未用到(從soomth_L1_Loss layer代碼中可以看到),而?

?同樣隱含在caffe blob大小中

這樣,公式與代碼就完全對(duì)應(yīng)了。特別需要注意的是,在訓(xùn)練和檢測(cè)階段生成和存儲(chǔ)anchors的順序完全一樣,這樣訓(xùn)練結(jié)果才能被用于檢測(cè)!

5.2 通過訓(xùn)練好的RPN網(wǎng)絡(luò)收集proposals

在該步驟中,利用之前的RPN網(wǎng)絡(luò),獲取proposal rois,同時(shí)獲取positive softmax probability,如圖20,然后將獲取的信息保存在python pickle文件中。該網(wǎng)絡(luò)本質(zhì)上和檢測(cè)中的RPN網(wǎng)絡(luò)一樣,沒有什么區(qū)別。

圖20 rpn_test.pt

5.3 訓(xùn)練Faster RCNN網(wǎng)絡(luò)

讀取之前保存的pickle文件,獲取proposals與positive probability。從data層輸入網(wǎng)絡(luò)。然后:

將提取的proposals作為rois傳入網(wǎng)絡(luò),如圖21藍(lán)框

計(jì)算bbox_inside_weights+bbox_outside_weights,作用與RPN一樣,傳入soomth_L1_loss layer,如圖21綠框

這樣就可以訓(xùn)練最后的識(shí)別softmax與最終的bounding box regression了。

圖21 stage1_fast_rcnn_train.pt

之后的stage2訓(xùn)練都是大同小異,不再贅述了。Faster R-CNN還有一種end-to-end的訓(xùn)練方式,可以一次完成train,有興趣請(qǐng)自己看作者GitHub吧。

rbgirshick py-faster-rcnn?github.com

Questions and Answer

此篇文章初次成文于2016年內(nèi)部學(xué)習(xí)分享,再后來經(jīng)多次修正和完善成為現(xiàn)在的樣子。感謝大家一直以來的支持,現(xiàn)在總結(jié)常見疑問回答如下:

為什么Anchor坐標(biāo)中有負(fù)數(shù)

回顧anchor生成步驟:首先生成9個(gè)base anchor,然后通過坐標(biāo)偏移在?

?大小的?

?下采樣FeatureMap每個(gè)點(diǎn)都放上這9個(gè)base anchor,就形成了?

?個(gè)anhcors。至于這9個(gè)base anchor坐標(biāo)是什么其實(shí)并不重要,不同代碼實(shí)現(xiàn)也許不同。

顯然這里面有一部分邊緣anchors會(huì)超出圖像邊界,而真實(shí)中不會(huì)有超出圖像的目標(biāo),所以會(huì)有clip anchor步驟。

Anchor到底與網(wǎng)絡(luò)輸出如何對(duì)應(yīng)

VGG輸出?

?的特征,對(duì)應(yīng)設(shè)置?

?個(gè)anchors,而RPN輸出?

?的分類特征矩陣和?

?的坐標(biāo)回歸特征矩陣。

其實(shí)在實(shí)現(xiàn)過程中,每個(gè)點(diǎn)的?

?個(gè)分類特征與?

?回歸特征,與?

?個(gè)anchor逐個(gè)對(duì)應(yīng)即可,這實(shí)際是一種“人為設(shè)置的邏輯映射”。當(dāng)然,也可以不這樣設(shè)置,但是無論如何都需要保證在訓(xùn)練和測(cè)試過程中映射方式必須一致。

為何有ROI Pooling還要把輸入圖片resize到固定大小的MxN

由于引入ROI Pooling,從原理上說Faster R-CNN確實(shí)能夠檢測(cè)任意大小的圖片。但是由于在訓(xùn)練的時(shí)候需要使用大batch訓(xùn)練網(wǎng)絡(luò),而不同大小輸入拼batch在實(shí)現(xiàn)的時(shí)候代碼較為復(fù)雜,而且當(dāng)時(shí)以Caffe為代表的第一代深度學(xué)習(xí)框架也不如Tensorflow和PyTorch靈活,所以作者選擇了把輸入圖片resize到固定大小的800x600。這應(yīng)該算是歷史遺留問題。

另外很多問題,都是屬于具體實(shí)現(xiàn)問題,真誠(chéng)的建議讀者閱讀代碼自行理解。

參考文獻(xiàn)

Object Detection and Classification using R-CNNs?www.telesens.co

拓展

檢測(cè)算法的評(píng)價(jià)指標(biāo):

請(qǐng)問目標(biāo)檢測(cè)中的detection performance一般是指那個(gè)指標(biāo),還是一個(gè)統(tǒng)稱??www.zhihu.com

Faster RCNN在文字檢測(cè)中的應(yīng)用:CTPN

場(chǎng)景文字檢測(cè)—CTPN原理與實(shí)現(xiàn)?zhuanlan.zhihu.com

Faster RCNN在高德導(dǎo)航中的應(yīng)用:

機(jī)器學(xué)習(xí)在交通標(biāo)志檢測(cè)與精細(xì)分類中的應(yīng)用?mp.weixin.qq.com

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容