Mask_RCNN代碼研讀(matterport版本)系列文(二)- Feature Pyramid Network部份
- 前言
- 訓練及推論模式中的共同部份
- Feature Pyramid Network
- 小結
- 參考連結
前言
在本系列的第一篇Mask_RCNN代碼研讀(matterport版本)系列文(一)- ResNet部份中,我們了解到ResNet在Mask RCNN的大架構裡扮演的是特徵抽取器(backbone)的角色,而這些feature maps將被Feature Pyramid Network(以下簡稱FPN)用來進一步構建在更層語義訊息皆很強的特徵。在本篇中將會接著對FPN進行探討。
對FPN還不了解的同學可以先看看Feature Pyramid Networks for Object Detection論文研讀與問題討論這篇文章。
訓練及推論模式中的共同部份
Feature Pyramid Network
以下是論文中闡述FPN的圖:
筆者參考代碼,畫了一個更能與代碼對應的圖:
FPN共由三個部份所組成,分別是:bottom-up pathway,top-bottom pathway及lateral connection。
其中bottom-up pathway就是backbone(即ResNet)中的前向傳播部份,會生成
C
1
C_1
C1 ~
C
5
C_5
C5。(
C
1
C_1
C1未畫出)
top-bottom pathway是上圖中紅色朝下的箭頭。
lateral-connection則是上圖左側朝右的1x1 Conv。
以上這兩步會從
C
1
C_1
C1 ~
C
5
C_5
C5生成
P
2
′
P_2'
P2′ ~
P
5
′
P_5'
P5′。
注意到紅色朝下的箭頭做的是將top-bottom pathway上的feature map做上採樣後與lateral connection出來的feature map做逐元素相加。但是為何是做逐元素相加呢?,這仍是筆者不太明白的地方。
FPN中top-down pathway及lateral connection的作用是什麼呢?論文中作者做了ablation experiment,從中可以看出top-down enrichment的重要性及lateral-connection的重要性。
得到
P
2
′
P_2'
P2′ ~
P
5
′
P_5'
P5′後,還會經過3x3 Convolution,生成
P
2
P_2
P2 ~
P
5
P_5
P5。
P
6
P_6
P6則是由
P
5
P_5
P5下採樣而來,僅為region proposal network(RPN)所用。
至於為何得到P2’~P5’後,還要再做3x3 Convolution?,論文作者說是為了減少上採樣所帶來的aliasing effect。
FPN的輸入
C
2
C_2
C2 ~
C
5
C_5
C5間有很大的語義鴻溝,詳見使用deep ConvNet固有的feature hierarchy。
FPN會為這些feature maps做處理,得到在各層皆有很強語義訊息的
P
2
P_2
P2 ~
P
6
P_6
P6。
如果直接使用
C
2
C_2
C2 ~
C
5
C_5
C5來做預測會怎麼樣呢?論文作者做了ablation experiment,結果詳見:
top-down enrichment的重要性及Fast R-CNN物體偵測效果的變化的(c)及(d)。
這些feature maps會接著送進RPN得到候選框,也會被稍後的classifier, regressor及mask branch所使用。
classifier, regressor及mask branch被稱作網路的頭部。而這些頭部是被
P
2
P_2
P2 ~
P
6
P_6
P6所共享的。
這個repo裡的FPN並沒有獨立成一個函數,而是直接寫在MaskRCNN這個類別裡。
以下是它的代碼:
# Top-down Layers
# TODO: add assert to varify feature map sizes match what's in config
P5 = KL.Conv2D(config.TOP_DOWN_PYRAMID_SIZE, (1, 1), name='fpn_c5p5')(C5)
P4 = KL.Add(name="fpn_p4add")([
KL.UpSampling2D(size=(2, 2), name="fpn_p5upsampled")(P5),
KL.Conv2D(config.TOP_DOWN_PYRAMID_SIZE, (1, 1), name='fpn_c4p4')(C4)])
P3 = KL.Add(name="fpn_p3add")([
KL.UpSampling2D(size=(2, 2), name="fpn_p4upsampled")(P4),
KL.Conv2D(config.TOP_DOWN_PYRAMID_SIZE, (1, 1), name='fpn_c3p3')(C3)])
P2 = KL.Add(name="fpn_p2add")([
KL.UpSampling2D(size=(2, 2), name="fpn_p3upsampled")(P3),
KL.Conv2D(config.TOP_DOWN_PYRAMID_SIZE, (1, 1), name='fpn_c2p2')(C2)])
# Attach 3x3 conv to all P layers to get the final feature maps.
P2 = KL.Conv2D(config.TOP_DOWN_PYRAMID_SIZE, (3, 3), padding="SAME", name="fpn_p2")(P2)
P3 = KL.Conv2D(config.TOP_DOWN_PYRAMID_SIZE, (3, 3), padding="SAME", name="fpn_p3")(P3)
P4 = KL.Conv2D(config.TOP_DOWN_PYRAMID_SIZE, (3, 3), padding="SAME", name="fpn_p4")(P4)
P5 = KL.Conv2D(config.TOP_DOWN_PYRAMID_SIZE, (3, 3), padding="SAME", name="fpn_p5")(P5)
# P6 is used for the 5th anchor scale in RPN. Generated by
# subsampling from P5 with stride of 2.
P6 = KL.MaxPooling2D(pool_size=(1, 1), strides=2, name="fpn_p6")(P5)
# Note that P6 is used in RPN, but not in the classifier heads.
rpn_feature_maps = [P2, P3, P4, P5, P6]
mrcnn_feature_maps = [P2, P3, P4, P5]
C
2
C_2
C2 ~
C
5
C_5
C5是前篇介紹的ResNet輸出的feature maps。
而此處的FPN會接受
C
2
C_2
C2 ~
C
5
C_5
C5當作輸入,並輸出
P
2
P_2
P2 ~
P
6
P_6
P6。
代碼的上半部可以對應到上圖的左側,即由
C
2
C_2
C2 ~
C
5
C_5
C5生成
P
2
′
P_2'
P2′ ~
P
5
′
P_5'
P5′(在此把這個中間結果稱作
P
2
′
P_2'
P2′ ~
P
5
′
P_5'
P5′)。
我們可以看到
P
5
′
P_5'
P5′是由
C
5
C_5
C5做1x1 Conv2D而來。
而
P
4
′
P_4'
P4′是由經過2x2 upsampling後的
P
5
′
P_5'
P5′與做過1x1 Conv2D的
C
4
C_4
C4相加而來。
P
3
P_3
P3與
P
2
P_2
P2也是經歷同樣的過程而得來的。
注意到
C
2
C_2
C2 ~
C
5
C_5
C5在經過Conv2D後的厚度都變為config.TOP_DOWN_PYRAMID_SIZE。這是在config.py檔案裡設置的參數,用於調控top-down pathway上的feature maps的厚度,預設值為256。
而代碼的下半部則對應到上圖的右側。
P
2
′
P_2'
P2′ ~
P
5
′
P_5'
P5′做3x3 Conv2D後得到
P
2
P_2
P2 ~
P
5
P_5
P5,而
P
6
P_6
P6是由
P
5
P_5
P5下採樣而來。
最後
P
2
P_2
P2 ~
P
6
P_6
P6會用作RPN的輸入feature maps。
而
P
2
P_2
P2 ~
P
5
P_5
P5則作為classifier, regressor, mask head的輸入feature maps。
小結
在本篇中我們看到了FPN會利用ResNet輸出的
C
2
C_2
C2 ~
C
5
C_5
C5,建構在各層語義訊息皆很強的
P
2
P_2
P2 ~
P
6
P_6
P6。
而它們在下一步將會為region proposal network(RPN)及classifier, regressor, mask head所使用。
下一篇我們將會介紹RPN本身以及它在Mask RCNN這個大架構裡所發揮的作用。
參考連結
Mask_RCNN代碼研讀(matterport版本)系列文(一)- ResNet部份
Feature Pyramid Networks for Object Detection論文研讀與問題討論
為何是做逐元素相加呢?
top-down enrichment的重要性
lateral-connection的重要性
為何得到P2’~P5’後,還要再做3x3 Convolution?
使用deep ConvNet固有的feature hierarchy
Fast R-CNN物體偵測效果的變化
這些頭部是被
P
2
P_2
P2 ~
P
6
P_6
P6所共享的