train stochastic sgd optimizer gradientdescentoptimizer descent tensorflow neural-network deep-learning conv-neural-network

tensorflow - stochastic - Adam optimizer se vuelve loco después de 200k lotes, la pérdida de entrenamiento crece



tensorflow stochastic gradient descent (2)

Sí, esto podría ser una especie de caso de ecuaciones / números inestable súper complicado, pero lo más seguro es que su velocidad de entrenamiento es simplemente demasiado alta ya que su pérdida disminuye rápidamente hasta 25K y luego oscila mucho en el mismo nivel. Intenta disminuirlo por un factor de 0.1 y ver qué pasa. Usted debe ser capaz de alcanzar un valor de pérdida aún menor.

¡Seguir explorando! :)

He estado observando un comportamiento muy extraño al entrenar una red, donde después de un par de 100k iteraciones (de 8 a 10 horas) de aprender bien, todo se rompe y la pérdida de entrenamiento crece :

Los datos de entrenamiento en sí mismos son aleatorios y se distribuyen en muchos archivos .tfrecord que contienen 1000 ejemplos cada uno, luego se barajan nuevamente en la etapa de entrada y se agrupan hasta 200 ejemplos.

El fondo

Estoy diseñando una red que realiza cuatro tareas de regresión diferentes al mismo tiempo, por ejemplo, determinando la probabilidad de que aparezca un objeto en la imagen y determinando simultáneamente su orientación. La red comienza con un par de capas convolucionales, algunas con conexiones residuales, y luego se ramifica en los cuatro segmentos totalmente conectados.

Dado que la primera regresión resulta en una probabilidad, estoy usando la entropía cruzada para la pérdida, mientras que los otros usan la distancia L2 clásica. Sin embargo, debido a su naturaleza, la pérdida de probabilidad es de alrededor del orden de 0..1 , mientras que las pérdidas de orientación pueden ser mucho más grandes, digamos 0..10 . Ya normalicé los valores de entrada y salida y uso el recorte

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

En los casos en que las cosas pueden ponerse muy mal.

He estado utilizando (con éxito) el optimizador de Adam para optimizar el tensor que contiene todas las pérdidas distintas (en lugar de reduce_sum ), así:

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)

Para mostrar los resultados en TensorBoard, realmente hago

loss_sum = tf.reduce_sum(loss)

para un resumen escalar.

Adam está configurado para la tasa de aprendizaje 1e-4 y épsilon 1e-4 (veo el mismo comportamiento con el valor predeterminado de epislon y se rompe aún más rápido cuando mantengo la tasa de aprendizaje en 1e-3 ). La regularización tampoco tiene influencia en esto, hace este tipo de forma consistente en algún momento.

También debo agregar que detener la capacitación y reiniciar desde el último punto de control, lo que implica que los archivos de entrada de la capacitación también se barajan nuevamente, da como resultado el mismo comportamiento. El entrenamiento siempre parece comportarse de manera similar en ese punto.


Sí. Este es un problema conocido de Adán.

Las ecuaciones para Adán son

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)

donde m es un promedio móvil exponencial del gradiente medio y v es un promedio móvil exponencial de los cuadrados de los gradientes. El problema es que cuando ha estado entrenando durante mucho tiempo y está cerca de lo óptimo, entonces v puede volverse muy pequeño. Si de repente, los gradientes comienzan a aumentar nuevamente, se dividirá por un número muy pequeño y explotará.

Por defecto, beta1=0.9 y beta2=0.999 . Entonces m cambia mucho más rápido que v . Así que m puede volver a ser grande, mientras que v es aún pequeño y no puede ponerse al día.

Para remediar este problema, puede aumentar epsilon que es 10-8 por defecto. De este modo, se detiene el problema de dividir casi por 0. Según su red, un valor de epsilon en 0.1 , 0.01 o 0.001 puede ser bueno.