Повышение дискретизации автоэнкодера в pytorch - PullRequest
0 голосов
/ 23 сентября 2019

Я определил мой авто-кодер в 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

Ответы [ 2 ]

3 голосов
/ 23 сентября 2019

Вы недостаточно повышаете частоту дискретизации через 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 в декодере используйте 3 или 2 или даже 1
  • Повышение семпла, например: torch.nn.ConvTranspose2d(8, 64, kernel_size=7, stride=2) даст вам 7x7
  • Что бы я сделал лично: меньше даунсэмпла в кодере, поэтому выведите форму после него как минимум 4x4или, может быть, 5x5.Если вы сократите изображение настолько, что не сможете закодировать достаточно информации в один пиксель, и даже если код пройдет, сеть не получит никакого полезного представления.
2 голосов
/ 24 сентября 2019

Мне удалось реализовать авто-кодер, который обеспечивает кластеризацию без контроля (в моем случае 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)
)
...