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

PyTorch卷积自编码器输出维度与输入不符问题排查

问题根源

输出形状不匹配的核心原因是:解码器未对应编码器的2倍下采样操作,实现等比例上采样。

编码器通过两次MaxPool2d(kernel_size=2)完成两次下采样:

  • 输入255×255 → 第一次MaxPool后变为127×127(奇数尺寸由255//2=127导致)
  • 127×127 → 第二次MaxPool后变为63×63(同理127//2=63)

而你当前的ConvTranspose2d使用默认stride=1,仅做普通转置卷积,没有上采样能力,自然无法恢复原尺寸。另外,output_padding必须配合stride>1使用——它的作用是在stride>1时微调输出的末尾补边,单独使用无法实现上采样。

修正后的模型

下面是调整后的代码,解码器用stride=2的ConvTranspose2d实现2倍上采样,同时用output_padding=1补全奇数尺寸的最后1个像素:

import torch.nn as nn

class AutoEncoder(nn.Module):
    def __init__(self) -> None:
        super().__init__()
        
        self.encoder = nn.Sequential(
            nn.Conv2d(in_channels=3, out_channels=32, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2),  # 255 → 127
            nn.Conv2d(in_channels=32, out_channels=128, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2)   # 127 → 63
        )

        self.decoder = nn.Sequential(
            nn.Conv2d(in_channels=128, out_channels=128, kernel_size=3, padding=1),
            nn.ReLU(),
            # 第一次上采样:63 → 127,stride=2实现2倍放大,output_padding补1像素
            nn.ConvTranspose2d(in_channels=128, out_channels=32, kernel_size=3, stride=2, padding=1, output_padding=1),
            nn.ReLU(),
            # 第二次上采样:127 → 255,同逻辑恢复原尺寸
            nn.ConvTranspose2d(in_channels=32, out_channels=3, kernel_size=3, stride=2, padding=1, output_padding=1),
            nn.Sigmoid()
        )

    def forward(self, x):
        x = self.encoder(x)
        x = self.decoder(x)
        return x
尺寸验证

用torchsummary验证输出:

  • 编码器输出:[-1, 128, 63, 63]
  • 第一次转置卷积后:[-1, 32, 127, 127](计算公式:(输入尺寸-1)*stride - 2*padding + kernel_size + output_padding → (63-1)2 -21 +3 +1=127)
  • 第二次转置卷积后:[-1, 3, 255, 255](同理计算得255)

此时输出与输入形状完全一致。

替代方案:插值上采样

如果你更习惯TensorFlow的Upscale逻辑,PyTorch也支持插值上采样+普通卷积的组合,这种方式无需计算复杂的转置卷积参数,对奇数尺寸兼容性更好:

self.decoder = nn.Sequential(
    nn.Conv2d(128, 128, 3, padding=1),
    nn.ReLU(),
    nn.Upsample(scale_factor=2, mode='bilinear', align_corners=False),  # 63 → 126
    nn.Conv2d(128, 32, 3, padding=1),
    nn.ReLU(),
    nn.Upsample(scale_factor=2, mode='bilinear', align_corners=False),  # 126 → 252
    nn.Conv2d(32, 3, 3, padding=2),  # padding=2让252 → 255
    nn.Sigmoid()
)

插值上采样是固定规则,而转置卷积可以学习上采样权重,你可以根据需求选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 03:40:54