金字塔c_FPN特征金字塔网络解读
上傳在github:https://github.com/FermHan/Learning-Notes發(fā)表在CSDN:https://blog.csdn.net/hancoder/article/發(fā)表在知乎專欄:https://zhuanlan.zhihu.com/c_1088438808227254272
預(yù)備知識(shí): Faster R-CNN,RPN可見本人博客https://blog.csdn.net/hancoder/article/details/87917174
Feature Pyramid Networks for Object Detection (簡(jiǎn)稱FPN)
作者Tusing-Yi Lin,Ross Girshich,Kaiming He
[TOC]
1、常見卷積與FPN模型
首先看幾種卷積分類方式
(a) Featurized image pyramid 計(jì)算與內(nèi)存開銷太大
剛開始你可能會(huì)不熟悉這4個(gè)命名方式,你只需記住第一個(gè)里是圖像image金字塔,而FPN是特征feature金字塔。因?yàn)樾枰s放原圖然后進(jìn)行卷積,這種卷積方式肯定是耗內(nèi)存的,最不科學(xué)的。
(b) Single feature map 框不出小物體
b所講的就是簡(jiǎn)單的分類網(wǎng)絡(luò),如AlexNet等。使用Single feature map的包括R-CNN、SPPNet、Fast R-CNN、Faster R-CNN、YOLOv1以及R-FCN系列。
(c) Pyramidal feature hierarchy 底層大scale的feature map語義信息少,雖然框出了小物體,但小物體容易被錯(cuò)分:
使用Pyramidal feature hierarchy的包括SSD。SSD沒有上采樣過程,因?yàn)槭窃谠刑卣鲌D上預(yù)測(cè)的,所以也不會(huì)增加額外的計(jì)算開銷,但作者認(rèn)為SSD沒有用到足夠底層的特征,而越底層的特征對(duì)檢測(cè)小物體越有利。SSD用的最底層的特征是conv4_3。SSD也可以去我的CSDN等地觀看。
Note:
- YOLOv2是個(gè)特例,其在 26×26 層設(shè)置了通道層接至 13×13 層。本質(zhì)上即為single-scale上處理two-scale的feature map信息。
總結(jié):上面abc這三種卷積方式都不是特征理想,那么怎么才能兼顧準(zhǔn)確率(檢測(cè)小物體)和速度(開銷)呢?
FPN的框架
(d) Feature Pyramid Network
參照d圖及下圖。特征金字塔網(wǎng)絡(luò)相當(dāng)于先進(jìn)行傳統(tǒng)的bottom-up自上而下的特征卷積(d圖左側(cè)),然后FPN試圖融合左側(cè)特征圖的相鄰的特征圖。左側(cè)模型叫bottom-up,右側(cè)模型叫top-down,橫向的箭頭叫橫向連接lateral connections。這么做的目的是因?yàn)楦邔拥奶卣髡Z義多,低層的特征語義少但位置信息多。
左側(cè)模型特征圖大小相差1倍,但像AlexNet一樣,其實(shí)是每在同樣大小的feature上卷積幾次才進(jìn)行一次池化操作,我們把在同樣大小feature上的卷積稱之為一個(gè)stage。d圖這里畫的圖是每個(gè)stage的最后一個(gè)卷積層,因?yàn)槊總€(gè)stage的最后一層feature語義信息最多
具體做法是兩個(gè)特征層的較高層特征2倍上采樣(上采樣方法很多,上采樣幾乎都是采用內(nèi)插值方法,即在原有圖像像素的基礎(chǔ)上在像素點(diǎn)之間采用合適的插值算法插入新的元素,總之是把feature大小擴(kuò)大了一倍)。較低層特征通過1×1卷積改變一下低層特征的通道數(shù),然后簡(jiǎn)單地把將上采樣和1×1卷積后的結(jié)果對(duì)應(yīng)元素相加。為什么橫向連接要使用1×1卷積呢,為什么不能原地不動(dòng)地拿過來呢?原來在于作者想用1×1改變通道數(shù),以達(dá)到各個(gè)level處理結(jié)果的channel都為256-d,便于后面對(duì)加起來的特征進(jìn)行分類。這段文字表述的即是下圖。
FPN只是提取特征的一種方法而已,這篇論文作者的應(yīng)用于實(shí)驗(yàn)主要是在Faster R-CNN上進(jìn)行的。
雖然d圖只畫了3個(gè)stage,但我們以論文描述的為主,其實(shí)最起碼有6個(gè)stage。左側(cè)模型從低到高的卷積結(jié)果記為C2,C3,C4,C5,C6(有C1,但是論文里是拋棄了這層,為了不造成混淆,所以這里自動(dòng)忽略了),同理右側(cè)模型從低到高記為P2,P3,P4,P5,P6。接下來的內(nèi)容最好聯(lián)系下圖Faster R-CNN網(wǎng)絡(luò)進(jìn)行學(xué)習(xí)。
先在圖像上進(jìn)行完像圖d一樣的操作后,得到FPN的結(jié)果,結(jié)果即d圖右側(cè)模型$P_i$。而d圖左側(cè)是普通的主干網(wǎng)絡(luò)$C_i$。然后我們?cè)贔PN的結(jié)果(d圖右側(cè))上進(jìn)行操作:像Faster R-CNN中的RPN一樣,先在$P_i$上進(jìn)行3×3的卷積操作,然后在此結(jié)果上,兩支并行的1×1卷積核分別卷積出來分類(前背景)與框位置信息(xywh)。
然后我們把RPN的結(jié)果拿出來進(jìn)行RoIpooling后進(jìn)行分類。
至此FPN的框架介紹結(jié)束,簡(jiǎn)言之把FPN結(jié)合到普通網(wǎng)絡(luò)中后,有三條路線:Bottom-up pathway + Top-down pathway + lateral connections。
2、框架三部分Details
Bottom-up pathway
Bottom-up的畫的是每個(gè)stage的最后一層feature,這個(gè)我們已經(jīng)前文說過,因?yàn)樵搶佑凶顂trong的特征。
此文用的是ResNet,所以$C_i={C_2,C_3,C_4,C_5}?$,分別對(duì)應(yīng)conv2,conv3,conv4,conv5的輸出,與原圖相比的步長(zhǎng)分別是{4,8,16,32}。不要conv1的原因是its large memory footprint(能體會(huì)但是不會(huì)翻譯)。
Top-down pathway and lateral connections
上采樣操作降低了特征的分辨率(hallucinate higher resolution features,這句可能沒理解好,望糾正)。但是這些上采樣的結(jié)果通過與橫向連接結(jié)合,相加更好enhance了。相加的兩者中,bottom-up的特征$C_i$雖然語義信息較少,但他的位置信息較多,因?yàn)樗南虏蓸哟螖?shù)更少。The bottom-up feature map is of lower-level semantics,but its activations are more accurately localized as it was subsampled fewer times
在ResNet中,先在$C_5$上進(jìn)行1×1卷積降維通道數(shù),與上采樣結(jié)果相加融合后用3×3卷積處理,以減小上采樣帶來的混淆現(xiàn)象(附原文We append a 3×3 convolution on each merged map to generate the final feature map,which is to reduce the aliasing effect of upsampling)。相加的結(jié)果稱為${P_2,P_3,P_4,P_5}$,與同樣大小的$C_i$對(duì)應(yīng)。
因?yàn)榻鹱炙屑?jí)level使用相同的分類/回歸器(這句應(yīng)該指的是RPN),所以固定了特征圖上的通道數(shù)d都為256,即每個(gè)stage或每個(gè)level的特征圖$P_i?$的通道數(shù)都是d=256。
由上圖可以看出(圖上P5P6處有些錯(cuò)誤),我們的C2-C5是正常卷積出來的,P5是1×1卷積改變通道數(shù)256后的結(jié)果,其余P4,P3,P2是1×1卷積和上采樣加和的融合。然后P2-P5經(jīng)過3×3卷積后仍然叫P2-P5(Pi處理后賦值給Pi)。P6是從P5極大值池化后直接得到的
3、應(yīng)用
FPN for RPN
RPN即一個(gè)用于目標(biāo)檢測(cè)的一系列滑動(dòng)窗口。具體地,RPN是先進(jìn)行3×3,然后跟著兩條并行的1×1卷積,分布產(chǎn)生前背景分類和框位置回歸,我們把這個(gè)組合叫做網(wǎng)絡(luò)頭部network head。
但是前背景分類與框位置回歸是在anchor的基礎(chǔ)上進(jìn)行的,簡(jiǎn)言之即我們先人為定義一些框,然后RPN基于這些框進(jìn)行調(diào)整即可。在SSD中anchor叫prior,更形象一些。為了回歸更容易,anchor在Faster R-CNN中預(yù)測(cè)了3種大小scale,寬高3種比率ratio{1:1,1:2,2:1},共9種anchor框。
在FPN中我們同樣用了一個(gè)3×3和兩個(gè)并行的1×1,但是是在每個(gè)級(jí)上都進(jìn)行了RPN這種操作。既然FPN已經(jīng)有不同大小的特征scale了,那么我們就沒必要像Faster R-CNN一樣采用3中大小的anchor了,我們只要采用3種比率的框就行了。所以每個(gè)級(jí)level的anchor都是相同的scale。所以我們?cè)?{P_2,P_3,P_4,P_5,P_6}$上分別定義anchor的scale為${32^2,64^2,128^2,256^2,521^2}$,在每級(jí)level的$P_i?$上有{1:1,1:2,2:1}三種寬高比率ratio的框。所以我們?cè)谔卣鹘鹱炙峡偣灿?5個(gè)anchor。
RPN訓(xùn)練時(shí)需要有anchor的前背景類標(biāo)。對(duì)anchor進(jìn)行l(wèi)abel的原理和Faster R-CNN里一模一樣,詳情可以去本人博客https://blog.csdn.net/hancoder/article/details/87917174 的RPNlabel部分查看。反正就是與gt的IoU>0.7就是正類label=1,IoU<0.3是負(fù)類背景l(fā)abel=0,其余介于0.3和0.7直接的都扔掉不參與訓(xùn)練label=-1。在faster rcnn中拿256個(gè)anchors訓(xùn)練后得到W×H×9個(gè)roi。
此外,每個(gè)級(jí)level的頭部的參數(shù)是共享的,共享的原因是實(shí)驗(yàn)驗(yàn)證出來的。實(shí)驗(yàn)證明,雖然每級(jí)的feature大小不一樣,但是共享與不共享頭部參數(shù)的準(zhǔn)確率是相似的。這個(gè)結(jié)果也說明了其實(shí)金字塔的每級(jí)level都有差不多相似的語義信息,而不是普通網(wǎng)絡(luò)那樣語義信息區(qū)別很大。
FPN for Fast R-CNN
RPN抽取到特征后,Fast R-CNN用RoIpool抽取出RoI后進(jìn)行分類。Fast R-CNN is a region-based object detector in which Region-of-Interest(RoI) pooling is used to extract features.Fast R-CNN在單scale特征上有好的表現(xiàn)。為了使用FPN,需要把各個(gè)scale的RoI賦給金字塔級(jí)level。Fast rcnn中的ROI Pooling層使用region proposal的結(jié)果和特征圖作為輸入。經(jīng)過特征金字塔,我們得到了許多特征圖,作者認(rèn)為,不同層次的特征圖上包含的物體大小也不同,因此,不同尺度的ROI,使用不同特征層作為ROI pooling層的輸入。大尺度ROI就用后面一些的金字塔層,比如P5;小尺度ROI就用前面一點(diǎn)的特征層,比如P4。
對(duì)于原圖上w×h 的RoI,需要選擇一層的feature map來對(duì)他RoIpooling,選擇的feature map的層數(shù)P_k的選擇依據(jù)是
$k=left lfloor k_0+log_2(sqrt{wh}/224) right rfloor?$
224是ImageNet預(yù)訓(xùn)練的大小,k0是基準(zhǔn)值,設(shè)置為5或4,代表P5層的輸出(原圖大小就用P5層),w和h是ROI區(qū)域的長(zhǎng)和寬,假設(shè)ROI是112 * 112的大小,那么k = k0-1 = 5-1 = 4,意味著該ROI應(yīng)該使用P4的特征層。k值做取整處理。這意味著如果RoI的尺度變小(比如224的1/2),那么它應(yīng)該被映射到一個(gè)精細(xì)的分辨率水平。4、實(shí)驗(yàn)
使用80類的COCO數(shù)據(jù)集,訓(xùn)練集80k,驗(yàn)證集35k+5k(mini),在ImageNet1k上預(yù)訓(xùn)練。使用ResNet-50和Resnet-101模型。
表1 FPN對(duì)RPN的影響:關(guān)心的是召回率AR
下標(biāo)sml指的是gt框的大小small,medium,large
- (a,b)只使用conv4或conv5的R-CNN在召回率上提升10%(a,b),尤其在小物體上提升明顯。(使用相同的超參數(shù)anchors)
- (d)去掉了top-down,只保留橫向連接 。即去掉了上采樣。相當(dāng)于論文圖1的c。性能僅與原 RPN 差不多,原因可能是不同層的語義信息差別較大。原因在于不同層之間的語義特征差距較大。還測(cè)試了共享/不共享頭部參數(shù)的區(qū)別,都很差。
- (e)去掉了橫向鏈接。相當(dāng)于只上采樣。語義多,但位置不準(zhǔn)確。
- (f)只用P2特征層,不使用金字塔模型。對(duì)應(yīng)論文圖1的(b)。結(jié)果當(dāng)然不是很好。
表2 FPN對(duì)Fast R-CNN的影響:關(guān)心的是準(zhǔn)確率AP
類似于RPN的實(shí)驗(yàn),改變FPN的結(jié)構(gòu),以驗(yàn)證FPN對(duì)Fast R-CNN重要性。
表3FPN對(duì)整個(gè)Faster R-CNN的影響
表4 對(duì)比其他單模型
表5 共享特征
在FPN基礎(chǔ)上,將RPN和Fast R-CNN的特征共享,與原Faster R-CNN一樣,精度得到了小幅提升。
表6 在實(shí)例分割上的表現(xiàn)
5、CVPR現(xiàn)場(chǎng):
海報(bào):https://vision.cornell.edu/se3/wp-content/uploads/2017/07/fpn-poster.pdf
上圖是FPN的海報(bào),Fast R-CNN+FPN與單純的Fast R-CNN沒什么差別。通道數(shù)從1024減小到256減少了計(jì)算量,訓(xùn)練和前向運(yùn)算都快了。
我們利用2個(gè)MLP層取代了Conv5,作為我們的頭分類器;
CVPR 現(xiàn)場(chǎng) QA:
Q1. 不同深度的 feature map 為什么可以經(jīng)過 upsample 后直接相加?
A:作者解釋說這個(gè)原因在于我們做了 end-to-end 的 training,因?yàn)椴煌瑢拥膮?shù)不是固定的,不同層同時(shí)給監(jiān)督做 end-to-end training,所以相加訓(xùn)練出來的東西能夠更有效地融合淺層和深層的信息。
Q2. 為什么 FPN 相比去掉深層特征 upsample(bottom-up pyramid) 對(duì)于小物體檢測(cè)提升明顯?(RPN 步驟 AR 從 30.5 到 44.9,Fast RCNN 步驟 AP 從 24.9 到 33.9)
A:作者在 poster 里給出了這個(gè)問題的答案
對(duì)于小物體,一方面我們需要高分辨率的 feature map 更多關(guān)注小區(qū)域信息,另一方面,如圖中的挎包一樣,需要更全局的信息更準(zhǔn)確判斷挎包的存在及位置。
Q3. 如果不考慮時(shí)間情況下,image pyramid 是否可能會(huì)比 feature pyramid 的性能更高?
A:作者覺得經(jīng)過精細(xì)調(diào)整訓(xùn)練是可能的,但是 image pyramid 主要的問題在于時(shí)間和空間占用太大,而 feature pyramid 可以在幾乎不增加額外計(jì)算量情況下解決多尺度檢測(cè)問題。
后續(xù)
- FPN如今已成為Detecton算法的標(biāo)準(zhǔn)組件,不管是one-stage(RetinaNet、DSSD)、two-stage(Faster R-CNN、Mask R-CNN)還是four-stage(Cascade R-CNN)都可用;
- 何愷明大神的論文Mask R-CNN 獲得ICCV最佳論文,其中也應(yīng)用了FPN網(wǎng)絡(luò)
- R-FCN系由于其自身設(shè)計(jì)的緣故,無法使用FPN;
- 后來者PAN在FPN的基礎(chǔ)上再加了一個(gè)bottom-up方向的增強(qiáng),使得頂層feature map也可以享受到底層帶來的豐富的位置信息,從而把大物體的檢測(cè)效果也提上去了:
6、代碼實(shí)現(xiàn)
# 在此貼出Pi卷積層的代碼,幫助理解 # Build the shared convolutional layers. # Bottom-up Layers # Returns a list of the last layers of each stage, 5 in total. # 扔掉了C1 _, C2, C3, C4, C5 = resnet_graph(input_image, "resnet101", stage5=True) # Top-down Layers # TODO: add assert to varify feature map sizes match what's in config P5 = KL.Conv2D(256, (1, 1), name='fpn_c5p5')(C5) # C5卷積一下就當(dāng)做P5 P4 = KL.Add(name="fpn_p4add")([ # P4 開始有了對(duì)應(yīng)元素add操作KL.UpSampling2D(size=(2, 2), name="fpn_p5upsampled")(P5),KL.Conv2D(256, (1, 1), name='fpn_c4p4')(C4)]) P3 = KL.Add(name="fpn_p3add")([KL.UpSampling2D(size=(2, 2), name="fpn_p4upsampled")(P4),KL.Conv2D(256, (1, 1), name='fpn_c3p3')(C3)]) P2 = KL.Add(name="fpn_p2add")([KL.UpSampling2D(size=(2, 2), name="fpn_p3upsampled")(P3),KL.Conv2D(256, (1, 1), name='fpn_c2p2')(C2)])# Attach 3x3 conv to all P layers to get the final feature maps. P2 = KL.Conv2D(256, (3, 3), padding="SAME", name="fpn_p2")(P2) P3 = KL.Conv2D(256, (3, 3), padding="SAME", name="fpn_p3")(P3) P4 = KL.Conv2D(256, (3, 3), padding="SAME", name="fpn_p4")(P4) P5 = KL.Conv2D(256, (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是P5的極大值池化 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]參考:
https://blog.csdn.net/jningwei/article/details/80661954
https://vision.cornell.edu/se3/wp-content/uploads/2017/07/fpn-poster.pdf FPN的海報(bào)
機(jī)器之心
https://blog.csdn.net/weixin_40683960/article/details/79055537
總結(jié)
以上是生活随笔為你收集整理的金字塔c_FPN特征金字塔网络解读的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于Aws SNS的使用 小结
- 下一篇: Android 全局悬浮按钮,悬浮按钮点