Lección 14

Adam: el optimizador inteligente

SGD (descenso por gradiente) da el mismo tamaño de paso a todos los parámetros. Adam recuerda el historial de cada parámetro y ajusta el paso individualmente. El resultado: entrenamiento mucho más rápido y estable.

1. El ciclista en la montaña

Imagina un ciclista que baja por una montaña hacia el valle más profundo (el mínimo de pérdida). Tiene dos formas de decidir cuánto pedalear:

🚲 SGD — Sin memoria

Siempre pedalea con la misma fuerza, sin importar si lleva 10 km bajando por la misma pendiente o si acaba de doblar una curva empinada. El viento lateral lo hace zigzaguear.

🏎️ Adam — Con memoria

Lleva un mapa interno. Si lleva rato bajando en línea recta, acelera un poco. Si la pendiente cambia mucho en dirección impredecible, frena. Cada parámetro tiene su propio "piloto automático".

🏔️ Adam = SGD + dos memorias por parámetro. La primera memoria (m) guarda el promedio de los gradientes recientes — la "tendencia" actual. La segunda (v) guarda el promedio de los gradientes al cuadrado — cuán variable ha sido ese parámetro. Adam usa ambas para calcular un paso más inteligente.

2. Las dos memorias de Adam

Cada parámetro del modelo tiene sus propias dos memorias: m (momentum, tendencia del gradiente) y v (varianza, estabilidad del gradiente). Al principio ambas son cero.

✍️ Actualización de Adam — paso a paso
Parámetros de Adam en microgpt:
  β₁ = 0.85   ← peso de la memoria de tendencia (m)
  β₂ = 0.99   ← peso de la memoria de varianza (v)
  lr = 0.01   ← learning rate base
  ε  = 1e-8   ← número pequeño para evitar dividir por cero

─────────────────────────────────────────────────
Para un parámetro W con gradiente g:

PASO 1: Actualizar la tendencia (momentum)
  m = β₁ × m_anterior + (1 - β₁) × g

  Ejemplo, paso t=1, g = 0.5, m_anterior = 0:
  m = 0.85 × 0 + 0.15 × 0.5 = 0.075

PASO 2: Actualizar la varianza
  v = β₂ × v_anterior + (1 - β₂) × g²

  Ejemplo: v = 0.99 × 0 + 0.01 × 0.5² = 0.0025

PASO 3: Corrección de sesgo (bias correction)
  Al principio m y v son muy pequeños (empezaron en 0).
  Esta corrección los "agranda" hasta su valor real.

  m̂ = m / (1 - β₁^t) = 0.075 / (1 - 0.85¹) = 0.075 / 0.15 = 0.5
  v̂ = v / (1 - β₂^t) = 0.0025 / (1 - 0.99¹) = 0.0025 / 0.01 = 0.25

PASO 4: Actualizar el parámetro
  W = W - lr × m̂ / (√v̂ + ε)
  W = W - 0.01 × 0.5 / (√0.25 + 1e-8)
  W = W - 0.01 × 0.5 / (0.5 + 1e-8)
  W = W - 0.01    ← el paso fue exactamente lr

─────────────────────────────────────────────────
PASO t=2, mismo parámetro, g = 0.1 (gradiente más pequeño):

  m = 0.85 × 0.075 + 0.15 × 0.1 = 0.07875
  v = 0.99 × 0.0025 + 0.01 × 0.01 = 0.002575

  m̂ = 0.07875 / (1 - 0.85²) = 0.07875 / 0.2775 = 0.284
  v̂ = 0.002575 / (1 - 0.99²) = 0.002575 / 0.0199 = 0.129

  W = W - 0.01 × 0.284 / (√0.129 + ε)
  W = W - 0.01 × 0.284 / 0.359
  W = W - 0.0079    ← paso más pequeño porque el gradiente bajó
      

3. Por qué Adam supera a SGD

Comparación · SGD vs Adam en un paisaje de pérdida

El paisaje tiene una dirección "fácil" (horizontal, gradiente suave) y una "difícil" (vertical, gradiente ruidoso). SGD oscila lateralmente. Adam estabiliza la dirección difícil y avanza recto hacia el mínimo.

CaracterísticaSGDAdam
Paso por parámetroEl mismo para todosAdaptado a cada uno
Memoria por parámetro0 (ninguna)2 (m y v)
Oscilación en vallesAltaBaja (v la suaviza)
Parámetros rarosAprende lentom lo empuja, aprende
ConvergenciaLenta, requiere lr pequeñoRápida, lr más alto
Uso de memoriaBajo×3 (parámetros + m + v)

🎮 Pruébalo: Adam en acción

Observa cómo Adam actualiza un parámetro a lo largo de 20 pasos. Compara los dos: SGD da el mismo paso siempre, Adam lo adapta.

4. Lo que aprendiste

En esta lección:
  • SGD actualiza todos los parámetros con el mismo paso: W -= lr × grad. Simple pero ineficiente.
  • Adam mantiene dos buffers por parámetro: m (tendencia del gradiente) y v (varianza). Usa ambos para adaptar el paso individualmente.
  • La corrección de sesgo (dividir por 1 - β^t) compensa que m y v empiezan en cero, y son artificialmente pequeños al principio.
  • En microgpt: β₁=0.85, β₂=0.99, lr=0.01. Estos valores son razonables para un modelo pequeño; los GPTs grandes usan lr≈3e-4 con schedules.