No se limite a “arrojarle a Adam”: entender mal a Adam le costará

en un problema de aprendizaje por refuerzo particularmente difícil. La investigación demostró que agentes similares aprenden tareas comparables. Sin embargo, nuestro modelo estaba muerto en el agua.

Simplifiqué la arquitectura. Agregué capas. Quité capas. Cambié LSTM por Transformers, agregué atención y lo eliminé. Reconstruí las funciones de entrada al menos 20 veces. Incluso probé arquitecturas de memoria exóticas. Pasé miles de horas de GPU en modo de búsqueda de hiperparámetros patológicos y no pude obtener los resultados.

Nada.

La solución, cuando finalmente la encontré, fue humillante: cambié β₂ de 0,999 a 0,95 y reduje β₁ de 0,9 a 0,5.

# La solución "humillante" que realmente funcionó: optimizador = optim.AdamW( model.parameters(), lr=3e-4, betas=(0.5, 0.95), # Los números mágicos eps=1e-4 # Prevenir la división por cero en RL)

La mayoría de los ingenieros de aprendizaje profundo, incluido yo mismo, simplemente hacen lo siguiente:

Simplemente use AdamW con los parámetros predeterminados y establezca la tasa de aprendizaje en 3e-4.

No codifico modelos de aprendizaje profundo por preferencia personal. Si lo hace, seguramente verá esto como la elección del optimizador y la tasa de aprendizaje.

De hecho, probemos GPT 5.6 con el mensaje: "crear un script de entrenamiento para un modelo de aprendizaje profundo"

Como era de esperar, GPT escupe alegremente:

CONFIG = { "lr": 3e-4, "weight_decay": 1e-5, … } …. optimizador = optim.AdamW( model.parameters(), lr=CONFIG["lr"],weight_decay=CONFIG["weight_decay"])

En Karpathy confiamos.

No.

El problema con esta peligrosa suposición es que los ingenieros pasan por alto este aspecto tan importante de la formación y tratan esta parte de la ecuación como resuelta.

Es posible que pueda salirse con la suya, ya que proporciona un valor predeterminado sensato, pero a la larga, especialmente cuando se encuentre con un panorama de optimización difícil o no estacionario, fracasará. Duro.

En este artículo, cubriré:

Cómo funciona realmente Adam Donde Adam falla espectacularmente La intuición detrás de la modificación de los valores predeterminados

Esta no es otra revisión genérica de optimización de parámetros.

Esta es la razón por la que su suposición incorrecta de "simplemente use Adam" está equivocada con la intuición matemática de por qué.

¿Para quién es esto? Utiliza Adam como su optimizador preferido con un nivel superficial (o nulo) de comprensión de cómo funciona y dónde falla.

Cómo funciona realmente Adam

El descenso de gradiente estocástico (SGD) de vainilla aplica la misma tasa de aprendizaje a cada parámetro:

θt=θt−1−α⋅gttheta_t = theta_{t-1} – alpha cdot g_t

Ésta es la ecuación con la que la mayoría de los profesionales están familiarizados. Si tiene un título en informática, es posible que lo haya implementado desde cero.

Multiplica αalpha (la tasa de aprendizaje) por gtg_t (gradiente) y listo, tienes una actualización.

Esto tiene algunos problemas fundamentales, como está ampliamente documentado en la investigación existente, incluida la inestabilidad fundamental causada por gradientes ruidosos. Todo el mundo lo sabe y por eso a SGD se le trata como a un ciudadano de segunda categoría*.

Pronto se inventaron variantes:

SGD con Momentum RMSProp, etc.

*Digo principalmente porque SGD a veces se utiliza como primera opción en problemas de imágenes a gran escala.

Entra Adán

Adam (Kingma & Ba, 2015) fue diseñado para resolver ambos problemas simultáneamente: suavizar gradientes ruidosos y adaptar tamaños de paso por parámetro en función de las estadísticas de gradiente observadas.

Adam mantiene dos estadísticas en ejecución para cada parámetro de su modelo, lo que puede ser matemáticamente elegante pero significa triplicar los requisitos de memoria con gigantescos state_dicts.

