【语义分割|代码解析】空洞卷积!DSNet-2: A Novel Way to Use Atrous Convolutions in Semantic Segmentation

【语义分割|代码解析2】空洞卷积!DSNet-2: A Novel Way to Use Atrous Convolutions in Semantic Segmentation

【语义分割|代码解析】空洞卷积!DSNet-2: A Novel Way to Use Atrous Convolutions in Semantic Segmentation



欢迎宝子们点赞、关注、收藏!欢迎宝子们批评指正!
祝所有的硕博生都能遇到好的导师!好的审稿人!好的同门!顺利毕业!

大多数高校硕博生毕业要求需要参加学术会议,发表EI或者SCI检索的学术论文会议论文:
可访问艾思科蓝官网,浏览即将召开的学术会议列表。会议入口:https://ais.cn/u/mmmiUz

论文地址:https://arxiv.org/pdf/2406.03702v1

前言

在这里插入图片描述

DSNet模型是一种基于膨胀卷积(Atrous Convolution)的语义分割网络,应用在遥感图像分析中能够提高对复杂场景的细节捕捉能力。DSNet模型的整体结构包括多尺度特征提取、特征融合以及分割头输出,以下是对代码的逐层解析,帮助理解每一个模块的功能和设计思想。

1. 代码全局设置

BatchNorm2d = nn.BatchNorm2d
bn_mom = 0.1
algc = True
  • BatchNorm2d:批量归一化操作,用于在训练时保持网络的稳定性。
  • bn_mom = 0.1:批量归一化的动量参数。
  • algc:通常用于控制算法设置,具体在代码中未直接应用。

2. DUC (Dense Upsampling Convolution) 模块

class DUC(nn.Module):
    def __init__(self, inplanes, planes, upscale_factor=2):
        super(DUC, self).__init__()
        self.relu = nn.ReLU()  # 激活函数
        self.conv = nn.Conv2d(inplanes, planes * upscale_factor ** 2, kernel_size=3, padding=1)  # 卷积层
        self.bn = nn.BatchNorm2d(planes * upscale_factor ** 2)  # 批量归一化
        self.pixel_shuffle = nn.PixelShuffle(upscale_factor)  # 像素洗牌操作用于上采样
        self.conv2 = nn.Conv2d(planes, planes, kernel_size=1, padding=0, bias=False)
  • self.relu:使用 ReLU 作为激活函数,增强非线性能力。
  • self.conv:卷积层,将输入通道数扩展为 planes * upscale_factor ** 2,以便在 PixelShuffle 后恢复目标分辨率。
  • self.bn:批量归一化层,应用于卷积输出,帮助加快收敛。
  • self.pixel_shuffle:通过 PixelShuffle 将通道信息转换为更高的分辨率,实现上采样。
  • self.conv21x1卷积层,用于进一步压缩通道数量。

forward 函数

def forward(self, x):
    x = self.relu(x)
    x = self.conv(x)
    x = self.bn(x)
    x = self.relu(x)
    x = self.pixel_shuffle(x)  # 通过PixelShuffle进行上采样
    x = self.conv2(x)
    return x
  • x = self.conv(x):卷积操作扩展特征通道。
  • x = self.bn(x):对卷积后的特征图进行批量归一化。
  • x = self.pixel_shuffle(x):进行上采样操作。
  • x = self.conv2(x):使用 1x1 卷积将输出通道进一步缩减。

3. ConvX 模块

class ConvX(nn.Module):
    def __init__(self, in_planes, out_planes, kernel=3, stride=1, dilation=1):
        super(ConvX, self).__init__()
        if dilation==1:
            self.conv = nn.Conv2d(in_planes, out_planes, kernel_size=kernel, stride=stride, bias=False)
        else:
            self.conv = nn.Conv2d(in_planes, out_planes, kernel_size=kernel, stride=stride, dilation=dilation, padding=dilation, bias=False)
        self.bn = BatchNorm2d(out_planes, momentum=bn_mom)
        self.relu = nn.ReLU(inplace=True)
  • 根据 dilation 值,决定是否使用膨胀卷积 (dilation > 1)。
  • self.bn:批量归一化层,帮助稳定训练。
  • self.relu:使用 ReLU 激活。

forward 函数

