optimizer learning tensorflow deep-learning

tensorflow - learning - adam optimizer



Descenso de gradiente vs Adagrad vs Momentum en TensorFlow (3)

Estoy estudiando TensorFlow y cómo usarlo, incluso si no soy un experto en redes neuronales y aprendizaje profundo (solo lo básico).

Siguiendo los tutoriales, no entiendo las diferencias reales y prácticas entre los tres optimizadores para pérdidas. Miro la API y entiendo los principios, pero mis preguntas son:

1. ¿Cuándo es preferible usar uno en lugar de los otros?

2. ¿Hay diferencias importantes para saber?


Aquí hay una breve explicación basada en mi comprensión:

  • El impulso helps SGD a navegar a lo largo de las direcciones relevantes y suaviza las oscilaciones en lo irrelevante. Simplemente agrega una fracción de la dirección del paso anterior a un paso actual. Esto logra la amplificación de la velocidad en la dirección correcta y suaviza la oscilación en direcciones incorrectas. Esta fracción generalmente está en el rango (0, 1). También tiene sentido usar el impulso adaptativo. Al comienzo del aprendizaje, un gran impulso solo dificultará su progreso, por lo que tiene sentido usar algo como 0.01 y una vez que todos los gradientes altos desaparecieron, puede usar un impulso más grande. Hay un problema con el impulso: cuando estamos muy cerca de la meta, nuestro impulso en la mayoría de los casos es muy alto y no sabe que debería disminuir. Esto puede hacer que se pierda u oscile alrededor de los mínimos.
  • El gradiente acelerado de nesterov supera este problema al comenzar a reducir la velocidad temprano. En el momento, primero calculamos el gradiente y luego hacemos un salto en esa dirección amplificado por cualquier momento que hayamos tenido previamente. NAG hace lo mismo pero en otro orden: al principio hacemos un gran salto en función de nuestra información almacenada, y luego calculamos el gradiente y hacemos una pequeña corrección. Este cambio aparentemente irrelevante ofrece aceleraciones prácticas significativas.
  • AdaGrad o gradiente adaptativo permite que la tasa de aprendizaje se adapte según los parámetros. Realiza actualizaciones más grandes para parámetros poco frecuentes y actualizaciones más pequeñas para uno frecuente. Debido a esto, es muy adecuado para datos dispersos (PNL o reconocimiento de imagen). Otra ventaja es que básicamente elimina la necesidad de ajustar la tasa de aprendizaje. Cada parámetro tiene su propia tasa de aprendizaje y, debido a las peculiaridades del algoritmo, la tasa de aprendizaje está disminuyendo monotónicamente. Esto causa el mayor problema: en algún momento la tasa de aprendizaje es tan pequeña que el sistema deja de aprender.
  • AdaDelta resolves el problema de disminuir monotónicamente la tasa de aprendizaje en AdaGrad. En AdaGrad, la tasa de aprendizaje se calculó aproximadamente como uno dividido por la suma de las raíces cuadradas. En cada etapa, agrega otra raíz cuadrada a la suma, lo que hace que el denominador aumente constantemente. En AdaDelta, en lugar de sumar todas las raíces cuadradas pasadas, usa una ventana deslizante que permite que la suma disminuya. RMSprop es muy similar a AdaDelta
  • Adam o el momento adaptativo es un algoritmo similar a AdaDelta. Pero además de almacenar las tasas de aprendizaje para cada uno de los parámetros, también almacena los cambios de impulso para cada uno de ellos por separado.

    Algunas visualizaciones :

Diría que SGD, Momentum y Nesterov son inferiores a los últimos 3.


Vamos a reducirlo a un par de preguntas simples:

¿Qué optimizador me daría el mejor resultado / precisión?

No hay bala de plata. Algunos optimizadores para su tarea probablemente funcionarían mejor que los demás. No hay forma de saberlo de antemano, debe probar algunos para encontrar el mejor. La buena noticia es que los resultados de diferentes optimizadores probablemente estarían cerca uno del otro. Sin embargo, debe encontrar los mejores hiperparámetros para cualquier optimizador único que elija.

¿Qué optimizador debo usar ahora?

Tal vez, tome AdamOptimizer y ejecútelo para learning_rate 0.001 y 0.0001. Si quieres mejores resultados, intenta correr para otras tasas de aprendizaje. O pruebe otros optimizadores y ajuste sus hiperparámetros.

Larga historia