Es posible que hayas visto esto 1000 veces. ¿Pero realmente lo entiendes? Lea esto detenidamente hasta que lo entienda.

Estimación del primer momento (el impulso):

mt=β1⋅mt−1+(1−β1)⋅gtm_t = beta_1 cdot m_{t-1} + (1 – beta_1) cdot g_t

Necesitamos entender cada variable en esta ecuación.

mtm_t: el promedio ponderado exponencialmente de los gradientes hasta el paso de tiempo actual tt. ->Esta es la dirección real aplicada a los parámetros del modelo β1beta_1: la caída del impulso, establecida en 0,9 por defecto. Esto es lo que puedes controlar. gtg_t: el gradiente calculado para la marca de tiempo. -> Esto no se aplica al modelo.

Entonces, el gradiente aplicado para cada paso de tiempo ha acumulado información direccional. Se mantiene en la dirección promedio, en lugar de utilizar la dirección calculada para cada paso de tiempo.

Debe comprender que el gradiente real nunca se aplica. Sólo afecta direccionalmente al gradiente final, que puede ser bastante diferente.

Su gradiente real sólo perturba el impulso acumulado, que es la dirección en la que realmente se mueve el gradiente. Imagen por autor

Estimación del segundo momento (la varianza):

vt=β2⋅vt−1+(1−β2)⋅gt2v_t = beta_2 cdot v_{t-1} + (1 – beta_2) cdot g_t^2

vtv_t: el promedio ponderado exponencialmente del gradiente al cuadrado hasta el paso de tiempo actual tt. -> Esto determina cómo se normaliza la actualización β2beta_2: la caída del gradiente al cuadrado, establecida en 0,999 de forma predeterminada. Esto es lo que puedes controlar. gt2g^2_t: el gradiente cuadrado calculado para la marca de tiempo.

Este segundo momento controla el tamaño del paso real.

No es que la tasa de aprendizaje no importe, pero Adam aumenta efectivamente el gradiente aplicado para los parámetros que normalmente reciben un gradiente real pequeño y amortigua el gradiente aplicado para aquellos que reciben gradientes grandes.

V_t controla cuánto se normaliza el gradiente por paso. Los gradientes grandes amortiguan el tamaño del paso. Pequeños gradientes pueden aumentar el tamaño del paso. Imagen del autor.

Tenga en cuenta que el valor predeterminado aquí: 0,999 promedios en los últimos ~1000 pasos.

Corrección de sesgo

Debido a que m₀ = 0 y v₀ = 0, las estimaciones están sesgadas hacia cero en el entrenamiento temprano. Adam corrige esto:

m^t=mt1−β1tv^t=vt1−β2that{m}_t = frac{m_t}{1 – beta_1^t} qquad hat{v}_t = frac{v_t}{1 – beta_2^t}

En los primeros pasos (t pequeña), el denominador (1 – β^t) es significativamente menor que 1, lo que aumenta las estimaciones para compensar la inicialización cero. A medida que t crece, la corrección se vuelve insignificante.

Poniéndolo todo junto: la actualización de parámetros real

La fórmula de actualización entonces se convierte en:

θt=θt−1−α⋅m^tv^t+ϵtheta_t = theta_{t-1} – alpha cdot frac{hat{m}_t}{sqrt{hat{v}_t} + epsilon}

θttheta_t: valor del parámetro actual αalpha tasa de aprendizaje m^that{m}_t​: primer momento con corrección de sesgo v^that{v}_t​: segundo momento con corrección de sesgo v^tsqrt{hat{v}_t}​​: escala de gradiente estimada ϵepsilon: piso de estabilidad (una pequeña constante para evitar grandes actualizaciones desde una escala pequeña)

La intuición es que Adam le da a cada parámetro su propia tasa de aprendizaje adaptativo. Los parámetros en regiones volátiles y de alto gradiente dan pasos pequeños y cautelosos. Los parámetros en regiones tranquilas y de bajo gradiente obtienen pasos más grandes y más seguros.

