Viele zu einem und viele zu viele LSTM-Beispiele in Keras


107

Ich versuche LSTMs zu verstehen und wie man sie mit Keras erstellt. Ich fand heraus, dass es hauptsächlich die 4 Modi gibt, um eine RNN auszuführen (die 4 richtigen im Bild).

Geben Sie hier die Bildbeschreibung ein Bildquelle: Andrej Karpathy

Jetzt frage ich mich, wie ein minimalistischer Codefragment für jeden von ihnen in Keras aussehen würde. Also so etwas wie

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

für jede der 4 Aufgaben, vielleicht mit ein wenig Erklärung.

Antworten:


120

So:

  1. Eins-zu-eins : Sie können eine DenseEbene verwenden, da Sie keine Sequenzen verarbeiten:

    model.add(Dense(output_size, input_shape=input_shape))
  2. Eins-zu-viele : Diese Option wird nicht gut unterstützt, da die Verkettung von Modellen nicht sehr einfach ist. Daher ist Kerasdie folgende Version die einfachste:

    model.add(RepeatVector(number_of_times, input_shape=input_shape))
    model.add(LSTM(output_size, return_sequences=True))
  3. Viele zu eins : Ihr Code-Snippet ist (fast) ein Beispiel für diesen Ansatz:

    model = Sequential()
    model.add(LSTM(1, input_shape=(timesteps, data_dim)))
  4. Viele-zu-Viele : Dies ist das einfachste Snippet, wenn die Länge der Eingabe und Ausgabe mit der Anzahl der wiederkehrenden Schritte übereinstimmt:

    model = Sequential()
    model.add(LSTM(1, input_shape=(timesteps, data_dim), return_sequences=True))
  5. Viele zu viele, wenn sich die Anzahl der Schritte von der Eingabe- / Ausgabelänge unterscheidet : Dies ist in Keras sehr schwierig. Es gibt keine einfachen Codefragmente, um das zu codieren.

BEARBEITEN: Anzeige 5

In einer meiner letzten Anwendungen haben wir etwas implementiert, das vielen zu vielen aus dem 4. Bild ähneln könnte . Wenn Sie ein Netzwerk mit der folgenden Architektur haben möchten (wenn eine Eingabe länger als die Ausgabe ist):

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

Sie können dies auf folgende Weise erreichen:

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

Wo Nist die Anzahl der letzten Schritte, die Sie abdecken möchten (auf dem Bild N = 3)?

Von diesem Punkt an:

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

ist so einfach wie eine künstliche Auffüllsequenz der Länge N, z. B. mit 0Vektoren, um sie auf eine geeignete Größe einzustellen.


10
Eine Klarstellung: Zum Beispiel verwenden Sie für viele zu eins LSTM (1, input_shape = (timesteps, data_dim)). Ich dachte, die 1 steht für die Anzahl der LSTM-Zellen / versteckten Knoten, aber anscheinend nicht. Wie würden Sie ein Many- codieren? zu eins mit sagen wir mal 512 Knoten als? (Da ich etwas Ähnliches gelesen habe, dachte ich, dass es mit model.add (LSTM (512, input_shape = ...)) model.add (Dense (1)) gemacht werden würde. Wofür wird das verwendet als?)
Luca Thiede

1
In diesem Fall - Ihr Code - sollte nach Korrektur eines Tippfehlers in Ordnung sein.
Marcin Możejko

Warum verwenden wir den RepeatVector und keinen Vektor mit dem ersten Eintrag 1 = 0 und allen anderen Einträgen = 0 (gemäß dem obigen Bild ist der in den späteren Zuständen überhaupt kein Eingang und nicht immer der gleiche Eingang). was Repeat Vector nach meinem Verständnis tun würde)
Luca Thiede

1
Wenn Sie sich dieses Bild genau überlegen, ist es nur eine konzeptionelle Darstellung einer Idee von Eins zu Viele . Alle diese versteckten Einheiten müssen etwas als Eingabe akzeptieren. Also - sie akzeptieren möglicherweise die gleiche Eingabe sowie die Eingabe, wobei die erste Eingabe gleich xund die andere gleich ist 0. Andererseits könnten sie das Gleiche auch xviele Male wiederholen. Ein anderer Ansatz besteht darin, Modelle zu verketten, was schwierig ist Keras. Die Option, die ich bereitgestellt habe, ist der einfachste Fall einer Eins-zu-Viele- Architektur in Keras.
Marcin Możejko

Nett ! Ich denke darüber nach, LSTM N bis N in einer GAN-Architektur zu verwenden. Ich werde einen LSTM-basierten Generator haben. Ich werde diesem Generetor (wie in "Latente Variable" in Gans verwendet) die erste Hälfte der Zeitreihe geben, und dieser Generator wird die zweite Hälfte der Zeitreihe erzeugen. Dann werde ich die beiden Hälften (real und generiert) kombinieren, um die "falsche" Eingabe für das Gan zu erzeugen. Denken Sie, dass die Verwendung von Poin 4 Ihrer Lösung funktionieren wird? oder mit anderen Worten, ist dies (Lösung 4) der richtige Weg, dies zu tun?
rjpg

6

Tolle Antwort von @Marcin Możejko

Ich würde NR.5 Folgendes hinzufügen (viele zu viele mit unterschiedlicher In / Out-Länge):

A) als Vanilla LSTM

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

B) als 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
Könnten Sie bitte die Details der B) Encoder-Decoder LSTMArchitektur erklären ? Ich habe Probleme beim Verständnis der Rollen der Schritte "RepeatVector" / "TimeDistributed".
Marsellus Wallace
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.