Hinzufügen von Funktionen zum Zeitreihenmodell LSTM

42

Ich habe ein wenig über LSTMs und ihre Verwendung für Zeitreihen nachgelesen und es war interessant, aber gleichzeitig schwierig. Eine Sache, die ich bisher nicht verstanden habe, ist der Ansatz, zusätzliche Funktionen zu einer Liste von Zeitreihenfunktionen hinzuzufügen. Angenommen, Sie haben Ihren Datensatz wie folgt eingerichtet:

t-3, t-2, t-1, Ausgabe

Nehmen wir nun an, Sie wissen, dass Sie eine Funktion haben, die die Ausgabe beeinflusst, aber nicht unbedingt eine Zeitreihenfunktion ist, sagen wir, es ist das Wetter draußen. Ist dies etwas, was Sie einfach hinzufügen können und das LSTM wird in der Lage sein zu unterscheiden, was der Zeitreihenaspekt ist und was nicht?

Rjay155
quelle
Ich mag deine Frage. Können Sie jedoch erläutern, wie diese Nicht-Zeitreihenfunktion die Ausgabe zum Zeitpunkt t auf der Grundlage des Fachwissens beeinflusst?
HoraceT

Antworten:

39

Für RNNs (zB LSTMs und Grus), die Schicht Eingang ist eine Liste von Zeitschritten, und jeder Zeitschritt ist ein Merkmal Tensor. Das bedeutet, dass Sie einen Eingangstensor wie diesen haben könnten (in Pythonic-Notation):

# Input tensor to RNN
[
    # Timestep 1
    [ temperature_in_paris, value_of_nasdaq, unemployment_rate ],
    # Timestep 2
    [ temperature_in_paris, value_of_nasdaq, unemployment_rate ],
    # Timestep 3
    [ temperature_in_paris, value_of_nasdaq, unemployment_rate ],
    ...
]

Sie können also in jedem Zeitschritt mehrere Funktionen verwenden. In meinen Augen ist Wetter ein Zeitreihenmerkmal: Wo ich lebe, ist es eine Funktion der Zeit. Es ist also durchaus sinnvoll, Wetterinformationen in jedem Zeitschritt als eine Ihrer Funktionen zu codieren (mit einer geeigneten Codierung, z. B. bewölkt = 0, sonnig = 1 usw.).

Wenn Sie Daten haben, die keine Zeitreihen sind, ist es jedoch nicht wirklich sinnvoll, sie durch den LSTM zu leiten. Vielleicht funktioniert der LSTM trotzdem, aber selbst wenn dies der Fall ist, geht dies wahrscheinlich zu Lasten eines höheren Verlusts / einer geringeren Genauigkeit pro Trainingszeit.

Alternativ können Sie diese Art von "zusätzlichen" Informationen in Ihr Modell außerhalb des LSTM über zusätzliche Ebenen einfügen. Möglicherweise haben Sie einen Datenfluss wie diesen:

TIME_SERIES_INPUT ------> LSTM -------\
                                       *---> MERGE ---> [more processing]
AUXILIARY_INPUTS --> [do something] --/

Sie würden also Ihre AUX-Eingänge mit den LSTM-Ausgängen zusammenführen und Ihr Netzwerk von dort aus fortsetzen. Jetzt ist Ihr Modell einfach mehrwertig.

Angenommen, Sie behalten in Ihrer speziellen Anwendung nur die letzte Ausgabe der LSTM-Ausgabesequenz bei. Nehmen wir an, es ist ein Vektor der Länge 10. Ihre Hilfseingabe könnte Ihr codiertes Wetter sein (also ein Skalar). Ihre Verschmelzungsschicht einfach könnte die Hilfswetterinformationen auf das Ende des LSTM Ausgangsvektor anhängen einen einzigen Vektor der Länge zu produzieren 11. Aber Sie müssen nicht müssen nur die letzte LSTM Ausgang Zeitschritt halten: Wenn der LSTM 100 Zeitschritte ausgegeben, die jeweils Mit einem 10-Vektor-Feature können Sie immer noch Ihre zusätzlichen Wetterinformationen anheften, was zu 100 Zeitschritten führt, die jeweils aus einem Vektor von 11 Datenpunkten bestehen.

Einen guten Überblick darüber bietet die Keras-Dokumentation zu ihrer funktionalen API .

