J'ai un LSTM implémenté dans PyTorch comme ci-dessous.

import numpy as np

import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable

class LSTM(nn.Module):
    """
    Defines an LSTM.
    """

    def __init__(self, input_dim, hidden_dim, output_dim, num_layers):

        super(LSTM, self).__init__()

        self.lstm = nn.LSTM(input_dim, hidden_dim, num_layers, batch_first=True)

    def forward(self, input_data):

        lstm_out_pre, _ = self.lstm(input_data)
        return lstm_out_pre

model = LSTM(input_dim=2, hidden_dim=2, output_dim=1, num_layers=8)

random_data1 = torch.Tensor(np.random.standard_normal(size=(1, 5, 2)))
random_data2 = torch.Tensor(np.random.standard_normal(size=(1, 5, 2)))

out1 = model(random_data1).detach().numpy()
out2 = model(random_data2).detach().numpy()

print(out1)
print(out2)

Je crée simplement un réseau LSTM et y passe deux entrées aléatoires. Les sorties n'ont pas de sens car quelles que soient random_data1 et random_data2, out1 et out2 sont toujours les mêmes. Cela n'a aucun sens pour moi, car les entrées aléatoires multipliées par des poids aléatoires devraient donner des sorties différentes.

Cela ne semble pas être le cas si j'utilise moins de couches cachées. Avec num_layers=2, cet effet semble nul. Et à mesure que vous l'augmentez, out1 et out2 continuent de se rapprocher. Cela n'a pas de sens pour moi car avec plus de couches de LSTM empilées les unes sur les autres, nous multiplions l'entrée avec plus de poids aléatoires, ce qui devrait amplifier les différences dans l'entrée et donner une sortie très différente.

Quelqu'un peut-il expliquer ce comportement? Y a-t-il un problème avec ma mise en œuvre?

Dans une exécution particulière, random_data1 est

tensor([[[-2.1247, -0.1857],
         [ 0.0633, -0.1089],
         [-0.6460, -0.1079],
         [-0.2451,  0.9908],
         [ 0.4027,  0.3619]]])

random_data2 est

tensor([[[-0.9725,  1.2400],
         [-0.4309, -0.7264],
         [ 0.5053, -0.9404],
         [-0.6050,  0.9021],
         [ 1.4355,  0.5596]]])

out1 est

[[[0.12221643 0.11449362]
  [0.18342148 0.1620608 ]
  [0.2154751  0.18075559]
  [0.23373817 0.18768947]
  [0.24482158 0.18987371]]]

out2 est

[[[0.12221643 0.11449362]
  [0.18342148 0.1620608 ]
  [0.2154751  0.18075559]
  [0.23373817 0.18768945]
  [0.24482158 0.18987371]]]

EDIT: je cours sur les configurations suivantes -

PyTorch - 1.0.1.post2 
Python - 3.6.8 with GCC 7.3.0 
OS - Pop!_OS 18.04 (Ubuntu 18.04, more-or-less) 
CUDA - 9.1.85
Nvidia driver - 410.78
2
ANANDA PADHMANABHAN S 13 mars 2019 à 08:22

3 réponses

Meilleure réponse

Les poids initiaux pour LSTM sont de petits nombres proches de 0, et en ajoutant plus de couches, les poids initiaux et les biais deviennent plus petits : tous les poids et biais sont initialisés de -sqrt(k) à -sqrt(k), où k = 1/ hidden_size (https://pytorch.org/docs/stable/nn. html#torch.nn.LSTM)

En ajoutant plus de couches, vous multipliez efficacement l'entrée par de nombreux petits nombres, donc l'effet de l'entrée est fondamentalement de 0 et seuls les biais dans les couches ultérieures comptent.

Si vous essayez LSTM avec bias=False, vous verrez que la sortie se rapproche de plus en plus de 0 avec l'ajout de couches.

4
Sergii Dymchenko 13 mars 2019 à 08:28

J'ai essayé de changer le nombre de couches en un nombre inférieur et les valeurs diffèrent, c'est parce que les valeurs sont multipliées par un petit nombre encore et encore, ce qui réduit l'importance de l'entrée.

2
Jibin Mathew 13 mars 2019 à 08:31

J'ai initialisé tous les poids dans l'utilisation de kaiming_normal et cela fonctionne bien.

0
Alex 3 janv. 2021 à 19:22