zoukankan      html  css  js  c++  java
  • 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):@绝版臭咸鱼

    微信公众号:@臭咸鱼

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


  • 相关阅读:
    R语言:提取路径中的文件名字符串(basename函数)
    课程一(Neural Networks and Deep Learning),第三周(Shallow neural networks)—— 0、学习目标
    numpy.squeeze()的用法
    课程一(Neural Networks and Deep Learning),第二周(Basics of Neural Network programming)—— 4、Logistic Regression with a Neural Network mindset
    Python numpy 中 keepdims 的含义
    课程一(Neural Networks and Deep Learning),第二周(Basics of Neural Network programming)—— 3、Python Basics with numpy (optional)
    课程一(Neural Networks and Deep Learning),第二周(Basics of Neural Network programming)—— 2、编程作业常见问题与答案(Programming Assignment FAQ)
    课程一(Neural Networks and Deep Learning),第二周(Basics of Neural Network programming)—— 0、学习目标
    课程一(Neural Networks and Deep Learning),第一周(Introduction to Deep Learning)—— 0、学习目标
    windows系统numpy的下载与安装教程
  • 原文地址:https://www.cnblogs.com/chouxianyu/p/14584463.html
Copyright © 2011-2022 走看看