Incluso si los gradientes son aleatorios o ruidosos, desaparecen. En teoría, esto debería ayudar al optimizador a encontrar los verdaderos mínimos locales de pérdida, pero obviamente no está garantizado.

Esto es elegante. En general funciona, por eso se ha convertido en un meme en la comunidad. También es la fuente de casi todos los modos de falla.

Un ejemplo visual de una de las fallas épicas de Adán.

En este ejemplo, un tamaño de paso adaptable hace que Adam supere drásticamente los mínimos reales, Imagen por autor.

Donde Adam falla espectacularmente

Si las explicaciones visuales no te hacen desenamorarte de Adam, estos fallos sí podrían hacerlo.

Adam no puede converger en problemas triviales de optimización convexa

Esto no es hipotético.

El artículo ICLR de Reddi, Kale y Kumar de 2018, Sobre la convergencia de Adam y más allá, construyó un problema de optimización convexo simple explícito donde Adam no converge a la solución óptima, y ​​identificó el defecto: la prueba de convergencia dada en el artículo original de Adam era completamente errónea.

La memoria a corto plazo de la media móvil exponencial acaba con los gradientes informativos demasiado rápido, y los autores incluso muestran un caso en el que Adam converge hacia la peor solución posible.

Adam converge a una solución subóptima, ¡pero más rápido!

Parece que tu modelo está entrenando en la dirección correcta. Esas curvas de pérdida parecen bastante decentes y direccionalmente precisas.

No.

El artículo de NeurIPS de 2017 de Wilson et al., El valor marginal de los métodos de gradiente adaptativo en el aprendizaje automático, es un ejemplo interesante.

En el artículo, construyen una tarea de clasificación binaria simple. SGD logra cero errores de prueba, mientras que los métodos adaptativos, incluido Adam, tienen errores mucho mayores. Se trata de problemas triviales que se resuelven fácilmente mediante el aprendizaje no adaptativo.

Las arquitecturas modelo importan poco. En esta investigación, cada solución (diferentes arquitecturas) produce el mismo resultado:

Los modelos adaptativos funcionan peor, no mejor, que el SGD básico en el conjunto de prueba.

¡Cuanto más grande es el modelo, más fracasos tiene Adam!

Los investigadores de Meta (Molybog et al.) publicaron Una teoría sobre la inestabilidad de Adam en el aprendizaje automático a gran escala que muestra picos de pérdida inexplicables durante el entrenamiento de modelos de lenguaje grandes.

Los investigadores muestran que Adam tiene la culpa en este caso, con el cambio de escala del gradiente adaptativo. Su análisis está respaldado por experimentos en modelos que van desde 7 mil millones a 546 mil millones de parámetros.

La intuición es esta:

Algunos parámetros ingresan a estados donde la actualización del gradiente es bastante pequeña, lo que reduce v_t.

Como se explicó anteriormente, Adam usa v_t para normalizar la actualización del gradiente, lo que puede ser un problema importante cuando es pequeño.

Por ejemplo, dividiendo por:

vt+ϵ​​sqrt{v_t} + épsilon​ ​

Es un problema cuando v_t se ha reducido a más de 1000 pasos con gradientes calculados muy pequeños. Si aparecen valores de gradiente grandes, aumente m_t a un ritmo desalineado con v_t y 💥: ¡actualización gigantesca! ¡Punto de pérdidas! Dinámica extraña e inexplicable en la que no se puede explicar lo que sucedió ya que nadie inspecciona los momentos de segundo orden de su optimizador state_dict con más de 100 millones de parámetros.

Esto es lo que suponemos que estaba sucediendo con nuestro entrenamiento. Estábamos alcanzando picos extraños en nuestras pérdidas que eran inexplicables. No tengo la paciencia para examinar los momentos de una red muy grande para descubrir qué parámetros estaban causando la actualización explosiva, pero es mi mejor suposición.

RL (puede) destruir a Adán

Si trabaja en RL, esto es especialmente importante, ya que rara vez se analiza en la investigación real y las patologías de Adam solo se contabilizan en lugares difíciles de encontrar (por ejemplo, debe leer el código fuente para encontrarlo).

