Подготовить декодер последовательности к сети последовательности в PyTorch - PullRequest
0 голосов
/ 21 сентября 2018

Я работал с моделями от последовательности к последовательности в Pytorch.Последовательность в последовательность моделей состоит из кодера и декодера.

кодер преобразует (batch_size X input_features X num_of_one_hot_encoded_classes) -> (batch_size X input_features X hidden_size)

декодер возьмет эту входную последовательность и преобразует ее в (batch_size X output_features X num_of_one_hot_encoded_classes)

Примером может быть: -

enter image description here

Так что в приведенном выше примере мне необходимо преобразовать 22 входных объекта в 10 выходных объектов.В Keras это можно сделать с помощью RepeatVector (10).

Пример -

model.add(LSTM(256, input_shape=(22, 98)))
model.add(RepeatVector(10))
model.add(Dropout(0.3))
model.add(LSTM(256, return_sequences=True))

Хотя я не уверен, является ли это правильным способом преобразования входных последовательностей ввыходные.

Итак, мой вопрос -

  • Какой стандартный способ преобразования входных последовательностей в выходные.например.преобразование из (batch_size, 22, 98) -> (batch_size, 10, 98)?Или как мне подготовить декодер?

Фрагмент кода кодера (написанный на Pytorch) -

class EncoderRNN(nn.Module):
    def __init__(self, input_size, hidden_size):
        super(EncoderRNN, self).__init__()
        self.hidden_size = hidden_size
        self.lstm = nn.LSTM(input_size=input_size, hidden_size=hidden_size,
          num_layers=1, batch_first=True)

    def forward(self, input):
        output, hidden = self.lstm(input)
        return output, hidden

1 Ответ

0 голосов
/ 12 марта 2019

Ну, у вас есть опции, во-первых, нужно повторить последнее состояние кодера 10 раз и передать его в качестве входных данных для декодера, например так:

import torch
input = torch.randn(64, 22, 98)
encoder = torch.nn.LSTM(98, 256, batch_first=True)
encoded, _ = encoder(input)
decoder_input = encoded[:, -1:].repeat(1, 10, 1)
decoder = torch.nn.LSTM(256, 98, batch_first=True)
decoded, _ = decoder(decoder_input)
print(decoded.shape) #torch.Size([64, 10, 98])

Другой вариант - использовать вниманиемеханизм, как это:

#assuming we have obtained the encoded sequence and declared the decoder as before
attention_calculator = torch.nn.Conv1d(256+98, 1, kernel_size=1)
hidden = (torch.zeros(1, 64, 98), torch.zeros(1, 64, 98))
outputs = []
for i in range(10):
    attention_input = torch.cat([hidden[0][0][:, None, :].expand(-1, 22, -1), encoded], dim=2).permute(0, 2, 1)
    attention_value = torch.nn.functional.softmax(attention_calculator(attention_input).squeeze(), dim=1)
    decoder_input = (attention_value[:, :, None] * encoded).sum(dim=1, keepdim=True)
    output, hidden = decoder(decoder_input, hidden)
    outputs.append(output)
outputs = torch.cat(outputs, dim=1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...