Hay algunos aspectos a considerar al elegir su optimizador:

  • Fácil de usar (es decir, qué tan rápido puede encontrar parámetros que funcionen para usted);
  • Velocidad de convergencia (básica como SGD o más rápida que cualquier otra);
  • Huella de memoria (generalmente entre 0 y x2 tamaños de su modelo);
  • Relación con otras partes del proceso de capacitación.

El SGD simple es lo mínimo que se puede hacer: simplemente multiplica los gradientes por la tasa de aprendizaje y agrega el resultado a los pesos. SGD tiene una serie de hermosas cualidades: tiene solo 1 hiperparámetro; no necesita memoria adicional; tiene un efecto mínimo en las otras partes del entrenamiento. También tiene 2 inconvenientes: puede ser demasiado sensible a la elección de la tasa de aprendizaje y la capacitación puede llevar más tiempo que con otros métodos.

A partir de estos inconvenientes de SGD simple, podemos ver para qué son las reglas de actualización más complicadas (optimizadores): sacrificamos una parte de nuestra memoria para lograr un entrenamiento más rápido y, posiblemente, simplificar la elección de hiperparámetros.

La sobrecarga de memoria generalmente no es significativa y puede ignorarse. A menos que el modelo sea extremadamente grande, o esté entrenando en GTX760, o luchando por el liderazgo de ImageNet. Los métodos más simples como el impulso o el gradiente acelerado de Nesterov necesitan 1.0 o menos del tamaño del modelo (tamaño de los hiperparámetros del modelo). Los métodos de segundo orden (Adam, podrían necesitar el doble de memoria y cálculo).

Velocidad de convergencia: prácticamente cualquier cosa es mejor que SGD y cualquier otra cosa es difícil de comparar. Una nota podría ser que AdamOptimizer es bueno para comenzar a entrenar casi de inmediato, sin calentamiento.

Considero que la facilidad de uso es la más importante en la elección de un optimizador. Los diferentes optimizadores tienen un número diferente de hiperparámetros y tienen una sensibilidad diferente para ellos. Considero que Adam es el más simple de todos los disponibles. Por lo general, debe verificar 2-4 tasas de aprendizaje entre 0.001 y 0.0001 para determinar si el modelo converge bien. Para la comparación de SGD (e impulso), típicamente intento [0.1, 0.01, ... 10e-5] . Adam tiene 2 hiperparámetros más que rara vez tienen que cambiarse.

Relación entre optimizador y otras partes del entrenamiento . El ajuste de hiperparámetros generalmente implica seleccionar {learning_rate, weight_decay, batch_size, droupout_rate} simultáneamente. Todos ellos están relacionados entre sí y cada uno puede verse como una forma de regularización del modelo. Uno, por ejemplo, tiene que prestar mucha atención si, exactamente, se utiliza weight_decay o L2-norm y posiblemente elija AdamWOptimizer lugar de AdamOptimizer .


La respuesta de Salvador Dali ya explica las diferencias entre algunos métodos populares (es decir, optimizadores), pero trataría de explicarlos un poco más.
(Tenga en cuenta que nuestras respuestas no están de acuerdo sobre algunos puntos, especialmente con respecto a ADAGRAD).

Ímpetu clásico (CM) vs Gradiente acelerado de Nesterov (NAG)

(Principalmente basado en la sección 2 del documento sobre la importancia de la inicialización y el impulso en el aprendizaje profundo ).

Cada paso en CM y NAG está compuesto de dos subpasos:

  • Un subpaso de impulso: esto es simplemente una fracción (típicamente en el rango [0.9,1) ) del último paso.
  • Un subpaso dependiente del gradiente: es como el paso habitual en SGD : es el producto de la tasa de aprendizaje y el vector opuesto al gradiente, mientras que el gradiente se calcula desde dónde comienza este subpaso.

CM toma el subpaso de gradiente primero, mientras que NAG toma el subpaso de impulso primero.

Aquí hay una demostración de una respuesta sobre la intuición para CM y NAG :

Entonces NAG parece ser mejor (al menos en la imagen), pero ¿por qué?

Lo importante a tener en cuenta es que no importa cuándo llega el subpaso de impulso, sería lo mismo de cualquier manera. Por lo tanto, también podríamos comportarnos si el subpaso de impulso ya se ha tomado.

Por lo tanto, la pregunta en realidad es: suponiendo que el subpaso del gradiente se tome después del subpaso del momento, ¿deberíamos calcular el subpaso del gradiente como si comenzara en la posición anterior o posterior al subpaso del momento?

