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))
Voici l'exemple de LSTM tiré de la documentation. Je ne sais pas comprendre les choses suivantes:
Modifier:
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: matrices attendues, obtenu en 3D, tenseurs 2D en
La sortie pour le LSTM est la sortie pour tous les nœuds cachés de la couche finale.hidden_size
- le nombre de blocs LSTM par couche.input_size
- le nombre d'entités en entrée par pas de temps.num_layers
- le nombre de couches cachées.
Au total, il y a hidden_size * num_layers
Blocs LSTM.
Les dimensions en entrée sont (seq_len, batch, input_size)
.seq_len
- le nombre de pas de temps dans chaque flux d'entrée.batch
- la taille de chaque lot de séquences d'entrée.
Les dimensions cachées et de la cellule sont: (num_layers, batch, hidden_size)
output (seq_len, batch, hidden_size * num_directions): tenseur contenant les entités en sortie (h_t) de la dernière couche du RNN, pour chaque t.
Donc, il y aura hidden_size * num_directions
les sorties. Vous n'avez pas initialisé le RNN pour qu'il soit bidirectionnel, donc num_directions
est 1. Donc output_size = hidden_size
.
Éditer : Vous pouvez modifier le nombre de sorties en utilisant un calque linéaire:
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)))
Note : pour cette réponse, j'ai supposé que nous ne parlions que de LSTM non bidirectionnels.
Source: documents PyTorch .
Answer by cdo256 est presque correct. Il se trompe en parlant de hidden_size. Il l'explique comme:
hidden_size - nombre de blocs LSTM par couche.
mais vraiment, voici une meilleure explication:
Chaque couche d'état sigmoïde, tanh ou masquée de la cellule est en réalité un ensemble de nœuds dont le nombre est égal à la taille de la couche masquée. Par conséquent, chacun des "nœuds" dans la cellule LSTM est en réalité un groupe de nœuds de réseau neuronal normaux, comme dans chaque couche d'un réseau neuronal densément connecté. Par conséquent, si vous définissez hidden_size = 10, chacun de vos blocs LSTM, ou cellules, aura des réseaux de neurones contenant 10 nœuds. Le nombre total de blocs LSTM dans votre modèle LSTM sera équivalent à celui de votre longueur de séquence.
Ceci peut être constaté en analysant les différences dans les exemples entre nn.LSTM et nn.LSTMCell:
https://pytorch.org/docs/stable/nn.html#torch.nn.LSTM
et
Vous pouvez définir
batch_first = True
si vous voulez faire une entrée et une sortie fournies comme
(batch_size, seq, input_size)
Je dois le savoir aujourd'hui, donc partager avec vous.