Die Architektur des Long Short-Term Memory (LSTM) basiert auf einem rekursiven Konzept, das dem des Simple RNN ähnelt. Sowohl der aktuelle Cell State als auch der aktuelle Hidden State werden an den nächsten Zeitschritt (die nächste LSTM-Zelle) weitergegeben 📝. Das LSTM erweitert die Architektur des RNNs um eine Memory Cell (den Cell State) sowie um Gate Units, die den Datenfluss im LSTM kontrollieren 📝.
Beim Simple RNN wird aus dem gewichteten aktuellen Input und dem gewichteten letzten Hidden State der aktuelle Hidden State berechnet, der wiederum an die nächste Schicht bzw. den Output-Layer weitergegeben wird. Der jeweilige Hidden State repräsentiert den aktuellen Stand der Zeitreihe 📝. Beim Training des Modells wird das Verfahren der Backpropagation through time (BPTT) angewendet, um die Gewichte für den Input und den Hidden State zu lernen 📝. Dabei wird der Fehler (Loss) zu jedem Zeitschritt aus der Summe des Fehlers, der mit dem aktuellen Input produziert wird, und dem zuletzt berechneten Fehler zum Zeitpunkt berechnet und rückwärts durch die Zeit weitergegeben 📝. Um den Fehler zu minimieren, ist eine Anpassung der Gewichte erforderlich. Für die Berechnung dieses Updates muss eine Ableitung erfolgen. Dies impliziert für die Struktur des Simple RNNs die wiederholte Anwendung der Kettenregel, was bedeutet, dass für jeden Zeitschritt mit einem Wert kleiner als 1 nachdifferenziert werden muss 📝. Das führt dazu, dass keine Aktualisierung der Gewichte mehr erfolgt und das RNN nichts mehr lernen kann, bzw. nicht fähig ist, Abhängigkeiten über einen längeren Zeitraum zu erlernen 📝. Diesen Effekt bezeichnet man als Vanishing Gradient Problem 📝.
Weiterführende Literatur:
Sepp Hochreiter. 1998. The vanishing gradient problem during learning recurrent
neural nets and problem solutions. International Journal of Uncertainty, Fuzziness
and Knowledge-Based Systems 6, 02 (1998), 107–116.
Der Cell State (Memory Cell) ist in der Lage, Informationen über lange Zeiträume hinweg konsistent zu speichern 📝, 📝, 📝. Die Kontrolle darüber, welche Informationen aus dem aktuellen Input und dem letzten Cell State weiterfließen bzw. "vergessen" werden sollen, obliegt dem Input Gate und dem Forget Gate 📝, 📝, 📝. Auf diese Weise wird dafür gesorgt, dass nur relevante Informationen gespeichert werden und die Gewichte nicht aufgrund von einem großen lokalen Fehler auf zu kleine Werte geupdatet werden 📝. Die additive Berechnung des Cell States gewährleistet zudem, dass bei der Ableitung keine Nachdifferenzierung mit einem Wert kleiner als 1 erforderlich ist, sodass der Fehler konstant weitergegeben werden kann 📝, 📝, 📝. So kann das LSTM größere Abhängigkeiten lernen.
LSTMs sind darauf ausgelegt, Zeitreihen zu verarbeiten 📝. Ein mögliches Anwendungsbeispiel ist die Klassifikation von Text in positives oder negatives Sentiment 📝. Im folgenden werden einige Filmkritiken in positives oder negatives Sentiment klassifiziert.
Eine Filmkritik kann dabei als Zeitreihe betrachtet werden, wobei jedes einzelne Wort (bzw. jeder Token) einen Zeitschritt darstellt. Um die Wörter in eine für das LSTM verarbeitbare Form zu bringen, werden mit einem Embedding Layer Wortembeddings erstellt, welche an das erste LSTM Layer weitergereicht werden. Dieses berechnet für jeden Zeitschritt den Cell State und den Hidden State. Da das Modell darauf trainiert wurde, das Sentiment solcher Filmkritiken vorherzusagen, beinhaltet der Hidden State diese Information für jeden Zeitschritt auf einer abstrakten Ebene. Die nächste LSTM-Schicht benötigt wiederum eine Zeitreihe als Input, weshalb alle Hidden States übermittelt werden, sobald die gesamte Zeitreihe verarbeitet wurde. Um eine Sentiment-Klassifikation des gesamten Textes zu vollziehen, wird am Ende (nur!) der letzte Hidden State an ein Dense Layer weitergegeben.
Dies entspricht einer Architektur, die man mit folgendem Python code mit Keras erstellen kann:
import keras
vocab_size = 10000
max_len = 250
output_dim = 128
model = keras.Sequential()
model.add(keras.layers.Input(shape=(max_len,)))
model.add(keras.layers.Embedding(input_dim=vocab_size, output_dim=output_dim))
model.add(keras.layers.LSTM(output_dim, return_sequences=True))
model.add(keras.layers.LSTM(output_dim))
model.add(keras.layers.Dense(1, activation='sigmoid'))
model.summary()
Die Filmkritiken wurden unter Verwendung eines Vokabulars von 10.000 Wörtern verfasst und auf eine einheitliche Länge von 250 Token gebracht. Das heißt, bei zu kurzen Kritiken wurde Padding hinzugefügt, während zu lange Kritiken abgeschnitten wurden.
Das Embedding Layer generiert Embeddings mit 128 Dimensionen. Das bedeutet, dass ein Wort durch einen dense Vektor mit 128 Fließkommazahlen repräsentiert wird.
In diesem Fall ist die Inputdimension des ersten LSTM Layers gleich der Outputdimension. (Das wäre im Gegensatz zu einer Regresseionsaufgabe bei einer Klassifikationsaufgabe wie dieser nicht nötig gewesen).
Damit alle Hidden States des ersten LSTM Layers an das zweite LSTM Layer weitergegeben werden, ist es erforderlich, den Wert von return_sequences auf True zu setzen.
Das zweite LSTM Layer gibt lediglich den letzten Hidden State an das Dense Layer weiter. Dieses kann mit Hilfe des übergebenen Hidden States die Filmkritik in eine Zahl zwischen 0 (negatives Sentiment) und 1 (positives Sentiment) klassifizieren (Outputdimension ist 1 und Wertebereich wegen der sigmoid Aktivierungsfunktion zwischen 0 und 1).
In der nachfolgenden Visualisierung kannst du den Datenfluss bei der Prediction des Sentiments für eine Beispiel-Filmkritik innerhalb des Modells Schritt für Schritt nachverfolgen:
"This movie was so frustrating. Everything seemed energetic and I was totally prepared to have a good time. I at least thought I'd be able to stand it. But, I was wrong. First, the weird looping? It was like watching "America's Funniest Home Videos". The damn parents. I hated them so much. The stereo-typical Latino family? I need to speak with the person responsible for this. We need to have a talk. That little girl who was always hanging on someone? I just hated her and had to mention it. Now, the final scene transcends, I must say. It's so gloriously bad and full of badness that it is a movie of its own. What crappy dancing. Horrible and beautiful at once."
Klassifikationsergebnis: (negativ)