介紹
FPN是一種利用常規(guī)CNN模型來高效提取圖片中各維度特征的方法澜公。在計算機視覺學科中坟乾,多維度的目標檢測一直以來都是通過將縮小或擴大后的不同維度圖片作為輸入來生成出反映不同維度信息的特征組合。這種辦法確實也能有效地表達出圖片之上的各種維度特征甚侣,但卻對硬件計算能力及內(nèi)存大小有較高要求殷费,因此只能在有限的領(lǐng)域內(nèi)部使用。
FPN通過利用常規(guī)CNN模型內(nèi)部從底至上各個層對同一scale圖片不同維度的特征表達結(jié)構(gòu)详羡,提出了一種可有效在單一圖片視圖下生成對其的多維度特征表達的方法实柠。它可以有效地賦能常規(guī)CNN模型,從而可以生成出表達能力更強的feature maps以供下一階段計算機視覺任務(wù)像object detection/semantic segmentation等來使用窒盐。本質(zhì)上說它是一種加強主干網(wǎng)絡(luò)CNN特征表達的方法登钥。
Featurized image pyramid
下圖中描述了四種不同的得到一張圖片多維度特征組合的方法。
上圖(a)中的方法即為常規(guī)的生成一張圖片的多維度特征組合的經(jīng)典方法看锉。即對某一輸入圖片我們通過壓縮或放大從而形成不同維度的圖片作為模型輸入,使用同一模型對這些不同維度的圖片分別處理后伯铣,最終再將這些分別得到的特征(feature maps)組合起來就得到了我們想要的可反映多維度信息的特征集腔寡。此種方法缺點在于需要對同一圖片在更改維度后輸入處理多次,因此對計算機的算力及內(nèi)存大小都有較高要求放前。
圖(b)中的方法則只拿單一維度的圖片做為輸入凭语,然后經(jīng)CNN模型處理后,拿最終一層的feature maps作為最終的特征集似扔。顯然此種方法只能得到單一維度的信息。優(yōu)點是計算簡單豪墅,對計算機算力及內(nèi)存大小都無過高需求黔寇。此方法為大多數(shù)R-CNN系列目標檢測方法所用像R-CNN/Fast-RCNN/Faster-RCNN等。因此最終這些模型對小維度的目標檢測性能不是很好状囱。
圖(c)中的方法同樣是拿單一維度的圖片做為輸入倘是,不過最終選取用于接下來分類或檢測任務(wù)時的特征組合時袭艺,此方法不只選用了最后一層的high level feature maps猾编,同樣也會選用稍靠下的反映圖片low level 信息的feature maps。然后將這些不同層次(反映不同level的圖片信息)的特征簡單合并起來(一般為concat處理)答倡,用于最終的特征組合輸出。此方法可見于SSD當中获茬。不過SSD在選取層特征時都選用了較高層次的網(wǎng)絡(luò)。比如在它以VGG16作為主干網(wǎng)絡(luò)的檢測模型里面所選用的最低的Convolution的層為Conv4鹏氧,這樣一些具有更低級別信息的層特征像Conv2/Conv3就被它給漏掉了佩谣,于是它對更小維度的目標檢測效果就不大好。
圖(d)中的方法同圖(c)中的方法有些類似吊履,也是拿單一維度的圖片作為輸入调鬓,然后它會選取所有層的特征來處理然后再聯(lián)合起來做為最終的特征輸出組合。(作者在論文中拿Resnet為實例時并沒選用Conv1層冕臭,那是為了算力及內(nèi)存上的考慮燕锥,畢竟Conv1層的size還是比較大的,所包含的特征跟直接的圖片像素信息也過于接近)托慨。另外還對這些反映不同級別圖片信息的各層自上向下進行了再處理以能更好地組合從而形成較好的特征表達(詳細過程會在下面章節(jié)中進一步介紹)暇榴。而此方法正是我們本文中要講的FPN CNN特征提取方法。
FPN基本架構(gòu)
FPN會使用CNN網(wǎng)絡(luò)中每一層的信息來生成最后的表達特征組合婆硬。下圖是它的基本架構(gòu)奸例。從中我們能看到FPN會模型每個CNN層的特征輸出進行處理以生成反映此維度信息的特征。而自上至下處理后所生成出的特征之間也有個關(guān)聯(lián)關(guān)系谐区,即上層high level的特征會影響下一層次的low level特征表達逻卖。最終所有的特征一起用來作為下一步的目標檢測或類別分析等任務(wù)的輸入评也。
FPN詳細介紹
FPN是傳統(tǒng)CNN網(wǎng)絡(luò)對圖片信息進行表達輸出的一種增強戈鲁。它目的是為了改進CNN網(wǎng)絡(luò)的特征提取方式嘹叫,從而可以使最終輸出的特征更好地表示出輸入圖片各個維度的信息罩扇。它的基本過程有三個分別為:自下至上的通路即自下至上的不同維度特征生成;自上至下的通路即自上至下的特征補充增強喂饥;CNN網(wǎng)絡(luò)層特征與最終輸出的各維度特征之間的關(guān)聯(lián)表達。
我們在下圖中能看出這三個過程的細粒度表示或粮。
- 自下至上的通路(Bottom-top pathway):這個沒啥奇怪就是指的普通CNN特征自底至上逐層濃縮表達特征的一個過程氯材。此過程很早即被認識到了即較底的層反映較淺層次的圖片信息特征像邊緣等硝岗;較高的層則反映較深層次的圖片特征像物體輪廓、乃至類別等冗尤;
- 自上至下的通路(Top-bottome pathway):上層的特征輸出一般其feature map size比較小胀溺,但卻能表示更大維度(同時也是更加high level)的圖片信息。此類high level信息經(jīng)實驗證明能夠?qū)罄m(xù)的目標檢測背零、物體分類等任務(wù)發(fā)揮關(guān)鍵作用扯躺。因此我們在處理每一層信息時會參考上一層的high level信息做為其輸入(這里只是在將上層feature map等比例放大后再與本層的feature maps做element wise相加);
- CNN層特征與每一級別輸出之間的表達關(guān)聯(lián):在這里作者實驗表明使用1x1的Conv即可生成較好的輸出特征,它可有效地降低中間層次的channels 數(shù)目。最終這些1x1的Convs使得我們輸出不同維度的各個feature maps有著相同的channels數(shù)目(本文用到的Resnet-101主干網(wǎng)絡(luò)中禾乘,各個層次特征的最終輸出channels數(shù)目為256)始藕。
FPN在目標檢測中的實際應(yīng)用
以下為一個FPN特征提取方法在RCNN目標檢測框架中應(yīng)用的例子氮趋。從中我們可以更加詳細地了解到它的具體實現(xiàn)江耀。
代碼實例
以下為p4與p3層之間Up-bottom pathway及各自層上的lateral connections處理祥国。其它層次之間的關(guān)系與此類似。
layer {
bottom: "p4"
top: "p4_lateral"
name: "p4_lateral"
param {
lr_mult: 1.0
}
param {
lr_mult: 2.0
}
type: "Convolution"
convolution_param {
num_output: 256
kernel_size: 1
weight_filler { type: "gaussian" std: 0.001 }
bias_filler { type: "constant" value: 0.0 }
}
}
layer {
name: "upP4"
type: "Deconvolution"
bottom: "p4_lateral"
top: "upP4"
convolution_param {
kernel_h : 4
kernel_w : 4
stride_h: 2
stride_w: 2
pad_h: 1
pad_w: 1
num_output: 256
group: 256
bias_term: false
weight_filler {
type: "bilinear"
}
}
param { lr_mult: 0 decay_mult: 0 }
}
layer {
bottom: "res3d"
top: "c3"
name: "newC3"
param {
lr_mult: 1.0
}
param {
lr_mult: 2.0
}
type: "Convolution"
convolution_param {
num_output: 256
kernel_size: 1
weight_filler { type: "gaussian" std: 0.001 }
bias_filler { type: "constant" value: 0.0 }
}
}
layer {
name: "p3"
type: "Eltwise"
bottom: "c3"
bottom: "upP4"
top: "p3"
eltwise_param {
operation: SUM
}
}
layer {
bottom: "p3"
top: "p3_lateral"
name: "p3_lateral"
param {
lr_mult: 1.0
}
param {
lr_mult: 2.0
}
type: "Convolution"
convolution_param {
num_output: 256
kernel_size: 1
weight_filler { type: "gaussian" std: 0.001 }
bias_filler { type: "constant" value: 0.0 }
}
}
以下幾層則為由p3的feature maps所生成的RPN網(wǎng)絡(luò)。在test網(wǎng)絡(luò)上壁查,它就會生成出一些region proposals來。
#========= RPN/p3 ============
layer {
name: "rpn_conv/3x3/p3"
type: "Convolution"
bottom: "p3"
top: "rpn/output/p3"
param { lr_mult: 1.0
name: "rpn_conv_3x3_w"
}
param { lr_mult: 2.0
name: "rpn_conv_3x3_b"
}
convolution_param {
num_output: 512
kernel_size: 3 pad: 1 stride: 1
weight_filler { type: "gaussian" std: 0.001 }
bias_filler { type: "constant" value: 0 }
}
}
layer {
name: "rpn_relu/3x3/p3"
type: "ReLU"
bottom: "rpn/output/p3"
top: "rpn/output/p3"
}
layer {
name: "rpn_cls_score/p3"
type: "Convolution"
bottom: "rpn/output/p3"
top: "rpn_cls_score/p3"
param { lr_mult: 1.0
name: "rpn_cls_score_w"
}
param { lr_mult: 2.0
name: "rpn_cls_score_b"
}
convolution_param {
num_output: 12 # 2(bg/fg) * 9(anchors)
kernel_size: 1 pad: 0 stride: 1
weight_filler { type: "gaussian" std: 0.001 }
bias_filler { type: "constant" value: 0 }
}
}
layer {
name: "rpn_bbox_pred/p3"
type: "Convolution"
bottom: "rpn/output/p3"
top: "rpn_bbox_pred/p3"
param { lr_mult: 1.0
name:"rpn_bbox_pred_w"
}
param { lr_mult: 2.0
name:"rpn_bbox_pred_b"
}
convolution_param {
num_output: 24 # 4 * 9(anchors)
kernel_size: 1 pad: 0 stride: 1
weight_filler { type: "gaussian" std: 0.001 }
bias_filler { type: "constant" value: 0 }
}
}
######
layer {
bottom: "rpn_cls_score/p3"
top: "rpn_cls_score_reshape_/p3"
name: "rpn_cls_score_reshape_/p3"
type: "Reshape"
reshape_param { shape {dim: 0 dim: 2 dim: -1 dim:0} }
}
layer {
bottom: "rpn_bbox_pred/p3"
top: "rpn_bbox_pred_reshape/p3"
name: "rpn_bbox_pred_reshape/p3"
type: "Reshape"
reshape_param { shape { dim: 0 dim: 0 dim: -1 } }
}
layer {
bottom: "rpn_cls_score_reshape_/p3"
top: "rpn_cls_score_reshape/p3"
name: "rpn_cls_score_reshape/p3"
type: "Reshape"
reshape_param { shape {dim: 0 dim: 2 dim: -1 } }
}
以下為各個特征層所生成出的region proposal 集合。它們將用于接下來的RCNN的輸入沃暗。
#========= RoI Proposal ============
layer {
name: 'proposal'
type: 'Python'
bottom: 'im_info'
bottom: 'rpn_bbox_pred/p2'
bottom: 'rpn_bbox_pred/p3'
bottom: 'rpn_bbox_pred/p4'
bottom: 'rpn_bbox_pred/p5'
bottom: 'rpn_bbox_pred/p6'
bottom: 'fpn_out_reshape/p2'
bottom: 'fpn_out_reshape/p3'
bottom: 'fpn_out_reshape/p4'
bottom: 'fpn_out_reshape/p5'
bottom: 'fpn_out_reshape/p6'
top: 'rpn_rois'
python_param {
module: 'rpn.proposal_layer'
layer: 'ProposalLayer'
param_str: "'feat_stride': 4,8,16,32,64"
}
}
以下為結(jié)合了ROI proposals與bottom data后所生成的對RCNN的正式輸入孽锥。
#================rois process======================
layer {
name: 'roi-data'
type: 'Python'
bottom: 'rpn_rois'
bottom: 'gt_boxes'
bottom: 'data'
top: 'rois/h2'
top: 'rois/h3'
top: 'rois/h4'
top: 'rois/h5'
top: 'labels'
top: 'bbox_targets'
top: 'bbox_inside_weights'
top: 'bbox_outside_weights'
python_param {
module: 'rpn.proposal_target_layer'
layer: 'ProposalTargetLayer'
param_str: "'num_classes': 21"
}
}
參考文獻
- Feature Pyramid Networks for Object Detection, Tsung-Yi Lin, 2017
- https://github.com/unsky/FPN