Понимание простой LSTM pytorch

import torch,ipdb
import torch.autograd as autograd
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.autograd import Variable

rnn = nn.LSTM(input_size=10, hidden_size=20, num_layers=2)
input = Variable(torch.randn(5, 3, 10))
h0 = Variable(torch.randn(2, 3, 20))
c0 = Variable(torch.randn(2, 3, 20))
output, hn = rnn(input, (h0, c0))

Это пример LSTM из документов. Я не знаю, понимают ли следующие вещи:

  1. Что такое размер вывода и почему он не указан нигде?
  2. Почему вход имеет 3 измерения. Что представляют собой 5 и 3?
  3. Что такое 2 и 3 в h0 и c0, что они представляют?

Редактировать:

import torch,ipdb
import torch.autograd as autograd
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.autograd import Variable
import torch.nn.functional as F

num_layers=3
num_hyperparams=4
batch = 1
hidden_size = 20
rnn = nn.LSTM(input_size=num_hyperparams, hidden_size=hidden_size, num_layers=num_layers)

input = Variable(torch.randn(1, batch, num_hyperparams)) # (seq_len, batch, input_size)
h0 = Variable(torch.randn(num_layers, batch, hidden_size)) # (num_layers, batch, hidden_size)
c0 = Variable(torch.randn(num_layers, batch, hidden_size))
output, hn = rnn(input, (h0, c0))
affine1 = nn.Linear(hidden_size, num_hyperparams)

ipdb.set_trace()
print output.size()
print h0.size()

*** RuntimeError: ожидаемые матрицы, получили 3D, 2D тензоры в

Ответ 1

Выход для LSTM - это выход для всех скрытых узлов на конечном уровне.
hidden_size - количество блоков LSTM для каждого слоя.
input_size - количество входных функций на шаг времени.
num_layers - количество скрытых слоев.
Всего есть hidden_size * num_layers LSTM.

Входные размеры (seq_len, batch, input_size).
seq_len - количество шагов времени в каждом потоке ввода.
batch - размер каждой партии входных последовательностей.

Скрытые и размеры ячеек: (num_layers, batch, hidden_size)

output (seq_len, batch, hidden_size * num_directions): тензор, содержащий выходные характеристики (h_t) из последнего уровня RNN, для каждого t.

Таким образом, будут выполняться команды hidden_size * num_directions. Вы не инициализировали RNN двунаправленным, поэтому num_directions равно 1. Таким образом output_size = hidden_size.

Изменить: вы можете изменить количество выходов с помощью линейного слоя:

out_rnn, hn = rnn(input, (h0, c0))
lin = nn.Linear(hidden_size, output_size)
v1 = nn.View(seq_len*batch, hidden_size)
v2 = nn.View(seq_len, batch, output_size)
output = v2(lin(v1(out_rnn)))

Примечание: для этого ответа я предположил, что мы говорим только о двунаправленных LSTM.

Источник: документы PyTorch.

Ответ 2

Ответ cdo256 почти прав. Он ошибается, когда ссылается на то, что означает hidden_size. Он объясняет это как:

hidden_size - количество блоков LSTM для каждого слоя.

но на самом деле, вот лучшее объяснение:

Каждый уровень сигмоида, тана или скрытого состояния в ячейке фактически представляет собой набор узлов, число которых равно размеру скрытого слоя. Поэтому каждый из "узлов" в ячейке LSTM на самом деле представляет собой кластер нормальных нейронных сетевых узлов, как на каждом слое плотно связанной нейронной сети. Следовательно, если вы установите hidden_size = 10, то каждый из ваших блоков LSTM или ячеек будет иметь нейронные сети с 10 узлами в них. Общее количество блоков LSTM в вашей модели LSTM будет эквивалентно количеству вашей длины последовательности.

Это можно увидеть, проанализировав различия в примерах между nn.LSTM и nn.LSTMCell:

https://pytorch.org/docs/stable/nn.html#torch.nn.LSTM

а также

https://pytorch.org/docs/stable/nn.html#torch.nn.LSTMCell

Ответ 3

Вы можете установить

batch_first = True

если вы хотите сделать ввод и вывод представленными как

(batch_size, seq, input_size)

Я узнал это сегодня, так что делюсь с вами.