【问题标题】:Upsampling an autoencoder in pytorch在 pytorch 中对自动编码器进行上采样
【发布时间】:2020-01-23 22:30:13
【问题描述】:

我在 pytorch 中定义了我的自动编码器,如下所示(它在编码器的输出处给了我一个 8 维瓶颈,它工作正常 torch.Size([1, 8, 1, 1])):

self.encoder = nn.Sequential(
    nn.Conv2d(input_shape[0], 32, kernel_size=8, stride=4),
    nn.ReLU(),
    nn.Conv2d(32, 64, kernel_size=4, stride=2),
    nn.ReLU(),
    nn.Conv2d(64, 8, kernel_size=3, stride=1),
    nn.ReLU(),
    nn.MaxPool2d(7, stride=1)
)

self.decoder = nn.Sequential(
    nn.ConvTranspose2d(8, 64, kernel_size=3, stride=1),
    nn.ReLU(),
    nn.Conv2d(64, 32, kernel_size=4, stride=2),
    nn.ReLU(),
    nn.Conv2d(32, input_shape[0], kernel_size=8, stride=4),
    nn.ReLU(),
    nn.Sigmoid()
)

我不能做的是用

训练自动编码器
def forward(self, x):
    x = self.encoder(x)
    x = self.decoder(x)
    return x

解码器给我一个错误,解码器无法对张量进行上采样:

Calculated padded input size per channel: (3 x 3). Kernel size: (4 x 4). Kernel size can't be greater than actual input size

【问题讨论】:

    标签: python neural-network conv-neural-network pytorch


    【解决方案1】:

    您没有通过ConvTranspose2d 进行足够的上采样,编码器的形状仅为1 像素(width x height),请参见此示例:

    import torch
    
    layer = torch.nn.ConvTranspose2d(8, 64, kernel_size=3, stride=1)
    print(layer(torch.randn(64, 8, 1, 1)).shape)
    

    这会在上采样后打印您的确切 (3,3) 形状。

    你可以:

    • 使内核更小 - 而不是 4 在解码器中的第一个 Conv2d 使用 32 甚至 1
    • 上采样更多,例如:torch.nn.ConvTranspose2d(8, 64, kernel_size=7, stride=2) 会给你7x7
    • 我个人会做什么:在编码器中减少采样,因此输出形状至少为4x45x5。如果您将图像压缩得如此之多,则无法将足够的信息编码到一个像素中,即使代码通过网络也不会学习任何有用的表示。

    【讨论】:

    • 感谢您的回答。主要的限制是我想要图像的 8 维表示,因此减少到 1 个像素(我将有 8x 像素,以后可以用作分类器)。我想将图像分为 8 个类别。附言我不是靠这个赚钱的。这是为了我自己的好奇心。谢谢。
    • 我在想可能是 2x2x2 来获得我的 8 节课?您认为这样会更好吗?
    • 老实说,我不确定您的目标是什么。 Autoencoder 的目标是将表示压缩成最重要的部分,并尽可能无损地解压缩。你的输入形状是什么?为什么要使用自动编码器进行分类?正常的方法不会让你受益更多吗?
    • 我的输入形状是批处理,1,84,84 来自 openai 健身房的 atari 游戏。我想使用自动编码器将帧分类为 8 个不同的类。
    • 非常感谢您的建议。我会试试的。
    【解决方案2】:

    我已经设法实现了一个自动编码器,它提供了一个无监督的聚类(在我的例子中是 8 个类)

    这不是专家解决方案。感谢@Szymon Maszke 的建议。

    self.encoder = nn.Sequential(
        nn.Conv2d(1, 32, kernel_size=8, stride=4),
        nn.ReLU(),
        nn.Conv2d(32, 64, kernel_size=4, stride=2),
        nn.ReLU(),
        nn.Conv2d(64, 2, kernel_size=3, stride=1),
        nn.ReLU(),
        nn.MaxPool2d(6, stride=1)
    )
    
    self.decoder = nn.Sequential(
        nn.ConvTranspose2d(2, 64, kernel_size=3, stride=1),
        nn.ReLU(),
        nn.ConvTranspose2d(64, 32, kernel_size=8, stride=4),
        nn.ReLU(),
        nn.ConvTranspose2d(32, 1, kernel_size=8, stride=4)
    )
    

    【讨论】:

    猜你喜欢
    • 2022-08-02
    • 2020-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-27
    相关资源
    最近更新 更多