(即插即用模块-特征处理部分) 一、(ECCV 2018) ASPP 空间金字塔池化

在这里插入图片描述

paper:Encoder-Decoder with Atrous Separable Convolution for Semantic Image Segmentation

Code:https://github.com/tensorflow/models/tree/master/research/deeplab


1、Atrous Spatial Pyramid Pooling

这篇 DeepLabV3+ 也是语义分割方向相当经典的一篇论文了,里面的 空间金字塔池化 Atrous Spatial Pyramid Pooling(ASPP)更是相当出名的一个模块,在之后也有很多的魔改版本。虽说是18年的一篇论文,但还是在这里整理一下,在之后会慢慢更新近两年的内容。

ASPP 的主要原理是基于以下几点:多尺度信息的重要性: 不同的物体尺度需要不同大小的感受野来捕捉特征。池化操作的局限性: 传统的池化操作(如最大池化)会丢失图像的空间信息,导致无法有效地捕捉多尺度特征。而 ASPP 则通过并行地使用不同膨胀率的空洞卷积,可以在不改变特征图分辨率的情况下,有效地获取不同尺度的上下文信息。

ASPP 的实现方式主要有以下几步:

  1. 空洞卷积: 空洞卷积是一种特殊的卷积操作,通过在卷积核之间引入空洞,可以扩大感受野,而不增加参数数量和计算复杂度。
  2. 多尺度膨胀率: ASPP模块并行地使用不同膨胀率的空洞卷积,例如,在本篇论文中使用了 1x1、3x3(rate=6)、3x3(rate=12)、3x3(rate=18)四种膨胀率。
  3. 池化操作: ASPP模块还包括一个全局平均池化操作,将特征图的空间维度压缩为 1x1,从而获取全局信息。
  4. 特征融合: 最后,将不同膨胀率的空洞卷积输出和全局平均池化输出进行融合,得到最终的特征图。

ASPP 结构图:
在这里插入图片描述


2、代码实现

import torch
import torch.nn as nn
import torch.nn.functional as F


class ASPP(nn.Module):
    def __init__(self, dim_in, dim_out, rate=1, bn_mom=0.1):
        super(ASPP, self).__init__()
        self.branch1 = nn.Sequential(
            nn.Conv2d(dim_in, dim_out, 1, 1, padding=0, dilation=rate, bias=True),
            nn.BatchNorm2d(dim_out, momentum=bn_mom),
            nn.ReLU(inplace=True),
        )
        self.branch2 = nn.Sequential(
            nn.Conv2d(dim_in, dim_out, 3, 1, padding=6 * rate, dilation=6 * rate, bias=True),
            nn.BatchNorm2d(dim_out, momentum=bn_mom),
            nn.ReLU(inplace=True),
        )
        self.branch3 = nn.Sequential(
            nn.Conv2d(dim_in, dim_out, 3, 1, padding=12 * rate, dilation=12 * rate, bias=True),
            nn.BatchNorm2d(dim_out, momentum=bn_mom),
            nn.ReLU(inplace=True),
        )
        self.branch4 = nn.Sequential(
            nn.Conv2d(dim_in, dim_out, 3, 1, padding=18 * rate, dilation=18 * rate, bias=True),
            nn.BatchNorm2d(dim_out, momentum=bn_mom),
            nn.ReLU(inplace=True),
        )
        self.branch5_conv = nn.Conv2d(dim_in, dim_out, 1, 1, 0, bias=True)
        self.branch5_bn = nn.BatchNorm2d(dim_out, momentum=bn_mom)
        self.branch5_relu = nn.ReLU(inplace=True)

        self.conv_cat = nn.Sequential(
            nn.Conv2d(dim_out * 5, dim_out, 1, 1, padding=0, bias=True),
            nn.BatchNorm2d(dim_out, momentum=bn_mom),
            nn.ReLU(inplace=True),
        )

    def forward(self, x):
        [b, c, row, col] = x.size()
        conv1x1 = self.branch1(x)
        conv3x3_1 = self.branch2(x)
        conv3x3_2 = self.branch3(x)
        conv3x3_3 = self.branch4(x)

        global_feature = torch.mean(x, 2, True)
        global_feature = torch.mean(global_feature, 3, True)
        global_feature = self.branch5_conv(global_feature)
        global_feature = self.branch5_bn(global_feature)
        global_feature = self.branch5_relu(global_feature)
        global_feature = F.interpolate(global_feature, (row, col), None, 'bilinear', True)

        feature_cat = torch.cat([conv1x1, conv3x3_1, conv3x3_2, conv3x3_3, global_feature], dim=1)
        result = self.conv_cat(feature_cat)
        return result


if __name__ == '__main__':
    x = torch.randn(4, 512, 7, 7).cuda()
    model = ASPP(512, 512).cuda()
    out = model(x)
    print(out.shape)
### ASPP Pyramid Pooling Module 架构 ASPP (Atrous Spatial Pyramid Pooling)种用于语义分割模型中的重要组件,其灵感来源于 SPPNet 的特征金字塔概念[^1]。SPPNet 借鉴了传统计算机视觉领域中多尺度特征提取的思想,通过构建不同尺度下的特征词袋来适应不同的输入尺寸并摆脱固定大小的全连接层限制。 在 DeepLab 系列网络架构中,ASPP 模块步发展和完善了这理念。具体来说: - **多尺度上下文聚合**:ASPP 使用多个不同膨胀率(atrous rate)的空洞卷积核,在同位置上捕捉多种感受野范围内的信息。 - **全局平均池化分支**:除了标准的空洞卷积外,还加入了个全局平均池化的分支,该分支能够获取图像级别的上下文信息,并将其映射回原始分辨率的空间维度。 以下是简化版的 ASPP 结构示意代码表示: ```python import torch.nn as nn class ASPP(nn.Module): def __init__(self, in_channels, out_channels, rates=[6, 12, 18]): super(ASPP, self).__init__() # 定义各部分模块 self.branches = nn.ModuleList([ nn.Conv2d(in_channels, out_channels, kernel_size=1), *[nn.Sequential( nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=r, dilation=r)) for r in rates], nn.AdaptiveAvgPool2d((1, 1)), nn.Conv2d(in_channels, out_channels, kernel_size=1) ]) def forward(self, x): h, w = x.shape[-2:] feats = [] for branch in self.branches[:-1]: feat = branch(x) feats.append(feat) global_feat = self.branches[-1](x).expand(-1,-1,h,w) feats.append(global_feat) return torch.cat(feats, dim=1) ``` 此段代码展示了如何实现个基本版本的 ASPP 层,其中包含了几个具有不同扩张比例的标准卷积操作以及个全局均值池化路径。实际应用中可能会有所变化以适配特定任务需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

御宇w

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

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

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

打赏作者

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

抵扣说明:

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

余额充值