图像分割实战-系列教程16:deeplabV3+ VOC分割实战4-------网络结构2

图像分割实战-系列教程 总目录

有任何问题欢迎在下面留言
本篇文章的代码运行界面均在Pycharm中进行
本篇文章配套的代码资源已经上传

deeplab系列算法概述
deeplabV3+ VOC分割实战1
deeplabV3+ VOC分割实战2
deeplabV3+ VOC分割实战3
deeplabV3+ VOC分割实战4
deeplabV3+ VOC分割实战5

本项目的网络结构在network文件夹中,主要在modeling.py和_deeplab.py中:
modeling.py:指定要用的骨干网络是什么
_deeplab.py:根据modeling.py指定的骨干网络构建实际的网络结构

7、_deeplab.py的 ASPP类

ASPP,Atrous Spatial Pyramid Pooling,空洞空间卷积池化金字塔

class ASPP(nn.Module):
    def __init__(self, in_channels, atrous_rates):
        super(ASPP, self).__init__()
        out_channels = 256
        modules = []
        modules.append(nn.Sequential(
            nn.Conv2d(in_channels, out_channels, 1, bias=False),
            nn.BatchNorm2d(out_channels),
            nn.ReLU(inplace=True)))
        rate1, rate2, rate3 = tuple(atrous_rates)
  1. 定义了一个名为 ASPP 的类,继承自 PyTorch 的 nn.Module 基类
  2. ASPP 类的构造函数,接收输入通道数 in_channels 和一组膨胀率 atrous_rates 作为参数
  3. 调用基类的构造函数来正确初始化 ASPP 类
  4. 定义 ASPP 模块的输出通道数
  5. 初始化一个空的模块列表,用于存放构成 ASPP 的不同组件
  6. 添加一个执行序列模块到 modules 列表
  7. 这个执行序列由 1x1 卷积
  8. 批量归一化
  9. ReLU激活组成
  10. 解包膨胀率
        modules.append(ASPPConv(in_channels, out_channels, rate1))
        modules.append(ASPPConv(in_channels, out_channels, rate2))
        modules.append(ASPPConv(in_channels, out_channels, rate3))
        modules.append(ASPPPooling(in_channels, out_channels))
        self.convs = nn.ModuleList(modules)
        self.project = nn.Sequential(
            nn.Conv2d(5 * out_channels, out_channels, 1, bias=False),
            nn.BatchNorm2d(out_channels),
            nn.ReLU(inplace=True),
            nn.Dropout(0.1), )
  1. 对膨胀率rate1添加一个ASPPConv空洞卷积层到 modules
  2. 对膨胀率rate2添加一个ASPPConv空洞卷积层到 modules
  3. 对膨胀率rate3添加一个ASPPConv空洞卷积层到 modules
  4. 添加一个 ASPPPooling 层到 modules
  5. 将 modules 列表转换为 nn.ModuleList,modules 是python的list数据类型,将其转换成对应的pytorch的数据类型
  6. 定义一个名为project 的执行序列,这个执行序列包含
  7. 一个1*1的二维卷积
  8. 一个批量归一化
  9. 一个ReLU 激活
  10. 一个 Dropout
    def forward(self, x):
        res = []
        for conv in self.convs:
            res.append(conv(x))
        res = torch.cat(res, dim=1)
        return self.project(res)
  1. ASPP 类的前向传播函数
  2. 初始化一个空列表,用于存放不同卷积层的输出
  3. 遍历 self.convs 中的每个卷积层
  4. 将每个卷积层对输入 x 的处理结果添加到 res 列表
  5. 将 res 列表中的所有输出在特征通道维度(dim=1)上进行拼接操作
  6. 将连接后的结果传递给投影层 self.project,并返回最终结果

8、_deeplab.py的 ASPPConv类

class ASPPConv(nn.Sequential):
    def __init__(self, in_channels, out_channels, dilation):
        modules = [
            nn.Conv2d(in_channels, out_channels, 3, padding=dilation, dilation=dilation, bias=False),
            nn.BatchNorm2d(out_channels),
            nn.ReLU(inplace=True)
        ]
        super(ASPPConv, self).__init__(*modules)

这里是一个单独的模块,只有定义,也就是说只有在构建网络时使用构造函数才会使用这个类,可以多次调用,每次都是一个二维卷积、批归一化、ReLU激活。
这里的卷积实际上就是deeplab非常核心的空洞卷积,仅仅只有两个参数与一般卷积不同,那就是指定了padding=dilationdilation=dilation

9、_deeplab.py的 ASPPPooling类

class ASPPPooling(nn.Sequential):
    def __init__(self, in_channels, out_channels):
        super(ASPPPooling, self).__init__(
            nn.AdaptiveAvgPool2d(1),
            nn.Conv2d(in_channels, out_channels, 1, bias=False),
            nn.BatchNorm2d(out_channels),
            nn.ReLU(inplace=True))
    def forward(self, x):
        size = x.shape[-2:]
        x = super(ASPPPooling, self).forward(x)
        return F.interpolate(x, size=size, mode='bilinear', align_corners=False)
  1. 定义了一个名为 ASPPPooling 的类,继承自 PyTorch 的 nn.Sequential
  2. ASPPPooling 类的构造函数,接收 in_channelsout_channels 参数
  3. 调用基类的构造函数来初始化序列模块,包含4个模块:
  4. 一个自适应平均池化层,将输入的每个通道池化为 1x1 的输出,实现全局平均池化
  5. 一个 1x1 卷积层,用于调整通道数
  6. 一个批量归一化
  7. 一个ReLU激活函数
  8. 定义前向传播函数
  9. 存储输入 x 的高度和宽度
  10. 基类的 forward 方法执行序列中的池化、卷积、归一化和激活操作
  11. 将处理后的特征图 x 上采样回原始的空间维度,这里使用双线性插值进行上采样。

总体来说,ASPPPooling 类实现了一个全局平均池化操作,随后通过 1x1 卷积调整通道数,并进行上采样以匹配原始输入的空间尺寸。这种处理方式有助于在 DeepLabV3+ 模型中捕获全局上下文信息,对于提升分割精度非常重要。

deeplab系列算法概述
deeplabV3+ VOC分割实战1
deeplabV3+ VOC分割实战2
deeplabV3+ VOC分割实战3
deeplabV3+ VOC分割实战4
deeplabV3+ VOC分割实战5

你可能感兴趣的:(图像分割实战,深度学习,计算机视觉,pytorch,图像分割,deeplab)