FPN全稱是Feature Pyramid Network, 也就是特征金字塔網絡,主要是針對圖像中目標的多尺度的這個特點提出的,多尺度在目標檢測中非常常見,而且對應不同的問題應該設計不同的FPN。FPN是Facebook於2017年提出的用於目標檢測的模塊化結構,但FPN在很多計算機視覺任務中都有使用,比如姿態估計、語義分割等領域。
在深度學習興起以前,很多傳統方法都會使用到圖像金字塔。圖像金字塔如上圖所示,就是將圖片resize到不同的大小,然后分別得到對應大小的特征,然后進行預測。這種方法雖然可以一定程度上解決多尺度的問題,但是很明顯,帶來的計算量也非常大。
上圖是使用單個feature map進行檢測,這種結構在17年的時候是很多人在使用的結構,比如YOLOv1、YOLOv2、Faster R-CNN中使用的就是這種架構。直接使用這種架構導致預測層的特征尺度比較單一,對小目標檢測效果比較差。ps: YOLOv2中使用了multi-scale training的方式一定程度上緩解了尺度單一的問題,能夠讓模型適應更多輸入尺度。
上圖進行了在不同大小的feature map上分別進行預測,具有了多尺度預測的能力,但是特征與特征之間沒有融合,遵從這種架構的經典的目標檢測架構就是SSD, SSD用了非常多的尺度來進行檢測。
然后就是非常經典的FPN架構,FPN可以非常方便地應用到兩階段網絡如Faster R-CNN等或者一階段網絡YOLO、SSD等。FPN通過構造一種獨特的特征金字塔來避免圖像金字塔中計算量過高的問題,同時能夠較好地處理目標檢測中的多尺度變化問題,效果能夠達到當時的STOA。SSD的一個改進版DSSD就是使用了FPN,取得了比SSD更好的效果。
這里展開描述一下FPN的細節:
為了方便說明,做出以下規定:
- 圖像backbone部分每個層feature map用\(C_i\)來標記,比如說\(C_3\)代表\(stride=2^3=8\)對應的feature map,通常用\(C_1,...C_6\)代表每個feature map。
- 圖像右側的top-down結構每個feature map用\(P_i\)來標記,比如說\(P_3\)代表對應\(C_3\)大小的feature map。
假設當前層為第三層\(stride=8\), 要與\(stride=16\)的特征進行融合,那么\(C_3\)先通過\(1\times1\)卷積約束通道數和\(P_4\)層達到一致;來自\(P_4\)通過2倍上采樣得到的feature map大小和\(C_3\)一致,最終\(P_3\)是通過\(P_4\)上采樣結果和\(C_3\)進行element wise add得到結果。
那么為什么FPN采用融合以后效果要比使用pyramidal feature hierarchy這種方式要好呢?有以下幾個原因:
- 卷積雖然能夠高效地向上提取語義,但是也存在像素錯位問題,通過上采樣還原特征圖的方式很好地緩解了像素不准的問題。
- backbone可以分為淺層網絡和深層網絡,淺層網絡負責提取目標邊緣等底層特征,而深層網絡可以構建高級的語義信息,通過使用FPN這種方式,讓深層網絡更高級語義的部分的信息能夠融合到稍淺層的網絡,指導淺層網絡進行識別。
- 從感受野的角度思考,淺層特征的感受野比較小,深層網絡的感受野比較大,淺層網絡主要負責小目標的檢測,深層的網絡負責大目標的檢測(比如人臉檢測中的SSH就使用到了這個特點)。在之前發了一篇講感受野和目標檢測的文章中提到了理論感受野和實際感受野,如下圖所示:
黑色的框是理論感受野,中心呈高斯分布的亮點是實際感受野,FPN中的top-down之路通過融合不同感受野,兩個高斯分布的實際感受野進行融合,能夠讓高層加強低層所對應的感受野。(ps:這一部分是筆者的理解,若有不同見解,歡迎討論交流)
關於感受野這個觀點,FPN論文有一張圖,跟之前發表的那篇文章很像,如下圖所示:
這張圖講的是FPN應用在DeepMask中做實例分割,其中使用了一個5×5的多層感知機來生成一個14×14的分割結果。對應的淺橙色的區域代表的是對應到原圖的區域(與理論感受野相似),深橙色區域對應的是典型的目標區域(與實際感受野類似),觀察這個圖我們可以得到幾個結論:
- 網絡越深、特征圖越小對應到原圖的范圍也就越大。這也就可以解釋為什么加上FPN以后,小目標的效果提升了,比如在上圖的\(P_3\)到\(P_5\)中,\(P_3\)對應的目標區域要小一些,更符合小目標的大小。
- 在同一層中,理論感受野的范圍要大於實際感受野。
以上這點很多講解FPN網絡的作者們都忽略了,如果對這個部分感興趣,可以到FPN中的附錄中找到詳細解讀。
消融實驗
以上是FPN各部分的專有名稱,作者詳細對比了top-down pathway帶來的增益,lateral connection帶來的增益,
上表中的實驗中能得到幾個結論:
- 通過(a)和(b)比較,說明隨着網絡深入,小目標檢測效果會變差,大目標檢測效果會變好。
- 通過(d)和(e)比較,說明lateral connections是非常有必要的
- 通過(f)和(c)比較,說明只用最后一層\(P_2\)效果不如使用\(P_2,P_3,P_4\)
- 通過(f)和(c)比較,還可以發現由於\(P_2\)的空間分辨率比較高,anchor非常多,可以得到一個結論就是:僅僅是使用非常多的anchor這一點本身是不足以提升准確率的。
文章中還有幾個實驗將FPN添加到RPN網絡、DeepMask結構中,都帶來不錯的效果,FPN確實是一個比較好的feature fusion方法,在此之后,有很多架構的網絡也不斷地被提出來,都帶來了一定的提升。
總結
本來這篇文章想要將FPN架構的系列寫完,但是這樣篇幅太大了,所以將這個列成一個小的系列,專門關心FPN的設計。
之前和一個群友在討論的時候聊到了FPN的設計,當時靈感迸發,產生以下想法:
- 淺層網絡負責小目標檢測,深層網絡負責大目標檢測,這兩部分融合的時候一般是通過簡單的add或者concate進行融合的,為什么一定要這樣融合?
- 淺層小目標信息比較豐富,深層網絡具有高級語義,能夠一定程度上指導小目標的檢測,這里的淺層和深層能夠添加一個權重來具體決定哪個部分占比比較大嗎?
- 具體怎么決定淺層網絡和深層網絡的占比?通過先驗固定取值,還是自適應通過網絡學習得到?
其實看論文比較多的讀者可能已經想到了,ASFF, BiFPN,BiSeNet,ThunderNet等,這都是比較好解決這個問題的方法。之后會繼續解讀這幾個網絡中關於FPN的設計,也歡迎大家交流自己的想法。
特征融合方式總結
- 兩層特征add,eg:FPN
- 兩層特征concate,eg:YOLOv3
- 使用注意力機制, eg: BiSeNet, ThunderNet
- weighted add, eg: BiFPN