Boundary Aware PoolNet(1):PoolNet模型與代碼介紹

Boundary Aware PoolNet = PoolNet + BASNet,即使用BASNet中的Deep Supervision策略和Hybrid Loss改進PoolNet。

爲理解Boundary Aware PoolNet還是需要全面理解PoolNet的,因此本文將對PoolNet的模型結構及其代碼實現進行介紹。

相關文章彙總:

PoolNet

PoolNet的論文名稱爲:A Simple Pooling-Based Design for Real-Time Salient Object Detection,該論文來自南開程明明老師的實驗室。

傳送門

用一句話概括PoolNet

PoolNet基於FPN(Feature Pyramid Network,特徵金字塔網絡)構造了GGM(Global Guidance Module,全局指導模塊)和FAM(Feature Aggregation Module,特徵聚合模塊)2個模塊,實現了顯著性目標檢測。

PoolNet結構

PoolNet模型結構如下圖所示,其包括:

  1. GGM(下圖中,“P”指PPM,橙色箭頭指GGF)

  2. FAM(即下圖中的“A”)

  3. FPN(即下圖中的U型結構)

    因此下圖中GGM、FAM之外的部分就是FPN。

img

GGM和FAM

img

如上圖所示,GGM包括PPM(Pyramid pooling module,金字塔池化模塊)和GGF(Global Guiding Flows,全局指導流),其作用是在FPN自底向上路徑的頂部提取顯著目標的位置信息並將其提供給FPN自頂向下路徑中的不同金字塔層;FAM位於FPN自頂向下路徑中FUSE操作之前,其作用是使來自GGM的特徵與FPN自頂向下路徑中不同金字塔層的特徵更好地融合。

代碼

PoolNet的代碼在文件./networks/poolnet.py中的類PoolNet中,其調用了Backbone(比如ResNet50)、GGM、FAM等各個模塊。

