Понимание простой 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 из документов. Я не знаю, понимают ли следующие вещи:
- Что такое размер вывода и почему он не указан нигде?
- Почему вход имеет 3 измерения. Что представляют собой 5 и 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)
Я узнал это сегодня, так что делюсь с вами.