我刚开始使用PyTorch,想制作一个简单的自编码器来处理255×255的RGB图像,但输出形状与输入形状不同。
这是模型
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), nn.Conv2d(in_channels=32, out_channels=128, kernel_size=3, padding=1), nn.ReLU(), nn.MaxPool2d(kernel_size=2) ) self.decoder = nn.Sequential( nn.Conv2d(in_channels=128, out_channels=128, kernel_size=3, padding=1), nn.ReLU(), nn.ConvTranspose2d(in_channels=128, out_channels=32, kernel_size=3, output_padding=1), nn.ReLU(), nn.ConvTranspose2d(in_channels=32, out_channels=3, kernel_size=3, output_padding=1), nn.Sigmoid() ) def forward(self, x): x = self.encoder(x) x = self.decoder(x) return x
这是由torchsummary包给出的形状
---------------------------------------------------------------- Layer (type) Output Shape Param #================================================================ Conv2d-1 [-1, 32, 255, 255] 896 ReLU-2 [-1, 32, 255, 255] 0 MaxPool2d-3 [-1, 32, 127, 127] 0 Conv2d-4 [-1, 128, 127, 127] 36,992 ReLU-5 [-1, 128, 127, 127] 0 MaxPool2d-6 [-1, 128, 63, 63] 0 Conv2d-7 [-1, 128, 63, 63] 147,584 ReLU-8 [-1, 128, 63, 63] 0 ConvTranspose2d-9 [-1, 32, 66, 66] 36,896 ReLU-10 [-1, 32, 66, 66] 0 ConvTranspose2d-11 [-1, 3, 69, 69] 867 Sigmoid-12 [-1, 3, 69, 69] 0
我从另一个帖子中看到,解码器部分的output_padding
选项可以帮助调整输出形状,但对我来说没有效果。
我不知道问题出在哪里,来自Tensorflow的我会使用一个上采样层,但据我所知,这不是PyTorch的做法。
能有人解释一下为什么我的当前模型的形状会出问题吗?谢谢
回答:
控制输入上采样的主要参数是stride=
。设置stride=2
和kernel_size=2
将精确地将输入大小翻倍。
在你的情况下,使用stride=2
和kernel_size=3
来实现每个上卷积层的翻倍 + 1
大小变换。第一层将产生大小为2 x 63 + 1 = 127
的输出,第二层将产生2 x 127 + 1 = 255
的输出。
示例:
x = torch.rand(1, 128, 63, 63) #Conv2d-7的输出形状为(63, 63)x = nn.ConvTranspose2d(128, 32, kernel_size=3, stride=2)(x) #2h + 1上卷积print(x.shape)#out> torch.Size([1, 32, 127, 127])x = nn.ConvTranspose2d(32, 3, kernel_size=3, stride=2)(x) #2h + 1上卷积print(x.shape)#out> torch.Size([1, 3, 255, 255])