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:
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.
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 .
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:
- x⃗
- v⃗ =Wx⃗ +b⃗ Wb⃗
- 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.