"Después de eso" parece ser la respuesta correcta, ya que, en general, el gradiente en algún punto θ señala más o menos en la dirección de θ a un mínimo (con la magnitud relativamente correcta), mientras que el gradiente en algún otro punto es menos probable que apunte en la dirección de θ a un mínimo (con la magnitud relativamente correcta).

Aquí hay una demostración (del siguiente gif):

  • El mínimo es donde está la estrella, y las curvas son líneas de contorno . (Para obtener una explicación sobre las líneas de contorno y por qué son perpendiculares al gradiente, vea los videos 1 y 2 del legendario 3Blue1Brown ).
  • La flecha morada (larga) es el subpaso de impulso.
  • La flecha roja transparente es el subpaso de gradiente si comienza antes del subpaso de impulso.
  • La flecha negra es el subpaso de gradiente si comienza después del subpaso de impulso.
  • CM terminaría en el blanco de la flecha roja oscura.
  • NAG terminaría en el blanco de la flecha negra.

Tenga en cuenta que este argumento de por qué NAG es mejor es independiente de si el algoritmo está cerca de un mínimo.
En general, tanto NAG como CM a menudo tienen el problema de acumular más impulso del que es bueno para ellos, por lo que cada vez que deben cambiar de dirección, tienen un "tiempo de respuesta" embarazoso. La ventaja de NAG sobre CM que explicamos no evita el problema, sino que solo hace que el "tiempo de respuesta" de NAG sea menos vergonzoso (pero aún vergonzoso).

Este problema de "tiempo de respuesta" se demuestra maravillosamente en el gif de Alec Radford (que apareció en la respuesta de Salvador Dali ):

ADAGRAD

(Principalmente basado en la sección 2.2.2 en ADADELTA: Un método de tasa de aprendizaje adaptativo (el documento ADADELTA original), ya que me parece mucho más accesible que los Métodos adaptativos de subgradiente para el aprendizaje en línea y la optimización estocástica (el documento ADAGRAD original).

En SGD , el paso viene dado por - learning_rate * gradient , mientras que learning_rate es un hiperparámetro.
ADAGRAD también tiene un hiperparámetro de tasa de aprendizaje, pero la tasa de aprendizaje real para cada componente del gradiente se calcula individualmente.
El componente i -ésimo del paso t está dado por:

learning_rate - --------------------------------------- * gradient_i_t norm((gradient_i_1, ..., gradient_i_t))

mientras:

  • gradient_i_k es el componente i -ésimo del gradiente en el paso k -ésimo
  • (gradient_i_1, ..., gradient_i_t) es un vector con t componentes. Esto no es intuitivo (al menos para mí) que construir un vector así tiene sentido, pero eso es lo que hace el algoritmo (conceptualmente).
  • norm(vector) es la norma de Eucldiean (también conocida como norma l2 ) de vector , que es nuestra noción intuitiva de longitud de vector .
  • Confusamente, en ADAGRAD (así como en algunos otros métodos), la expresión que se multiplica por gradient_i_t (en este caso, learning_rate / norm(...) ) a menudo se llama "la tasa de aprendizaje" (de hecho, la llamé " la tasa de aprendizaje real "en el párrafo anterior). Supongo que esto se debe a que en SGD el hiperparámetro learning_rate y esta expresión son uno y el mismo.
  • En una implementación real, se agregaría alguna constante al denominador, para evitar una división por cero.

Por ejemplo si:

  • El componente i -ésimo del gradiente en el primer paso es 1.15
  • El componente i -ésimo del gradiente en el segundo paso es 1.35
  • El componente i -ésimo del gradiente en el tercer paso es 0.9

Entonces la norma de (1.15, 1.35, 0.9) es la longitud de la línea amarilla, que es:
sqrt(1.15^2 + 1.35^2 + 0.9^2) = 1.989 .
Y así, el componente i -ésimo del tercer paso es: - learning_rate / 1.989 * 0.9

Tenga en cuenta dos cosas sobre el componente i -ésimo del paso:

  1. Es proporcional a learning_rate .
  2. En sus cálculos, la norma está aumentando y, por lo tanto, la tasa de aprendizaje está disminuyendo.

Esto significa que ADAGRAD es sensible a la elección del hiperparámetro learning_rate .
Además, puede ser que después de algún tiempo los pasos se vuelvan tan pequeños que ADAGRAD prácticamente se atasque.

ADADELTA y RMSProp

Del artículo de ADADELTA :

La idea presentada en este documento se derivó de ADAGRAD para mejorar los dos inconvenientes principales del método: 1) la disminución continua de las tasas de aprendizaje durante la capacitación, y 2) la necesidad de una tasa de aprendizaje global seleccionada manualmente.

