web-dev-qa-db-fra.com

Plusieurs à un et plusieurs à plusieurs exemples de LSTM à Keras

J'essaie de comprendre les LSTM et comment les construire avec Keras. J'ai découvert qu'il y avait principalement les 4 modes pour exécuter un RNN (les 4 bons dans l'image)

enter image description here Source de l'image: Andrej Karpathy

Maintenant, je me demande à quoi ressemblerait un extrait de code minimaliste pour Keras. Donc quelque chose comme

model = Sequential()
model.add(LSTM(128, input_shape=(timesteps, data_dim)))
model.add(Dense(1))

pour chacune des 4 tâches, peut-être avec un peu d'explication.

83
Luca Thiede

Alors:

  1. One-to-one: vous pouvez utiliser un calque Dense car vous ne traitez pas de séquences:
    model.add(Dense(output_size, input_shape=input_shape))

2. n-à-plusieurs: cette option n'est pas prise en charge car le chaînage des modèles n'est pas très simple dans Keras, la version suivante est donc la plus simple:

    model.add(RepeatVector(number_of_times, input_shape=input_shape))
    model.add(LSTM(output_size, return_sequences=True))
  1. Plusieurs-à-un: en réalité, votre extrait de code est (presque) un exemple de cette approche:
    model = Sequential()
    model.add(LSTM(1, input_shape=(timesteps, data_dim)))
  1. Plusieurs à plusieurs: Il s'agit de l'extrait de code le plus simple lorsque la longueur de l'entrée et de la sortie correspond au nombre d'étapes récurrentes:
    model = Sequential()
    model.add(LSTM(1, input_shape=(timesteps, data_dim), return_sequences=True))
  1. Plusieurs-à-plusieurs lorsque le nombre d'étapes diffère de la longueur entrée/sortie: c'est extrêmement difficile en keras. Il n'y a pas d'extraits de code faciles à coder.

EDIT: Ad 5

Dans l'une de mes applications récentes, nous avons implémenté quelque chose qui pourrait être similaire à plusieurs-à-plusieurs à partir de la 4ème image. Si vous voulez avoir un réseau avec l’architecture suivante (quand une entrée est plus longue que la sortie):

                                        O O O
                                        | | |
                                  O O O O O O
                                  | | | | | | 
                                  O O O O O O

Vous pouvez y parvenir de la manière suivante:

    model = Sequential()
    model.add(LSTM(1, input_shape=(timesteps, data_dim), return_sequences=True))
    model.add(Lambda(lambda x: x[:, -N:, :]

N est le nombre de dernières étapes à couvrir (sur l'image N = 3).

De ce point arriver à:

                                        O O O
                                        | | |
                                  O O O O O O
                                  | | | 
                                  O O O 

est aussi simple qu'une séquence de remplissage artificielle de longueur N en utilisant par ex. avec les vecteurs 0, afin de l'ajuster à une taille appropriée.

85
Marcin Możejko

Super réponse de @Marcin Możejko

Je voudrais ajouter ce qui suit à NR.5 (plusieurs à plusieurs avec des longueurs d'entrée/sortie différentes):

A) comme LSTM vanille

model = Sequential()
model.add(LSTM(N_BLOCKS, input_shape=(N_INPUTS, N_FEATURES)))
model.add(Dense(N_OUTPUTS))

B) comme codeur-décodeur LSTM

model.add(LSTM(N_BLOCKS, input_shape=(N_INPUTS, N_FEATURES))  
model.add(RepeatVector(N_OUTPUTS))
model.add(LSTM(N_BLOCKS, return_sequences=True))  
model.add(TimeDistributed(Dense(1)))
model.add(Activation('linear')) 
0
gustavz