Pytorch LSTM grad только на последнем выходе - PullRequest
1 голос
/ 29 апреля 2019

Я работаю с последовательностями разной длины. Но я хотел бы только градуировать их на основе выходных данных, вычисленных в конце последовательности.

Сэмплы упорядочены таким образом, что их длина уменьшается и они дополняются нулями. Для 5 1D образцов это выглядит так (без учета ширины для видимости):

array([[5, 7, 7, 4, 5, 8, 6, 9, 7, 9],
       [6, 4, 2, 2, 6, 5, 4, 2, 2, 0],
       [4, 6, 2, 4, 5, 1, 3, 1, 0, 0],
       [8, 8, 3, 7, 7, 7, 9, 0, 0, 0],
       [3, 2, 7, 5, 7, 0, 0, 0, 0, 0]])

Для LSTM я использую nn.utils.rnn.pack_padded_sequence с индивидуальной длиной последовательности:

x = nn.utils.rnn.pack_padded_sequence(x, [10, 9, 8, 7, 5], batch_first=True)

Инициализация LSTM в конструкторе модели:

self.lstm = nn.LSTM(width, n_hidden, 2)

Затем я вызываю LSTM и распаковываю значения:

x, _ = self.lstm(x)
x = nn.utils.rnn.pad_packed_sequence(x1, batch_first=True)

Затем я применяю полностью связанный слой и softmax

x = x.contiguous()
x = x.view(-1, n_hidden)
x = self.linear(x)
x = x.reshape(batch_size, n_labels, 10) # 10 is the sample height
return F.softmax(x, dim=1)

Это дает мне вывод формы batch x n_labels x height (5x12x10).

Для каждого сэмпла я бы хотел использовать только одну оценку для последнего вывода batch x n_labels (5 * 12). У меня вопрос: как мне этого добиться?

Одна идея - применить tanh к последнему скрытому слою, возвращенному из модели, но я не совсем уверен, даст ли это тот же результат. Можно ли эффективно извлечь выходные данные, вычисленные в конце последовательности, например, используя ту же последовательность длин, что и для pack_padded_sequence?

Ответы [ 2 ]

1 голос
/ 30 апреля 2019

Как ответил Неаабфи, hidden[-1] правильно.Чтобы быть более конкретным в вашем вопросе, как писал docs :

output, (h_n, c_n) = self.lstm(x_pack) # batch_first = True

# h_n is a vector of shape (num_layers * num_directions, batch, hidden_size)

В вашем случае у вас есть стек из 2 слоев LSTM с направлением только forward, тогда:

h_n shape is (num_layers, batch, hidden_size)

Возможно, вы предпочитаете скрытое состояние h_n последнего слоя, тогда ** вот что вы должны сделать:

output, (h_n, c_n) = self.lstm(x_pack)
h = h_n[-1] # h of shape (batch, hidden_size)
y = self.linear(h)

Здесь это код, который оборачивает любой повторяющийся слой LSTM, RNN или GRU в DynamicRNN.DynamicRNN может выполнять повторяющиеся вычисления для последовательностей различной длины, не заботясь о порядке длин.

0 голосов
/ 29 апреля 2019

Вы можете получить доступ к последнему скрытому слою следующим образом:

output, (hidden, cell) = self.lstm(x_pack)
y = self.linear(hidden[-1])
...