Press "Enter" to skip to content

Boundary Aware PoolNet(1):PoolNet模型与代码介绍

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

 

为理解Boundary Aware PoolNet还是需要全面理解PoolNet的,因此本文将对PoolNet的模型结构及其代码实现进行介绍。

 

相关文章汇总:

 

Boundary Aware PoolNet:基于PoolNet和BASNet的显着性目标检测

 

Boundary Aware PoolNet(1):PoolNet模型与代码介绍

 

Boundary Aware PoolNet(2):BASNet模型与代码介绍

 

Boundary Aware PoolNet(3):Boundary Aware PoolNet模型与代码介绍

 

PoolNet

 

PoolNet的论文名称为:A Simple Pooling-Based Design for Real-Time Salient Object Detection,该论文来自南开程明明老师的实验室。

 

传送门

PoolNet论文: https://arxiv.org/abs/1904.09569
PoolNet代码: https://github.com/backseason/PoolNet
PoolNet论文阅读笔记: https://zhuanlan.zhihu.com/p/358445121

用一句话概括PoolNet

 

PoolNet基于 FPN (Feature Pyramid Network,特征金字塔网络)构造了GGM(Global Guidance Module,全局指导模块)和 FAM (Feature Aggregation Module,特征聚合模块)2个模块,实现了显着性目标检测。

 

PoolNet结构

 

PoolNet模型结构如下图所示,其包括:

 

 

GGM(下图中,“P”指PPM,橙色箭头指GGF)

 

FAM(即下图中的“A”)

 

FPN(即下图中的U型结构)

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

 

 

 

GGM和FAM

 

 

如上图所示, 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论文: https://arxiv.org/abs/1612.03144
ResNet论文: https://arxiv.org/abs/1512.03385
FPN论文阅读笔记: https://zhuanlan.zhihu.com/p/354140540
ResNet论文阅读笔记: https://zhuanlan.zhihu.com/p/353228657
ResNet50网络结构图及结构详解: https://zhuanlan.zhihu.com/p/353235794

FPN结构

 

FPN即Feature Pyramid Network(特征金字塔网络),其结构如下图所示。FPN包含1条自底向上路径(从此输入)和1条自顶向下路径(得到输出),形成1种U型结构。

 

 

自底向上路径

 

图片从该路径输入,经过卷积等一系列操作,特征的尺寸越来越小、通道数越来越多。上图所示的自底向上路径中有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的一部分)。

 

 

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自顶向下路径中的不同金字塔层。

 

传送门

PSPNet论文(PPM出处): https://arxiv.org/abs/1612.01105
PSPNet论文阅读笔记: https://zhuanlan.zhihu.com/p/354860476

PPM

 

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

 

PoolNet中使用的PPM包括4个子分支,PoolNet中PPM的实现如下(可结合代码理解):

 

 

用4个分支对Backbone的输出进行处理

第1个分支为恒等映射层(即不进行处理);后3个分支分别为输出尺寸为1×1的平均池化层(即全局平均池化层)、输出尺寸为3×3的平均池化层、输出尺寸为5×5的平均池化层,并且这3个平均池化层后面都有一个1×1卷积(不改变通道数)、ReLU、上采样层(使尺寸与Backbone输出的尺寸一致)。

 

将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自顶向下路径中不同金字塔层的特征更好地融合。

 

 

每个FAM包含4个子分支,如上图所示,其实现如下:

 

 

用4个分支对输入进行处理

第1个分支为恒等映射层(即不进行处理);后3个分支分别为下采样比例为2/4/8的平均池化层,每个平均池化层后为一个3×3卷积(不改变特征的通道数和尺寸)和上采样层(使尺寸与输入特征的尺寸一致)

 

将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): @绝版臭咸鱼

 

微信公众号: @臭咸鱼

 

转载请注明出处,欢迎讨论和交流!

Be First to Comment

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注