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

    微信公众号:@臭咸鱼

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


  • 相关阅读:
    20145204实验反思与总结
    20145204《信息安全系统设计基础》课程总结
    家庭作业:12.18,9.13,8.25,2.62
    20145204张亚军第14周博客总结
    20145204 张亚军《信息安全系统设计基础》第13周学习总结
    SLB技术原理浅析
    jumpserver在终端修改管理员密码及新建超级用户
    批量杀掉多个pid文件中记录的pid进程, 并集成到shell脚本中
    修改daemon.json重新加载后docker无法启动问题
    Docker的配置文件 daemon.json 详解
  • 原文地址:https://www.cnblogs.com/chouxianyu/p/14584463.html
Copyright © 2020-2023  润新知