def forward(self, x):
    out = self.relu(self.bn(self.conv(x)))
    return out
  • 逐步进行卷积、批量归一化、激活操作。

4. Conv1X1 模块

class Conv1X1(nn.Module):
    def __init__(self, in_planes, out_planes, kernel=1, stride=1, dilation=1):
        super(Conv1X1, self).__init__()
        self.conv = nn.Conv2d(in_planes, out_planes, kernel_size=kernel, stride=stride, bias=False)
        self.bn = BatchNorm2d(out_planes, momentum=bn_mom)
        self.relu = nn.ReLU(inplace=True)
  • Conv1X11x1 卷积,用于调整通道数。
  • self.bnself.relu:批量归一化和激活函数,与 ConvX 相同。

5. MFACB 模块

在这里插入图片描述

MFACB 使用多种膨胀卷积快速聚拢感受野。

class MFACB(nn.Module):
    def __init__(self, in_planes, inter_planes, out_planes, block_num=3, stride=1, dilation=[2,2,2]):
        super(MFACB, self).__init__()
        self.conv_list = nn.ModuleList()
        self.conv_list.append(ConvX(in_planes, inter_planes, stride=stride, dilation=dilation[0]))
        self.conv_list.append(ConvX(inter_planes, inter_planes, stride=stride, dilation=dilation[1]))
        self.conv_list.append(ConvX(inter_planes, inter_planes, stride=stride, dilation=dilation[2]))
  • self.conv_list:一个包含多层膨胀卷积的 ModuleList
  • 每层 ConvX 使用不同的膨胀率 (dilation),实现多尺度特征提取。

forward 函数

def forward(self, x):
    out_list = []
    out = x
    out1 = self.process1(x)
    for idx in range(3):
        out = self.conv_list[idx](out)
        out_list.append(out)
    out = torch.cat(out_list, dim=1)
    return self.process2(out) + out1
  • for idx in range(3):通过不同膨胀率的卷积层逐步提取多尺度特征。
  • torch.cat(out_list, dim=1):将所有特征拼接。
  • self.process2(out) + out1:经过 process2 进一步处理并加上 out1 路径的特征,实现特征聚合。

6. SPASPP 模块

在这里插入图片描述

SPASPP 实现了具有空间池化的ASPP,用于捕获不同尺度的特征。

class SPASPP(nn.Module):
    def __init__(self, in_planes, inter_planes, out_planes, block_num=3, stride=1, dilation=[6,12,18,24]):
        super(SPASPP, self).__init__()
        self.conv_list = nn.ModuleList()
        self.conv_list.append(ConvX(in_planes, inter_planes, stride=stride, dilation=dilation[0]))
        self.conv_list.append(ConvX(inter_planes, inter_planes, stride=stride, dilation=dilation[1]))
        self.conv_list.append(ConvX(inter_planes, inter_planes, stride=stride, dilation=dilation[2]))
        self.conv_list.append(ConvX(inter_planes, inter_planes, stride=stride, dilation=dilation[3]))
        self.pooling = ASPPPooling(in_planes, inter_planes)
  • self.conv_list:包含四个不同膨胀率的卷积层。
  • self.pooling:空间池化层,用于进一步丰富特征的上下文信息。

forward 函数

def forward(self, x):
    out_list = []
    out = x
    out1 = self.process1(x)
    out2 = self.pooling(x)
    for idx in range(4):
        out = self.conv_list[idx](out)
        out_list.append(out)
    out = torch.cat(out_list, dim=1)
    out = torch.cat((out, out2), dim=1)
    return self.process3(self.process2(out) + out1)
  • out2 = self.pooling(x):使用空间池化进一步补充上下文信息。
  • out = torch.cat((out, out2), dim=1):将不同膨胀率卷积特征与池化特征拼接。
  • 最后通过 process2process3 完成融合,输出最终结果。

欢迎宝子们点赞、关注、收藏!欢迎宝子们批评指正!
祝所有的硕博生都能遇到好的导师!好的审稿人!好的同门!顺利毕业!

大多数高校硕博生毕业要求需要参加学术会议,发表EI或者SCI检索的学术论文会议论文:
可访问艾思科蓝官网,浏览即将召开的学术会议列表。会议入口:https://ais.cn/u/mmmiUz

猜你喜欢

转载自blog.csdn.net/gaoxiaoxiao1209/article/details/143312550