Una de las suposiciones centrales que hace que Adam sea un valor predeterminado tan confiable es que la distribución del gradiente es estacionaria: la volatilidad de una actualización de parámetro ahora informará la volatilidad de la actualización en el futuro, lo que hace que los tamaños de paso adaptativos sean una opción razonable en el aprendizaje supervisado.

En RL, este simplemente no es el caso.

La política que generó los datos hace 10 pasos puede ser completamente diferente a la política que genera los datos ahora. El panorama de la optimización cambia constantemente. Como resultado, v_t siempre está persiguiendo un objetivo en movimiento.

En la investigación de RL se incorporan dos cosas muy comunes que explican las peculiaridades de Adam:

Aumentar ϵepsilon, la constante predeterminada utilizada en la normalización adaptativa (ver más abajo) Recortar el gradiente a un valor mucho más pequeño7

Aparte de aumentar ϵepsilon

El valor predeterminado de Adam es 1e-8: un piso de estabilidad que debe ser insignificante.

En Dopamine4, un marco de RL profundo elaborado por una investigación de Google, los siguientes valores de ϵepsilon se utilizan como valores predeterminados

AgenteAdam ϵepsilonvs. Adam default ϵepsilonDQN1.5e-4~15,000× más grandeRainbow1.5e-4~15,000× más grandeIQN / M-IQN3.125e-4~31,250× más grande

¿Por qué? Misteriosamente, nunca se discutió en la investigación y es solo un artefacto de personas inteligentes que masajearon a Adam para que la optimización de RL funcionara.

La razón por la que es hasta 32.000 veces más grande es para evitar un posible problema de división por casi cero. Las magnitudes del gradiente hacen que v_t se reduzca a valores muy pequeños, lo que aumenta la probabilidad de grandes actualizaciones desestabilizadoras. Gran no-no en RL.

Compuestos no estacionarios con el problema del objetivo en movimiento.

En los métodos de actor crítico para RL, el objetivo en sí (la estimación del valor hacia la que estás retrocediendo) cambia de manera bastante significativa a medida que la red se actualiza.

Esto significa que la verdadera dirección del gradiente de un parámetro cambia constantemente y puede invertir completamente la escala o el signo en menos de 100 pasos. La memoria exponencial de v_t, que promedia más de ~1000 pasos dada la configuración predeterminada de 0,999, es una receta para un rendimiento deficiente, dado que este objetivo y las ventajas calculadas a partir de él están en constante cambio.

🤔 ¿Deberías descartar a Adam en favor de otro optimizador, como RMSProp?

No necesariamente.

En Revisiting Rainbow, Obando-Ceron & Castro, 2021, los investigadores prueban directamente A/B a Adam vs. RMSProp en 60 juegos de Atari y concluyen que Adam combinado con pérdida de MSE supera la “práctica estándar” de pérdida de RMSProp + Huber, que era típica en los laboratorios de IA entre 2015 y 2018.

Por eso no dejé a Adam inmediatamente. Puede funcionar, pero es necesario convencerlo.

La conclusión clave no es "Adam trabaja en RL" o "Adam no funciona en RL", es que la optimización adaptativa funciona de manera diferente en RL que en el aprendizaje supervisado clásico, y "simplemente lanzar a Adam" fracasará.

No lo hagas. Piense en los valores predeterminados. Si ve algunas de las patologías que he mencionado, como picos inexplicables en su pérdida, mire directamente a su configuración de Adam.

La intuición detrás de la modificación de los valores predeterminados

Adam (y AdamW) se convirtieron en los predeterminados por una razón. Converge rápidamente en muchos problemas, normalmente no requiere ajuste y es (en su mayoría) indulgente en comparación con SGD.

Tu error no es usar a Adam. El error es utilizar a Adam con la suposición de que la optimización es un problema resuelto que no requiere reflexión.

Los valores predeterminados de Adán:

β1beta_1 : 0,9 β2beta_2 : 0,999 ϵepsilon : 1e-8

Se utilizan porque funcionan razonablemente bien en un amplio espectro de problemas de optimización. Como he expresado, esto puede llevar a un fracaso catastrófico e inexplicable.