注意:學習代碼時不只可以看PoolNet官方代碼,還可以看我的Boundary Aware PoolNet的代碼(包含詳細中文註釋,鏈接:https://github.com/chouxianyu/Boundary-Aware-PoolNet)。

接下來將分別介紹PoolNet模型中各個模塊的理論和代碼。

FPN

傳送門

FPN結構

FPN即Feature Pyramid Network(特徵金字塔網絡),其結構如下圖所示。FPN包含1條自底向上路徑(從此輸入)和1條自頂向下路徑(得到輸出),形成1種U型結構。

FPN網絡圖解

自底向上路徑

圖片從該路徑輸入,經過卷積等一系列操作,特徵的尺寸越來越小、通道數越來越多。上圖所示的自底向上路徑中有5個長方體,這並不代表該路徑中只有5層,而是表明在一系列操作中選出5層特徵圖以進一步利用。當然了,也可以選擇數量更多或更少的層。

自頂向下路徑

自頂向下路徑由多個FUSE操作組成,上圖所示的自頂向下路徑中包含4個FUSE操作(數量與自底向上路徑中選取的層的數量對應),將最後1個FUSE操作的輸出作爲整個模型的輸出。

FUSE

一般FPN的FUSE操作有2個輸入,其一是自底向上路徑中的特徵(對其進行1×1卷積),其二是自頂向下路徑中上1個FUSE操作的輸出(對其進行上採樣),分別對這2個輸入進行1×1卷積和上採樣再將兩者相加,最後進行3×3卷積得到該FUSE操作的輸出。

注意:因爲PoolNet引入了GGM,所以PoolNet中的FUSE操作有3個輸入(除了上述的2個輸入還有1個輸入是GGF的輸出),因此PoolNet中FPN的FUSE操作如下圖所示(綠色箭頭代表GGF,可以將上採樣理解爲GGF的一部分)。

img

Backbone

FPN更多是一種結構而非一種網絡,基於FPN這種U型結構,我們可以更換Backbone(骨幹網絡)。什麼是Backbone呢?暫時你可以將Backbone理解爲自底向上路徑中的網絡。常見的Backbone有VGG16、ResNet系列網絡等。PoolNet作者使用了VGG16和RestNet50。

代碼

由上可知,FPN結構可以分爲自底向上路徑和自頂向下路徑。

自底向上路徑即Backbone,ResNet50的代碼在文件./networks/deeplab_resnet.py中的類ResNet中,VGG16的代碼在文件./networks/vgg.py中的類vgg16中。

自頂向下路徑由多個FUSE操作形成,PoolNet作者將FUSE操作的代碼與FAM的代碼一起放在了文件./networks/poolnet.py中的類DeepPoolLayer中。

FPN自底向上路徑和自頂向下路徑中間還有一個1×1卷積,PoolNet作者將該1×1卷積的代碼和GGM的代碼放在了一起。

注意:學習代碼時不只可以看PoolNet官方代碼,還可以看我的Boundary Aware PoolNet的代碼(包含詳細中文註釋,鏈接:https://github.com/chouxianyu/Boundary-Aware-PoolNet)。

GGM

由前文可知,GGM包括PPM(Pyramid pooling module,金字塔池化模塊)和GGF(Global Guiding Flows,全局指導流),其作用是在FPN自底向上路徑的頂部提取顯著目標的位置信息並將其提供給FPN自頂向下路徑中的不同金字塔層。

傳送門

PPM

PPM由PSPNet一文提出。PoolNet中使用的是修改過的PPM,其位置在自底向上路徑的頂部。

PoolNet中使用的PPM包括4個子分支,PoolNet中PPM的實現如下(可結合代碼理解):

  1. 用4個分支對Backbone的輸出進行處理

    第1個分支爲恆等映射層(即不進行處理);後3個分支分別爲輸出尺寸爲1×1的平均池化層(即全局平均池化層)、輸出尺寸爲3×3的平均池化層、輸出尺寸爲5×5的平均池化層,並且這3個平均池化層後面都有一個1×1卷積(不改變通道數)、ReLU、上採樣層(使尺寸與Backbone輸出的尺寸一致)。

  2. 將4個分支的輸出拼接

    首先在通道維度上將4個子分支的輸出拼接,然後用3×3卷積使通道數與Backbone輸出的通道數一致,再加上1個ReLU。

由上可知,PPM輸出特徵的尺寸、通道數與輸入相同。

注意:FPN自底向上路徑和自頂向下路徑中間還有一個1×1卷積,PoolNet作者將這個1×1卷積放在了PPM之前。

GGF

當Backbone爲ResNet50時,則需要4個GGF。

每個GGF的輸入都是PPM的輸出,不同GGF之間的區別是輸出特徵的尺寸、通道數不相同同。

每個GGF的組成爲:上採樣(使尺寸與對應金字塔層的尺寸一致)、3×3卷積、ReLU。

代碼

FPN自底向上路徑和自頂向下路徑中間的1×1卷積、PPM、GGF的代碼都位於類Backbone_locate中。如果Backbone是ResNet50則代碼位於文件./networks/deeplab_resnet.py的類ResNet_locate中,如果Backbone是VGG16則代碼位於文件./networks/vgg.py的類vgg16_locate中。

注意:學習代碼時不只可以看PoolNet官方代碼,還可以看我的Boundary Aware PoolNet的代碼(包含詳細中文註釋,鏈接:https://github.com/chouxianyu/Boundary-Aware-PoolNet)。

FAM

由上可知,PoolNet作者在FPN自頂向下路徑中每個FUSE操作前引入了FAM,其可以使來自GGM的特徵與FPN自頂向下路徑中不同金字塔層的特徵更好地融合。

img

每個FAM包含4個子分支,如上圖所示,其實現如下:

  1. 用4個分支對輸入進行處理

    第1個分支爲恆等映射層(即不進行處理);後3個分支分別爲下采樣比例爲2/4/8的平均池化層,每個平均池化層後爲一個3×3卷積(不改變特徵的通道數和尺寸)和上採樣層(使尺寸與輸入特徵的尺寸一致)

  2. 將4個分支的輸出相加,再送入一個3×3卷積(根據設置改變或不改變通道數)

FAM和FPN的FUSE操作的代碼在文件./networks/poolnet.py中的類DeepPoolLayer中。

注意:學習代碼時不只可以看PoolNet官方代碼,還可以看我的Boundary Aware PoolNet的代碼(包含詳細中文註釋,鏈接:https://github.com/chouxianyu/Boundary-Aware-PoolNet)。


Github(github.com):@chouxianyu

Github Pages(github.io):@臭鹹魚

知乎(zhihu.com):@臭鹹魚

博客園(cnblogs.com):@臭鹹魚

B站(bilibili.com):@絕版臭鹹魚

微信公衆號:@臭鹹魚

轉載請註明出處,歡迎討論和交流!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章