Luego, el documento explica una mejora destinada a abordar el primer inconveniente:

En lugar de acumular la suma de gradientes cuadrados en todo momento, restringimos la ventana de gradientes anteriores que se acumulan para que tengan un tamaño fijo w [...]. Esto garantiza que el aprendizaje continúe progresando incluso después de que se hayan realizado muchas iteraciones de actualizaciones.
Dado que almacenar w gradientes cuadrados anteriores es ineficiente, nuestros métodos implementan esta acumulación como un promedio exponencialmente decreciente de los gradientes cuadrados.

Por "promedio exponencialmente decreciente de los gradientes cuadrados", el documento significa que para cada i calculamos un promedio ponderado de todos los componentes de la i -ésima al cuadrado de todos los gradientes que se calcularon.
El peso de cada componente i -ésimo cuadrado es mayor que el peso del componente i -ésimo cuadrado en el paso anterior.

Esta es una aproximación de una ventana de tamaño w porque los pesos en los pasos anteriores son muy pequeños.

(Cuando pienso en un promedio de descomposición exponencial, me gusta visualizar comet''s rastro de un comet''s , que se vuelve más y más oscuro a medida que se aleja del cometa:

)

Si solo realiza este cambio en ADAGRAD, obtendrá RMSProp, que es un método propuesto por Geoff Hinton en la Lección 6e de su Clase Coursera .

Entonces, en RMSProp, el componente i -ésimo del paso t está dado por:

learning_rate - ------------------------------------------------ * gradient_i_t sqrt(exp_decay_avg_of_squared_grads_i + epsilon)

mientras:

  • epsilon es un hiperparámetro que evita una división por cero.
  • exp_decay_avg_of_squared_grads_i es un promedio exponencialmente exp_decay_avg_of_squared_grads_i de los componentes de la i -ésima al cuadrado de todos los gradientes calculados (incluyendo gradient_i_t ).

Pero como se mencionó anteriormente, ADADELTA también tiene como objetivo deshacerse del hiperparámetro learning_rate , por lo que debe haber más cosas en él.

En ADADELTA, el componente i -ésimo del paso t está dado por:

sqrt(exp_decay_avg_of_squared_steps_i + epsilon) - ------------------------------------------------ * gradient_i_t sqrt(exp_decay_avg_of_squared_grads_i + epsilon)

mientras que exp_decay_avg_of_squared_steps_i es un promedio exponencialmente exp_decay_avg_of_squared_steps_i de los componentes de la i -ésima al cuadrado de todos los pasos calculados (hasta el paso t-1 ).
sqrt(exp_decay_avg_of_squared_steps_i + epsilon) es algo similar al impulso, y según el documento , "actúa como un término de aceleración". (El documento también da otra razón de por qué se agregó, pero mi respuesta ya es demasiado larga, así que si tiene curiosidad, consulte la sección 3.2).

Adán

(Principalmente basado en Adam: un método para la optimización estocástica , el artículo original de Adam).

Adam es la abreviatura de Adaptive Moment Estimation (vea esta respuesta para obtener una explicación sobre el nombre).
El componente i -ésimo del paso t está dado por:

learning_rate - ------------------------------------------------ * exp_decay_avg_of_grads_i sqrt(exp_decay_avg_of_squared_grads_i) + epsilon

mientras:

  • exp_decay_avg_of_grads_i es un promedio en descomposición exponencial de los componentes i -ésimo de todos los gradientes calculados (incluyendo gradient_i_t ).
  • En realidad, tanto exp_decay_avg_of_grads_i como exp_decay_avg_of_squared_grads_i también se corrigen para tener en cuenta un sesgo hacia 0 (para obtener más información al respecto, consulte la sección 3 en el documento y también una respuesta en stats.stackexchange ).

Tenga en cuenta que Adam usa un promedio de descomposición exponencial de los componentes i -ésimo de los gradientes donde la mayoría de los métodos SGD utilizan el componente i -ésimo del gradiente actual. Esto hace que Adam se comporte como "una bola pesada con fricción", como se explica en el artículo GAN entrenado por una regla de actualización de dos escalas de tiempo converge a un equilibrio local de Nash .
Vea esta respuesta para obtener más información sobre cómo el comportamiento de ímpetu de Adam es diferente del comportamiento de ímpetu habitual.