Основываясь на моих выводах на дискуссионном форуме Pytorch, существует несколько способов сделать это.
В качестве примера, основываясь на этом обсуждении, я подумал, что достаточно просто назначить транспонированные веса. Вот что делает:
Код: Выделить всё
self.decoder[0].weight = self.encoder[0].weight.t()
Затем я попытался обернуть приведенную выше строку в nn.Parameter():
Код: Выделить всё
self.decoder[0].weight = nn.Parameter(self.encoder[0].weight.t())
Затем я нашел эта ссылка, которая предоставляет различные способы распределения веса. однако я скептически отношусь к тому, что все приведенные там методы действительно верны.
Например, один из способов демонстрируется следующим образом:
Код: Выделить всё
# tied autoencoder using off the shelf nn modules
class TiedAutoEncoderOffTheShelf(nn.Module):
def __init__(self, inp, out, weight):
super().__init__()
self.encoder = nn.Linear(inp, out, bias=False)
self.decoder = nn.Linear(out, inp, bias=False)
# tie the weights
self.encoder.weight.data = weight.clone()
self.decoder.weight.data = self.encoder.weight.data.transpose(0,1)
def forward(self, input):
encoded_feats = self.encoder(input)
reconstructed_output = self.decoder(encoded_feats)
return encoded_feats, reconstructed_output
Код: Выделить всё
weights = nn.Parameter(torch.randn_like(self.encoder[0].weight))
self.encoder[0].weight.data = weights.clone()
self.decoder[0].weight.data = self.encoder[0].weight.data.transpose(0, 1)
Разве это не просто клонирование «необработанных» данных?
Когда я использовал этот подход и визуализировал веса, я заметил, что визуализации были разными, и это еще больше убедило меня в том, что что-то не так.
Я не уверен если бы разные визуализации происходили исключительно из-за одного существа транспонирование другого, или, как я уже подозревал, они оптимизируются независимо (т.е. веса не распределяются между слоями)
пример инициализации веса:


Подробнее здесь: https://stackoverflow.com/questions/579 ... in-pytorch
Мобильная версия