PSPNet: Pyramid Scene Parsing Network

paper:Pyramid Scene Parsing Network

code: GitHub - hszhao/semseg: Semantic Segmentation in Pytorch

mmsegmentation/psp_head.py at v0.17.0 · open-mmlab/mmsegmentation · GitHub

Important Observations

作者首先观察分析了将FCN方法应用于场景解析(Scene Parsing)时的几种代表性失败的情况,具体有以下三类:

Mismatched Relationship

语境关系普遍存在并且非常重要,尤其是对于复杂的场景理解问题。现实中往往存在的一些共存的视觉模式,比如,飞机通常是在跑道或空中飞行,而不是在马路上。如下图中的第一行,FCN根据外观将黄色框里的船预测为车,但众所周知汽车很少会在河上,缺少收集上下文信息的能力会增加错误分类的概率。

Confusion Categories

在分类中有很多类别标签容易混淆,比如filed和earth;mountain和hill;wall, house, building和skyscraper。他们的外观比较相似。如上图中第二行,FCN将黄色框中的物体一部分预测为摩天大楼,一部分预测为建筑物,这种结果显然是有问题的,目标物体应该要么被预测为skyscraper要么被预测为building,而不是两者都有。这个问题可以利用类别之间的关系来缓解。

Inconspicuous Classes

场景图片中会包含任意大小的对象,一些小尺寸的对象比如路灯和告示牌,很难找到但可能非常重要。相反,一些大的物体可能会超过FCN的感受野从而导致不连续的预测。如上图中的第三行所示,枕头的外观和床单相似,忽略全局场景类别可能会导致无法识别枕头。为了提高非常小和非常大物体的识别能力,应该注意那些包含不明显类别的不同的子区域。

综上所述,许多错误都或多或少的与不同感受野的上下文关系以及全局信息有关,因此,一个具有合适的全局上下文先验的网络可以大大提高场景解析的精度。

Pyramid Pooling Module

基于上述分析,作者提出了金字塔池化模块(pyramid pooling module),经验证明它可以作为一个有效的全局上下文先验。

全局平均池化是一种很好的全局上下文先验,常用于分类任务中。但对于复杂的场景图像,这种策略并不足以覆盖必要的信息,这些图像中的像素被标注为许多种类的对象,直接将它们融合成一个单一的向量可能会失去空间关系并造成歧义。而将全局上下文信息与各个子区域的上下文信息进行结合对区分各个类别非常有帮助,将不同子区域的信息进行融合可以得到一个更强大的特征表示。

在空间金字塔池化(spatial pyramid pooling, SPP)中,介绍见SPP: Spatial Pyramid Pooling_00000cj的博客-CSDN博客 ,金字塔池化生成的不同层级的特征图最终被展平、拼接然后送入全连接层进行分类,这种全局先验旨在消除CNN图像分类对固定输入大小的约束。为了进一步减少不同子区域之间的上下文信息的损失,本文提出了一种层级的全局先验,它包含了不同子区域中不同尺度的信息,即金字塔池化模块(Pyramid Pooling Module, PPM),它作用于网络的最后一个feature map上,如下图所示

PPM在多个不同尺度下融合特征,其中红色显示的是最粗糙全局池化,得到一个向量。下面的金字塔层将特征图划分为不同的子区域,然后对每个子区域进行池化从而得到各个子区域的集合特征表示。文中金字塔池化模块采用采用四个level,分别为1x1,2x2,3x3,6x6。作者通过消融实验发现average pooling比max pooling的效果好,因此最终采用平均池化。在每一层级的池化后接一个1x1卷积用于降维,假设层级为N,则降维比例为1/N,文中采用4个等级,输入通道为2048,因此每个层级1x1卷积的输出通道数为2048/4=512。每个层级的输出通过双线性插值上采样到输入大小,并与输入进行concatenate,最终的输出通道为2048+512*4=4096。

Deep Supervision for ResNet-Based FCN

文中作者还提出了一个auxiliary loss,对网络的中间结果进行监督,以ResNet101为例,该loss加在第4个stage后,即res4b22 residue block,如下图所示

 

引入的辅助损失有助于优化学习过程同时又不影响主分支的学习,文中通过实验发现添加辅助损失可以提高最终的精度,当辅助损失的权重\(\alpha=0.4\)时,精度最高。 

Experiments

在2016年的ImageNet的场景解析比赛中,PSPNet获得了第一,如下所示

在PASCAL VOC 2012数据集的语义分割任务中,当只用VOC 2012的数据进行训练时,PSPNet在所有20个类别上都达到了最高的精度。当用MS-COCO数据集进行预训练时,在19个类别上达到了最高的精度,如下表所示

 

代码

import torch.nn as nn
from mmcv.cnn import ConvModule
from mmseg.ops import resize


class PPM(nn.ModuleList):
    """Pooling Pyramid Module used in PSPNet.

    Args:
        pool_scales (tuple[int]): Pooling scales used in Pooling Pyramid
            Module.
        in_channels (int): Input channels.
        channels (int): Channels after modules, before conv_seg.
        conv_cfg (dict|None): Config of conv layers.
        norm_cfg (dict|None): Config of norm layers.
        act_cfg (dict): Config of activation layers.
        align_corners (bool): align_corners argument of F.interpolate.
    """

    def __init__(self, pool_scales, in_channels, channels, conv_cfg, norm_cfg,
                 act_cfg, align_corners, **kwargs):
        super(PPM, self).__init__()
        self.pool_scales = pool_scales  # (1, 2, 3, 6)
        self.align_corners = align_corners
        self.in_channels = in_channels  # 2048
        self.channels = channels  # 512
        self.conv_cfg = conv_cfg
        self.norm_cfg = norm_cfg
        self.act_cfg = act_cfg
        for pool_scale in pool_scales:
            self.append(
                nn.Sequential(
                    nn.AdaptiveAvgPool2d(pool_scale),
                    ConvModule(
                        self.in_channels,
                        self.channels,
                        1,
                        conv_cfg=self.conv_cfg,
                        norm_cfg=self.norm_cfg,
                        act_cfg=self.act_cfg,
                        **kwargs)))

    def forward(self, x):
        """Forward function."""
        ppm_outs = []
        for ppm in self:
            ppm_out = ppm(x)
            upsampled_ppm_out = resize(
                ppm_out,
                size=x.size()[2:],
                mode='bilinear',
                align_corners=self.align_corners)
            ppm_outs.append(upsampled_ppm_out)
        return ppm_outs

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

00000cj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值