You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将3D卷积编码器层改为反卷积层以匹配编码器空间尺寸变化率?

问题描述

我有一个由编码器和解码器组成的3D卷积网络,想在解码器部分把编码器用的卷积层改成反卷积层,让反卷积层按编码器的逆速率增大特征图空间尺寸,同时减少通道数。

编码器里的卷积层序列如下:

Conv_layer = nn.Sequential(
            BasicConv3d(64, 64, kernel_size=1, stride=1),
            SepConv3d(64, 192, kernel_size=3, stride=1, padding=1),
            nn.MaxPool3d(kernel_size=(1,3,3), stride=(1,2,2), padding=(0,1,1)),
        )

用到的卷积层定义:

class BasicConv3d(nn.Module):
    def __init__(self, in_planes, out_planes, kernel_size, stride, padding=0):
        super(BasicConv3d, self).__init__()
        self.conv = nn.Conv3d(in_planes, out_planes, kernel_size=kernel_size, stride=stride, padding=padding, bias=False)
        self.bn = nn.BatchNorm3d(out_planes, eps=1e-3, momentum=0.001, affine=True)
        self.relu = nn.ReLU()

    def forward(self, x):
        x = self.conv(x)
        x = self.bn(x)
        x = self.relu(x)
        return x
    
class SepConv3d(nn.Module):
    def __init__(self, in_planes, out_planes, kernel_size, stride, padding=0):
        super(SepConv3d, self).__init__()
        self.conv_s = nn.Conv3d(in_planes, out_planes, kernel_size=(1,kernel_size,kernel_size), stride=(1,stride,stride), padding=(0,padding,padding), bias=False)
        self.bn_s = nn.BatchNorm3d(out_planes, eps=1e-3, momentum=0.001, affine=True)
        self.relu_s = nn.ReLU()

        self.conv_t = nn.Conv3d(out_planes, out_planes, kernel_size=(kernel_size,1,1), stride=(stride,1,1), padding=(padding,0,0), bias=False)
        self.bn_t = nn.BatchNorm3d(out_planes, eps=1e-3, momentum=0.001, affine=True)
        self.relu_t = nn.ReLU()

    def forward(self, x):
        x = self.conv_s(x)
        x = self.bn_s(x)
        x = self.relu_s(x)

        x = self.conv_t(x)
        x = self.bn_t(x)
        x = self.relu_t(x)
        return x

请问怎么修改上述层的kernel_size、stride和padding参数,改成反卷积层,实现和编码器逆速率一致的特征图空间尺寸增大?

解决方案

要实现编码器的逆过程,核心是让反卷积的输出尺寸匹配编码器的输入尺寸,同时通道数反向调整(编码器升通道,解码器降通道)。以下是具体修改方案:

1. 替换卷积层为反卷积层

把原代码中的nn.Conv3d替换为nn.ConvTranspose3d,同时根据逆过程调整参数。反卷积的stride对应编码器下采样的步长,kernel_size和padding配合保证尺寸精准匹配。

(1)重构BasicConv3d为BasicDeconv3d

编码器中该层仅调整通道(无尺寸变化),解码器中需反转通道方向,参数保持不变即可:

class BasicDeconv3d(nn.Module):
    def __init__(self, in_planes, out_planes, kernel_size, stride, padding=0, output_padding=0):
        super(BasicDeconv3d, self).__init__()
        self.deconv = nn.ConvTranspose3d(in_planes, out_planes, kernel_size=kernel_size, stride=stride, 
                                         padding=padding, output_padding=output_padding, bias=False)
        self.bn = nn.BatchNorm3d(out_planes, eps=1e-3, momentum=0.001, affine=True)
        self.relu = nn.ReLU()

    def forward(self, x):
        x = self.deconv(x)
        x = self.bn(x)
        x = self.relu(x)
        return x

解码器中调用:BasicDeconv3d(64, 64, kernel_size=1, stride=1)

(2)重构SepConv3d为SepDeconv3d

编码器中该层仅升通道(无尺寸变化),解码器中反转通道方向,参数保持stride=1、padding=1:

class SepDeconv3d(nn.Module):
    def __init__(self, in_planes, out_planes, kernel_size, stride, padding=0, output_padding=0):
        super(SepDeconv3d, self).__init__()
        # 空间维度反卷积:对应编码器的conv_s
        self.deconv_s = nn.ConvTranspose3d(in_planes, out_planes, kernel_size=(1,kernel_size,kernel_size), 
                                           stride=(1,stride,stride), padding=(0,padding,padding), 
                                           output_padding=(0,output_padding,output_padding), bias=False)
        self.bn_s = nn.BatchNorm3d(out_planes, eps=1e-3, momentum=0.001, affine=True)
        self.relu_s = nn.ReLU()

        # 时间维度反卷积:对应编码器的conv_t
        self.deconv_t = nn.ConvTranspose3d(out_planes, out_planes, kernel_size=(kernel_size,1,1), 
                                           stride=(stride,1,1), padding=(padding,0,0), 
                                           output_padding=(output_padding,0,0), bias=False)
        self.bn_t = nn.BatchNorm3d(out_planes, eps=1e-3, momentum=0.001, affine=True)
        self.relu_t = nn.ReLU()

    def forward(self, x):
        x = self.deconv_s(x)
        x = self.bn_s(x)
        x = self.relu_s(x)

        x = self.deconv_t(x)
        x = self.bn_t(x)
        x = self.relu_t(x)
        return x

解码器中调用:SepDeconv3d(64, 64, kernel_size=3, stride=1, padding=1)

(3)替换MaxPool3d为反卷积(实现上采样)

编码器的MaxPool3d是下采样操作(时间维度尺寸不变,空间维度缩小为1/2),解码器需用反卷积实现逆过程:

  • kernel_size、stride、padding直接复用原池化层参数
  • 通道数从192降至64
  • output_padding设为(0,0,0)(因输入是偶数倍下采样,无需额外补边)

2. 解码器完整序列

按编码器的逆顺序组合层(编码器:Conv→SepConv→MaxPool,解码器:MaxPool逆→SepDeconv→BasicDeconv):

Deconv_layer = nn.Sequential(
            # 对应MaxPool3d的逆上采样:通道192→64,空间维度放大2倍
            nn.ConvTranspose3d(192, 64, kernel_size=(1,3,3), stride=(1,2,2), padding=(0,1,1), output_padding=(0,0,0), bias=False),
            nn.BatchNorm3d(64),
            nn.ReLU(),
            # 对应SepConv3d的逆:通道64→64,尺寸不变
            SepDeconv3d(64, 64, kernel_size=3, stride=1, padding=1),
            # 对应BasicConv3d的逆:通道64→64,尺寸不变
            BasicDeconv3d(64, 64, kernel_size=1, stride=1),
        )

关键参数匹配原则

  • stride:必须等于对应编码器下采样层的步长,保证尺寸放大倍数与下采样倍数一致
  • kernel_size&padding:参考原卷积/池化层参数,使反卷积输出尺寸满足公式:output_size = (input_size - 1)*stride - 2*padding + kernel_size
  • 通道数:编码器是输入通道→输出通道,解码器需改为输出通道→输入通道

内容的提问来源于stack exchange,提问作者dtr43

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 21:10:52