Ich benutze das LSTM-Netzwerk in Keras. Während des Trainings schwankt der Verlust stark und ich verstehe nicht, warum das passieren würde.
Hier ist das NN, das ich ursprünglich verwendet habe:
Und hier sind der Verlust und die Genauigkeit während des Trainings:
(Beachten Sie, dass die Genauigkeit letztendlich tatsächlich 100% erreicht, aber ungefähr 800 Epochen dauert.)
Ich dachte, dass diese Schwankungen aufgrund von Dropout-Ebenen / Änderungen in der Lernrate auftreten (ich habe rmsprop / adam verwendet), also habe ich ein einfacheres Modell erstellt:
Ich habe auch SGD ohne Schwung und Verfall verwendet. Ich habe verschiedene Werte für ausprobiert, lr
aber immer noch das gleiche Ergebnis erzielt.
sgd = optimizers.SGD(lr=0.001, momentum=0.0, decay=0.0, nesterov=False)
Aber ich hatte immer noch das gleiche Problem: Der Verlust schwankte, anstatt nur abzunehmen. Ich habe immer gedacht, dass der Verlust nur allmählich sinken soll, aber hier scheint er sich nicht so zu verhalten.
Damit:
Ist es normal, dass der Verlust während des Trainings so schwankt? Und warum sollte es passieren?
Wenn nicht, warum sollte dies für das einfache LSTM-Modell passieren, dessen
lr
Parameter auf einen wirklich kleinen Wert eingestellt sind?
Vielen Dank. (Bitte beachten Sie, dass ich hier ähnliche Fragen geprüft habe, aber es hat mir nicht geholfen, mein Problem zu lösen.)
Aktualisierung: Verlust für mehr als 1000 Epochen (keine BatchNormalization-Schicht, Keras 'Unmodifikator RmsProp):
Upd. 2: Für das endgültige Diagramm:
model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
history = model.fit(train_x, train_y, epochs = 1500)
Daten: Folgen von Stromwerten (von den Sensoren eines Roboters).
Zielvariablen: Die Oberfläche, auf der der Roboter arbeitet (als One-Hot-Vektor, 6 verschiedene Kategorien).
Vorverarbeitung:
- hat die Abtastfrequenz geändert, damit die Sequenzen nicht zu lang sind (LSTM scheint nichts anderes zu lernen);
- Schneiden Sie die Sequenzen in die kleineren Sequenzen (die gleiche Länge für alle kleineren Sequenzen: jeweils 100 Zeitschritte);
- Überprüfen Sie, ob jede der 6 Klassen ungefähr die gleiche Anzahl von Beispielen im Trainingssatz enthält.
Keine Polsterung.
Form des Trainingssatzes (# Sequenzen, # Zeitschritte in einer Sequenz, # Merkmale):
(98, 100, 1)
Form der entsprechenden Beschriftungen (als One-Hot-Vektor für 6 Kategorien):
(98, 6)
Schichten:
Die restlichen Parameter (Lernrate, Stapelgröße) entsprechen den Standardeinstellungen in Keras:
keras.optimizers.RMSprop(lr=0.001, rho=0.9, epsilon=None, decay=0.0)
batch_size: Integer oder None. Anzahl der Proben pro Gradientenaktualisierung. Wenn nicht angegeben, wird standardmäßig 32 verwendet.
Upd. 3:
Der Verlust für batch_size=4
:
Denn batch_size=2
das LSTM schien nicht richtig zu lernen (Verlust schwankt um den gleichen Wert und nimmt nicht ab).
Upd. 4: Um zu sehen, ob das Problem nicht nur ein Fehler im Code ist: Ich habe ein künstliches Beispiel gemacht (2 Klassen, die nicht schwer zu klassifizieren sind: cos vs arccos). Verlust und Genauigkeit während des Trainings für diese Beispiele:
Antworten:
Es gibt mehrere Gründe, die zu Schwankungen des Trainingsverlusts über Epochen führen können. Das wichtigste ist jedoch die Tatsache, dass fast alle neuronalen Netze mit unterschiedlichen Formen des anständigen stochastischen Gradienten trainiert werden . Aus diesem Grund gibt es den Parameter batch_size, der bestimmt, wie viele Beispiele Sie verwenden möchten, um die Modellparameter einmal zu aktualisieren. Wenn Sie alle Beispiele für jedes Update verwenden, sollte es abnehmen und schließlich ein Limit erreichen. Beachten Sie, dass es andere Gründe dafür gibt, dass der Verlust ein stochastisches Verhalten aufweist.
Dies erklärt, warum wir Schwingungen sehen. Aber in Ihrem Fall ist es mehr als normal, würde ich sagen. Wenn ich Ihren Code betrachte, sehe ich zwei mögliche Quellen.
Großes Netzwerk, kleiner Datensatz: Es scheint, dass Sie ein relativ großes Netzwerk mit mehr als 200K-Parametern mit einer sehr kleinen Anzahl von Stichproben (~ 100) trainieren. Um dies ins rechte Licht zu rücken, möchten Sie 200K-Parameter lernen oder ein gutes lokales Minimum in einem 200K-D-Raum mit nur 100 Abtastwerten finden. So könnten Sie am Ende nur herumwandern, anstatt sich auf ein gutes lokales Minimum festzulegen. (Das Wandern ist auch auf den zweiten Grund unten zurückzuführen).
Sehr kleine batch_size. Sie verwenden sehr kleine batch_size. Es ist also so, als ob Sie jedem kleinen Teil der Datenpunkte vertrauen. Angenommen, Sie haben innerhalb Ihrer Datenpunkte eine falsch beschriftete Stichprobe. Dieses Beispiel kann in Kombination mit 2-3 sogar ordnungsgemäß gekennzeichneten Beispielen zu einer Aktualisierung führen, die den globalen Verlust nicht verringert, sondern erhöht oder von lokalen Minima wegwirft. Wenn die batch_size größer ist, werden solche Effekte reduziert. Zusammen mit anderen Gründen ist es gut, wenn batch_size höher als ein Minimum ist. Wenn es zu groß ist, wird das Training auch langsam. Daher wird batch_size als Hyperparameter behandelt.
quelle
Ihre Verlustkurve sieht für mich nicht so schlecht aus. Es sollte definitiv ein wenig auf und ab "schwanken", solange der allgemeine Trend dahin geht, dass es sinkt - das macht Sinn.
Die Stapelgröße spielt auch eine Rolle beim Lernen Ihres Netzwerks. Daher möchten Sie diese möglicherweise zusammen mit Ihrer Lernrate optimieren. Außerdem würde ich die gesamte Kurve zeichnen (bis sie 100% Genauigkeit / minimalen Verlust erreicht). Es hört sich so an, als hätten Sie es für 800 Epochen trainiert und zeigen nur die ersten 50 Epochen - die gesamte Kurve wird wahrscheinlich eine ganz andere Geschichte erzählen.
quelle
Die Schwankungen sind innerhalb bestimmter Grenzen normal und hängen davon ab, dass Sie eine heuristische Methode verwenden, in Ihrem Fall sind sie jedoch übermäßig. Trotz allem nimmt die Leistung eine bestimmte Richtung und daher funktioniert das System. Aus den von Ihnen veröffentlichten Grafiken geht hervor, dass das Problem von Ihren Daten abhängt, sodass es ein schwieriges Training ist. Wenn Sie bereits versucht haben, die Lernrate zu ändern, versuchen Sie, den Trainingsalgorithmus zu ändern. Sie würden zustimmen, Ihre Daten zu testen: Berechnen Sie zuerst die Bayes-Fehlerrate mit einem KNN (verwenden Sie bei Bedarf die Trickregression). Auf diese Weise können Sie überprüfen, ob die Eingabedaten alle benötigten Informationen enthalten. Versuchen Sie dann das LSTM ohne Validierung oder Ausfall, um zu überprüfen, ob es in der Lage ist, das für Sie erforderliche Ergebnis zu erzielen. Wenn der Trainingsalgorithmus nicht geeignet ist, sollten Sie die gleichen Probleme auch ohne Validierung oder Ausfall haben. Passen Sie am Ende das Training und die Validierungsgröße an, um das beste Ergebnis im Testsatz zu erzielen. Die statistische Lerntheorie ist kein Thema, über das auf einmal gesprochen werden kann, wir müssen Schritt für Schritt vorgehen.
quelle