Algunos de los síntomas de la “optimización patológica” que debes conocer (y las intuiciones asociadas):

¿Grandes picos de pérdidas inexplicables? Considere reducir β₂ (primero a 0,99, luego a 0,95 y luego posiblemente a menos). Esto acorta la memoria del segundo momento y permite que la estimación de la varianza reaccione más rápidamente. ¿Problemas altamente no estacionarios (especialmente RL)? Pruebe con un ϵepsilon más grande y un β2beta_2 más pequeño. El optimizador debería olvidar las estadísticas obsoletas más rápidamente. ¿Gradientes ruidosos? Aumente el recorte de gradiente antes de reducir la tasa de aprendizaje. A veces la inestabilidad no es la tasa de aprendizaje, sino la normalización adaptativa de Adam. ¿Mala generalización a pesar de una excelente pérdida de entrenamiento? Intente cambiar el optimizador. SGD y SGD+Momentum (Vanilla o Nesterov), a veces pueden superar a Adam. ¿Entrenar modelos enormes? Busque explosiones repentinas de normas de gradiente e investigue el estado del optimizador si aparecen. Probablemente v_t sea el culpable.

La trampa de PyTorch que probablemente te pierdas

Una nota también extraña que quizás (o no) conozcas.

Si usa PyTorch, Adam tiene un peso_decay=0 predeterminado, pero, si lo cambia por AdamW, el valor predeterminado es Weight_decay=0.01. Esto también fue bastante problemático para mí, ya que se asumiría que los valores predeterminados serían los mismos en todas las implementaciones del optimizador en la misma biblioteca.

Concluyendo

El optimizador no es sólo un breve punto en su guión de entrenamiento. Es la decisión principal, manejar cada actualización de peso en su modelo de mil millones de parámetros.

La próxima vez que encuentre picos de pérdidas inexplicables, aprendizaje por refuerzo inestable o un modelo que no convergerá a pesar de semanas de cambios arquitectónicos, no rediseñe inmediatamente la red.

Abra el optimizador. Inspeccionar los hiperparámetros Valores predeterminados de las preguntas Pensar críticamente (ahora armado con una mejor intuición)

Es posible que descubras, como lo hice yo después de quemar miles de horas de GPU, que el problema no era tu modelo en absoluto.

Eran tres pequeños números.

Referencias

[1]Kingma, DP y Ba, J. (2015). Adam: un método para la optimización estocástica. Conferencia Internacional sobre Representaciones del Aprendizaje (ICLR).

[2]Molybog, I., Denoyelle, N., Bakhtin, A., Sankararaman, KA, Sinha, A. y Goyal, G. (2023). Una teoría sobre la inestabilidad de Adam en el aprendizaje automático a gran escala. Preimpresión de arXiv arXiv:2304.09871.

[3]Reddi, SJ, Kale, S. y Kumar, S. (2018). Sobre la convergencia de Adán y más allá. Conferencia Internacional sobre Representaciones del Aprendizaje (ICLR).

[4]Castro, PS, Moitra, S., Gelada, C., Kumar, S. y Bellemare, MG (2018). Dopamina: un marco de investigación para el aprendizaje por refuerzo profundo. arXiv preimpresión arXiv:1812.06110.

[5]Tieleman, T. y Hinton, G. (2012). Conferencia 6.5-RMSProp: Divida el gradiente por un promedio móvil de su magnitud reciente. CURSERA: Redes neuronales para el aprendizaje automático, 4(2), 26–31.

[6]Wilson, AC, Roelofs, R., Stern, M., Srebro, N. y Recht, B. (2017). El valor marginal de los métodos de gradiente adaptativo en el aprendizaje automático. Avances en los sistemas de procesamiento de información neuronal (NeurIPS), 30.

[7]Zhang, J., He, T., Sra, S. y Jadbabaie, A. (2020). Por qué el recorte de gradiente acelera el entrenamiento: una justificación teórica de la adaptabilidad. Conferencia Internacional sobre Representaciones del Aprendizaje (ICLR).