Molti a uno e molti a molti esempi LSTM in Keras


108

Cerco di capire gli LSTM e come costruirli con Keras. Ho scoperto che ci sono principalmente le 4 modalità per eseguire un RNN (le 4 a destra nella foto)

inserisci qui la descrizione dell'immagine Fonte immagine: Andrej Karpathy

Ora mi chiedo come sarebbe uno snippet di codice minimalista per ciascuno di essi in Keras. Quindi qualcosa di simile

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

per ciascuna delle 4 attività, magari con un po 'di spiegazione.

Risposte:


121

Così:

  1. Uno a uno : potresti usare un Denselivello poiché non stai elaborando sequenze:

    model.add(Dense(output_size, input_shape=input_shape))
  2. Uno-a-molti : questa opzione non è supportata e il concatenamento di modelli non è molto semplice Keras, quindi la seguente versione è la più semplice:

    model.add(RepeatVector(number_of_times, input_shape=input_shape))
    model.add(LSTM(output_size, return_sequences=True))
    
  3. Many-to-one : in realtà, il tuo frammento di codice è (quasi) un esempio di questo approccio:

    model = Sequential()
    model.add(LSTM(1, input_shape=(timesteps, data_dim)))
    
  4. Molti-a-molti : questo è lo snippet più semplice quando la lunghezza dell'input e dell'output corrisponde al numero di passaggi ricorrenti:

    model = Sequential()
    model.add(LSTM(1, input_shape=(timesteps, data_dim), return_sequences=True))
    
  5. Molti a molti quando il numero di passaggi differisce dalla lunghezza di input / output : questo è incredibilmente difficile in Keras. Non ci sono frammenti di codice facili per codificarlo.

EDIT: Annuncio 5

In una delle mie recenti applicazioni, abbiamo implementato qualcosa che potrebbe essere simile a molti-a-molti dalla quarta immagine. Nel caso in cui si desideri avere una rete con la seguente architettura (quando un input è più lungo dell'output):

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

È possibile ottenere ciò nel modo seguente:

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

Dov'è Nil numero di ultimi passaggi che vuoi coprire (nell'immagine N = 3).

Da questo punto si arriva a:

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

è semplice come una sequenza di imbottitura artificiale di lunghezza Nutilizzando ad esempio i 0vettori, al fine di adattarla a una dimensione appropriata.


10
Un chiarimento: ad esempio per molti a uno, usi LSTM (1, input_shape = (timesteps, data_dim))) Pensavo che 1 stia per il numero di celle LSTM / nodi nascosti, ma apparentemente non Come codificheresti un Molti- a uno con diciamo, 512 nodi però di? (Poiché ho letto qualcosa di simile a quello che pensavo sarebbe stato fatto con model.add (LSTM (512, input_shape = ...)) model.add (Dense (1)) a cosa serve quello?)
Luca Thiede

1
In questo caso - il tuo codice - dopo aver corretto un errore di battitura dovrebbe essere ok.
Marcin Możejko

Perché usiamo RepeatVector e non un vettore con la prima voce 1 = 0 e tutte le altre voci = 0 (secondo l'immagine sopra, non è affatto Input negli stati successivi, e non sempre lo stesso input, cosa farebbe Repeat Vector nella mia comprensione)
Luca Thiede

1
Se pensi attentamente a questa immagine, è solo una presentazione concettuale di un'idea di uno-a-molti . Tutte queste unità nascoste devono accettare qualcosa come input. Quindi, potrebbero accettare lo stesso input come input con il primo input uguale a xe l'altro uguale a 0. Ma - d'altra parte - potrebbero accettare lo stesso xripetuto anche molte volte. Un approccio diverso è quello di concatenare i modelli che è difficile Keras. L'opzione che ho fornito è il caso più semplice di architettura uno-a-molti in Keras.
Marcin Możejko

Bello ! Sto pensando di utilizzare LSTM da N a N in un'architettura GAN. Avrò un generatore basato su LSTM. Darò a questo generatore (come usato in "Variabile latente" in gans) la prima metà della serie temporale e questo generatore produrrà la seconda metà della serie temporale. Quindi combinerò le due metà (reale e generata) per produrre l'input "falso" per il gan. Pensi che usare il punto 4 della tua soluzione funzionerà? o, in altre parole, questa (soluzione 4) è il modo giusto per farlo?
rjpg

6

Ottima risposta di @Marcin Możejko

Vorrei aggiungere quanto segue al NR.5 (molti a molti con differenti in / out di lunghezza):

A) come Vanilla LSTM

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

B) come Encoder-Decoder 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')) 

1
Potresti spiegare i dettagli B) Encoder-Decoder LSTMdell'architettura? Ho problemi a comprendere i ruoli dei passaggi "RepeatVector" / "TimeDistributed".
Marsellus Wallace
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.