In anderen Fällen möchten Sie, wie @horaceT feststellt, den LSTM möglicherweise auf nicht-zeitlichen Daten ausrichten. Prognostizieren Sie beispielsweise das Wetter morgen an einem bestimmten Ort. In diesem Fall sind hier drei Vorschläge mit jeweils positiven / negativen:

  1. Lassen Sie den ersten Zeitschritt Ihre Konditionierungsdaten enthalten, da er den internen / verborgenen Zustand Ihres RNN effektiv "einstellt". Ehrlich gesagt würde ich dies aus einer Reihe von Gründen nicht tun: Ihre Konditionierungsdaten müssen dieselbe Form haben wie die übrigen Funktionen. Dies erschwert die Erstellung von statusbezogenen RNNs (im Hinblick darauf, wie Sie die Dateneingabe wirklich sorgfältig verfolgen) in das Netzwerk) kann das Netzwerk die Konditionierungsdaten mit genügend Zeit "vergessen" (z. B. lange Trainingssequenzen oder lange Vorhersagesequenzen) usw.

  2. Schließen Sie die Daten als Teil der zeitlichen Daten selbst ein. Jeder Merkmalsvektor zu einem bestimmten Zeitschritt enthält also "meistens" Zeitreihendaten, wobei jedoch die Konditionierungsdaten an das Ende jedes Merkmalsvektors angehängt werden. Wird das Netzwerk lernen, dies zu erkennen? Wahrscheinlich, aber selbst dann schaffen Sie eine schwierige Lernaufgabe, indem Sie die Sequenzdaten mit nicht-sequentiellen Informationen belasten. Deshalb würde ich auch davon abraten .

  3. Der wahrscheinlich beste Ansatz wäre, den verborgenen Zustand des RNN zum Zeitpunkt Null direkt zu beeinflussen. Dies ist der Ansatz von Karpathy und Fei-Fei sowie von Vinyals et al . So funktioniert es:

    1. x
    2. v=Wx+bWb
    3. v

    Dieser Ansatz ist am "theoretischsten" korrekt, da er die RNN für Ihre nicht-zeitlichen Eingaben ordnungsgemäß aufbereitet, das Formproblem auf natürliche Weise löst und außerdem verhindert, dass die Zeitschritte Ihrer Eingaben mit zusätzlichen, nicht-zeitlichen Informationen verschmutzt. Der Nachteil ist, dass dieser Ansatz häufig eine Steuerung Ihrer Architektur auf Diagrammebene erfordert. Wenn Sie also eine Abstraktion auf höherer Ebene wie Keras verwenden, ist die Implementierung schwierig, es sei denn, Sie fügen Ihren eigenen Ebenentyp hinzu.

Adam Sypniewski
quelle
1
Guter Vorschlag, aber was ist, wenn die Ausgabe des LSTM eine strukturelle Abhängigkeit von einem Nicht-Zeitreihen-Prädiktor aufweist?
HoraceT
Könnten Sie ein Beispiel geben?
Adam Sypniewski
6
OK, hier ist ein sehr künstliches Beispiel. Angenommen, Sie versuchen, das Wetter zum Zeitpunkt t basierend auf den Beobachtungen der letzten n Zeitschritte vorherzusagen. Das Wetter hängt von dem Teil der Welt ab, in dem Sie sich befinden. Wenn es Sommer auf der Nordhalbkugel ist, ist es Winter auf der Südhalbkugel. Dieser Nord-Süd-Faktor sollte also berücksichtigt werden. Können Sie es in LSTM integrieren?
HoraceT
1
Gute Frage! Ich habe Änderungen hinzugefügt, um dies zu beheben.
Adam Sypniewski
Danke für die Änderungen und die beiden Verweise. Ziemlich nützlich.
HoraceT
2

Basierend auf all den guten Antworten dieses Threads habe ich eine Bibliothek geschrieben, um Bedingungen für Hilfseingaben zu erstellen. Es abstrahiert die Komplexität und wurde so benutzerfreundlich wie möglich gestaltet:

https://github.com/philipperemy/cond_rnn/ (Tensorflow)

Ich hoffe es hilft!

Philippe Remy
quelle
0

Es gibt eine Funktion in Keras LSTM reset_states(states).

Der Parameter states ist jedoch die Verknüpfung von zwei Zuständen, Hidden State h und Cell State.

States = [h, c]

es wäre interessant zu wissen , ob Sie initialisieren sollen hoder cdie nach Ansätzen in den oben genannten Papieren.

user2614596
quelle
0

Dies ist wahrscheinlich nicht die effizienteste Methode, aber die statischen Variablen können mit der Option auf Zeitreihenlänge wiederholt werden tf.tile().

double-d
quelle