web-dev-qa-db-fra.com

Comprendre un simple pytorch LSTM

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:

  1. Qu'est-ce que la taille de sortie et pourquoi n'est-elle spécifiée nulle part?
  2. Pourquoi l'entrée a 3 dimensions. Que représentent 5 et 3?
  3. Que sont 2 et 3 dans h0 et c0, que représentent-ils?

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

26
Abhishek Bhatia

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 .

28
cdo256

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

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

8
Lsehovac

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.

2
zzuczy