wake-up-neo.com

Adam Optimizer geht nach 200.000 Chargen durcheinander, der Trainingsverlust wächst

Ich habe beim Trainieren eines Netzwerks ein sehr merkwürdiges Verhalten beobachtet, bei dem nach ein paar 100.000 Iterationen (8 bis 10 Stunden) des Lernens alles kaputt geht und der Trainingsverlust wächst:

Loss explodes

Die Trainingsdaten selbst werden randomisiert und auf viele .tfrecord - Dateien verteilt, die jeweils 1000 - Beispiele enthalten. Anschließend werden sie in der Eingabestufe erneut gemischt und zu 200 - Beispielen zusammengefasst.

Der Hintergrund

Ich entwerfe ein Netzwerk, das gleichzeitig vier verschiedene Regressionsaufgaben ausführt, z. Bestimmen der Wahrscheinlichkeit, dass ein Objekt in dem Bild erscheint, und gleichzeitiges Bestimmen seiner Ausrichtung. Das Netzwerk beginnt mit einigen Faltungsebenen, einige mit verbleibenden Verbindungen, und verzweigt sich dann in die vier vollständig verbundenen Segmente.

Da die erste Regression zu einer Wahrscheinlichkeit führt, verwende ich für den Verlust die Kreuzentropie, während die anderen die klassische L2-Distanz verwenden. Aufgrund ihrer Natur liegt der Wahrscheinlichkeitsverlust jedoch in der Größenordnung von 0..1, Während die Orientierungsverluste viel größer sein können, beispielsweise 0..10. Ich habe bereits sowohl Eingabe- als auch Ausgabewerte normalisiert und Clipping verwendet

normalized = tf.clip_by_average_norm(inferred.sin_cos, clip_norm=2.)

in Fällen, in denen es wirklich schlimm werden kann.

Ich habe (erfolgreich) den Adam-Optimierer verwendet, um den Tensor zu optimieren, der alle deutlichen Verluste enthält (anstatt sie mit reduce_sum Zu versehen), wie folgt:

reg_loss = tf.reduce_sum(tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES))
loss = tf.pack([loss_probability, sin_cos_mse, magnitude_mse, pos_mse, reg_loss])

optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate,
                                   epsilon=self.params.adam_epsilon)
op_minimize = optimizer.minimize(loss, global_step=global_step)

Um die Ergebnisse in TensorBoard anzuzeigen, mache ich das dann tatsächlich

loss_sum = tf.reduce_sum(loss)

für eine skalare Zusammenfassung.

Adam ist auf Lernrate 1e-4 Und epsilon 1e-4 Eingestellt (Ich sehe dasselbe Verhalten mit dem Standardwert für Epislon und es bricht sogar schneller ab, wenn ich die Lernrate auf 1e-3 Belasse.) ). Regularisierung hat auch keinen Einfluss darauf, sie tut dies irgendwann konsequent.

Ich sollte auch hinzufügen, dass das Beenden des Trainings und der Neustart ab dem letzten Prüfpunkt - was impliziert, dass die Trainingseingabedateien ebenfalls neu gemischt werden - dasselbe Verhalten zur Folge haben. Das Training scheint sich zu diesem Zeitpunkt immer ähnlich zu verhalten.

27
sunside

Ja. Dies ist ein bekanntes Problem von Adam.

Die Gleichungen für Adam sind

t <- t + 1
lr_t <- learning_rate * sqrt(1 - beta2^t) / (1 - beta1^t)

m_t <- beta1 * m_{t-1} + (1 - beta1) * g
v_t <- beta2 * v_{t-1} + (1 - beta2) * g * g
variable <- variable - lr_t * m_t / (sqrt(v_t) + epsilon)

dabei ist m ein exponentielles gleitendes Mittel des mittleren Gradienten und v ein exponentielles gleitendes Mittel der Quadrate der Gradienten. Das Problem ist, dass, wenn Sie lange trainiert haben und sich dem Optimum nähern, v sehr klein werden kann. Wenn dann plötzlich die Steigungen wieder zunehmen, wird sie durch eine sehr kleine Zahl geteilt und explodiert.

Standardmäßig beta1=0.9 und beta2=0.999. Also ändert sich m viel schneller als v. So kann m wieder groß werden, während v noch klein ist und nicht aufholen kann.

Um dieses Problem zu beheben, können Sie epsilon erhöhen. Dies ist 10-8 standardmäßig. Auf diese Weise wird das Problem des Teilens durch 0 aufgehoben. Abhängig von Ihrem Netzwerk wird der Wert epsilon in 0.1, 0.01, oder 0.001 könnte gut sein.

42
patapouf_ai

Ja, dies könnte ein super komplizierter Fall von instabilen Zahlen/Gleichungen sein, aber mit größter Gewissheit ist Ihre Trainingsrate einfach zu hoch, da Ihr Verlust schnell bis auf 25.000 abnimmt und dann viel auf demselben Niveau oszilliert. Versuchen Sie es um den Faktor 0,1 zu verringern und sehen Sie, was passiert. Sie sollten in der Lage sein, einen noch niedrigeren Verlustwert zu erreichen.

Erforschen Sie weiter! :)

3
Simanas