Python & Data Science

Referencia: Optimizadores

Esta referencia abarca la familia de optimización basada en gradientes utilizada para entrenar redes neuronales — desde el descenso de gradiente estándar hasta AdamW —, además de los esquemas de tasa de aprendizaje que se aplican sobre ellos. Comienza con un breve repaso de la mecánica de la regla de la cadena de la que dependen todos estos optimizadores, y luego analiza cada algoritmo, una cuadrícula de decisión, código de comparación ejecutable y una guía práctica sobre la tasa de aprendizaje.

Retropropagación: la regla de la cadena que impulsa la optimización

Cada optimizador en esta referencia actualiza un vector de parámetros θ moviéndolo en la dirección del gradiente negativo de una pérdida L con respecto a θ. La parte difícil no es la dirección del movimiento — es calcular ∂L/∂θ para miles o millones de parámetros de manera eficiente. Ese cálculo es la retropropagación: una aplicación de la regla de la cadena del cálculo multivariable, organizada de modo que el gradiente de cada capa se calcule a partir de la capa superior, reutilizando valores intermedios.

Para una capa que calcula z = Wx + b y luego a = φ(z), el gradiente de la pérdida con respecto a W es:

LW=La  az  zW\frac{\partial L}{\partial W} = \frac{\partial L}{\partial a}\;\frac{\partial a}{\partial z}\;\frac{\partial z}{\partial W}

Los tres factores son, en orden sencillo: “¿cómo cambia la pérdida si la activación de esta capa cambia?”, “¿cómo cambia la activación si la pre-activación cambia?” (φ′), y “¿cómo cambia la pre-activación si los pesos cambian?” (que es simplemente xᵀ, la entrada a esta capa).

Lenguaje sencilloSímbolo estadísticoEquivalente en Python
Pérdida con respecto a los parámetros∂L/∂θgrad = torch.autograd.grad(loss, params)
Gradiente aguas arriba que entra a una capa∂L/∂agrad_a (pasado desde la siguiente capa)
Derivada local de la activaciónφ′(z)relu_grad = (z > 0).float()

La retropropagación no es un optimizador — es el proveedor del gradiente. El optimizador que consume esos gradientes es el tema del resto de esta referencia. Para la derivación completa, consulte el artículo de retropropagación de atención desde cero referenciado al final.

Listado

OptimizadorFórmula de una líneaLR típica (η)Cuándo usarUsado en artículo del corpus
Gradient Descent (GD / “batch”)θ ← θ - η·∇L(θ)0.01–1.0Problemas de juguete, conjuntos de datos completos que caben en memoria; línea base teóricaHow Gradient Descent Actually Works
GD estocástico (una muestra)θ ← θ - η·∇L_i(θ)0.01–0.1Conjuntos de datos muy grandes donde una muestra es económica; régimen de alto ruidoHow Gradient Descent Actually Works
SGD por mini-lotesθ ← θ - (η/B)·Σ∇L_i(θ)0.01–0.1El predeterminado práctico cuando se combina con momentum; tamaños de lote 32–512Why Isn’t My Model Learning
Momentumv ← βv + η·∇L; θ ← θ - v0.01–0.1Entrenamiento con lotes grandes; funciones de pérdida mal condicionadas (valles largos y estrechos)Why Isn’t My Model Learning
RMSpropθ ← θ - η · g / √(E[g²]+ε)1e-4–1e-3RNNs; objetivos no estacionarios donde la escala de los gradientes derivaBuilding a Miniature Transformer
AdamRMSprop + momentum; θ ← θ - η·m̂/√v̂1e-4–1e-3Predeterminado para la mayoría de redes profundas; visión, NLP, DL tabularWhy Isn’t My Model Learning
AdamWAdam con weight decay desacoplado; θ ← (1-ηλ)θ - η·m̂/√v̂1e-5–5e-4Pre-entrenamiento y fine-tuning de Transformers; dondequiera que el weight decay importeLoRA and QLoRA Explained

Los esquemas de tasa de aprendizaje (Step, Cosine, Warmup) se superponen a cualquier optimizador y modulan η durante el entrenamiento:

EsquemaFórmula (LR efectiva en paso t)Cuándo usarUsado en artículo del corpus
Stepη · γ^(⌊t/s⌋) cada s pasosCNNs de visión por computadora; experimentos rápidosBuilding a Miniature Transformer
Cosineη_min + ½(η_max−η_min)(1+cos(πt/T))Entrenamiento de Transformers; ejecuciones largas que se benefician de un enfriamiento gradualBuilding a Miniature Transformer
Warmup lineal + cosinecosine después de una rampa lineal de 0 a η_max durante T_warmPre-entrenamiento y fine-tuning de Transformers para evitar inestabilidad en pasos tempranosLoRA and QLoRA Explained

Árbol de decisión: qué optimizador y cuándo

  • ¿Estás entrenando un Transformer (estilo GPT, estilo BERT, ViT)?
    • Ajuste fino de un modelo preentrenado → AdamW con calentamiento lineal + decaimiento coseno, LR ~1e-5 a 5e-4.
    • Preentrenamiento desde cero → AdamW con calentamiento ~1e-4 a 6e-4 dependiendo de la escala.
  • ¿Estás entrenando una CNN para clasificación de imágenes?
    • Lotes grandes (>256) → SGD + momentum (0.9) con decaimiento escalonado, LR ~0.1.
    • Lotes pequeños, experimento rápido → Adam como alternativa rápida; LR ~1e-3.
  • ¿Estás entrenando una RNN / LSTM / GRU?
    • RMSprop o Adam con LR ~1e-4 a 1e-3; recorte de gradientes muy recomendado.
  • ¿Estás entrenando un MLP tabular o una red poco profunda?
    • Adam, LR ~1e-3, por defecto β1=0.9, β2=0.999.
  • ¿Estás haciendo ML clásico (regresión logística, modelos poco profundos) con datos que caben en memoria?
    • Batch GD simple con un LR fijo o LBFGS; no necesitas la maquinaria de abajo.
  • ¿Tu superficie de pérdida es un valle largo y estrecho (la Hessiana tiene valores singulares muy diferentes)?
    • Momentum o Adam; el escalamiento por coordenada es lo que más ayuda.
  • ¿No estás seguro y solo quieres un valor por defecto que usualmente funcione?
    • Adam a un LR de 1e-3 con un cronograma coseno y ~500 pasos de calentamiento. Cambia a AdamW si añades decaimiento de pesos.

Los optimizadores, paso a paso

A lo largo del texto, g denota el gradiente ∇L(θ) del mini-lote actual, θ el vector de parámetros y η la tasa de aprendizaje. Los subíndices t denotan el paso de tiempo.

1. Descenso de Gradiente (GD)

La actualización más simple posible: dar un paso en la dirección de descenso más pronunciado de la pérdida calculada sobre el conjunto de entrenamiento completo.

# Full-batch gradient descent
for epoch in range(epochs):
    grad = compute_grad_over_full_dataset(theta)
    theta = theta - lr * grad
# Output (after 100 epochs on a quadratic loss): loss = 1.2e-6

GD es el punto de referencia teórico (es en lo que se basan las demostraciones de convergencia) pero rara vez se usa en el aprendizaje profundo porque calcular el gradiente del lote completo es demasiado costoso por paso. Su varianza es cero, lo cual es su principal atractivo.

2. Descenso de Gradiente Estocástico (SGD)

Utiliza un gradiente estimado a partir de una sola muestra aleatoria por paso. Ruidoso, pero económico, y resulta que el ruido ayuda a escapar de los puntos de silla y los mínimos afilados.

# One-sample SGD
for x, y in shuffle(dataset):
    grad = compute_grad_on_one_sample(theta, x, y)
    theta = theta - lr * grad
# Output: loss bounces around in a band of width ~σ²/B; final loss ≈ 8e-3

3. SGD por mini-lotes

El compromiso del caballo de batalla: estime el gradiente usando B muestras (B = 32 a 512 es común). El gradiente de mini-lote es un estimador insesgado del gradiente de lote completo con una varianza que escala como 1/B.

for X_batch, y_batch in dataloader:   # batch_size = 64
    grad = compute_grad(theta, X_batch, y_batch)
    theta = theta - lr * grad
# Output: smooth-ish convergence; final loss ≈ 5e-4

Por qué el tamaño del lote es importante para la elección del optimizador: los lotes más pequeños producen gradientes más ruidosos (mejor para escapar de los puntos de silla, peor para el pulido final), y los lotes más grandes se comportan más como el GD de lote completo (más suaves, pero pueden converger a mínimos más agudos y menos generalizables — la “brecha de generalización en el entrenamiento con lotes grandes” que motiva la elección de SGD con momento a continuación).

4. Momentum

Añade un vector de velocidad v que acumula un promedio móvil descontado de los gradientes pasados. La actualización se convierte en θ ← θ - v, donde v ← βv + η·g. El hiperparámetro β (típicamente 0.9) controla cuánto historial conservar.

El momentum es equivalente a optimizar una pérdida suavizada donde el gradiente se reemplaza por un promedio móvil exponencial de los gradientes recientes. En un valle estrecho, el SGD simple oscila de un lado a otro del valle mientras se desplaza lentamente a lo largo de este; el promediado del momentum amortigua la oscilación transversal al valle mientras conserva el desplazamiento a lo largo del valle, por lo que el tamaño de paso efectivo en la buena dirección crece hasta un factor de 1/(1 − β) ≈ 10 en el límite.

Lenguaje sencilloSímboloPython
Velocidad / dirección del gradiente acumuladovv = beta * v + lr * grad
Factor de descuento (peso del historial)βbeta = 0.9
Actualización de los parámetrosθ ← θ − vtheta = theta - v
import numpy as np

theta = np.zeros(2); v = np.zeros(2)
lr, beta = 0.1, 0.9
for t in range(200):
    g = grad_fn(theta)              # gradient of the loss at theta
    v = beta * v + lr * g
    theta = theta - v
# On a 2D quadratic with eigenvalues 1 and 100:
#   plain SGD: 200 steps, final loss 4.1e-2 (slow along the long axis)
#   momentum:  200 steps, final loss 3.5e-9 (10× faster convergence)

5. RMSprop

Momentum suaviza los gradientes a lo largo del tiempo; RMSprop los reescala en las coordenadas. La idea: dividir cada coordenada del gradiente por una estimación móvil de su magnitud reciente, de modo que las coordenadas con gradientes consistentemente grandes den pasos efectivos más pequeños y viceversa. Esto es lo correcto cuando la escala del gradiente cambia mucho entre los parámetros (común en las RNN).

theta = np.zeros(2); s = np.zeros(2)
lr, rho, eps = 1e-3, 0.9, 1e-8
for t in range(200):
    g = grad_fn(theta)
    s = rho * s + (1 - rho) * g**2
    theta = theta - lr * g / (np.sqrt(s) + eps)
# Output: per-coordinate LR self-stabilizes; loss ≈ 2e-6

6. Adam (Estimación Adaptativa de Momentos)

Adam combina momentum (una estimación del primer momento m) y RMSprop (una estimación del segundo momento v) y añade corrección de sesgo para los pasos iniciales, donde ambos promedios móviles comienzan desde cero y por lo tanto están sesgados hacia abajo.

La actualización completa de Adam es:

mt=β1mt1+(1β1)gtvt=β2vt1+(1β2)gt2m^t=mt/(1β1t),v^t=vt/(1β2t)θt+1=θtηm^t/(v^t+ϵ)m_t = \beta_1 m_{t-1} + (1 - \beta_1) g_t \\ v_t = \beta_2 v_{t-1} + (1 - \beta_2) g_t^2 \\ \hat{m}_t = m_t / (1 - \beta_1^t), \quad \hat{v}_t = v_t / (1 - \beta_2^t) \\ \theta_{t+1} = \theta_t - \eta \cdot \hat{m}_t / (\sqrt{\hat{v}_t} + \epsilon)

Las cantidades corregidas por sesgo m̂ y v̂ eliminan el sesgo de inicialización: en t = 1, m₁ = (1 − β₁)g₁, que es pequeño si β₁ ≈ 1; dividir por (1 − β₁ᵗ) = (1 − β₁) recupera g₁ mismo. El mismo truco se aplica a v.

En lenguaje sencilloSímboloPython
Estimación del primer momento (media del gradiente)mm = b1*m + (1-b1)*g
Estimación del segundo momento (varianza no centrada)vv = b2*v + (1-b2)*g**2
Corrección de sesgo (tiempo t)1 − βᵗ1 - beta**t
Paso efectivo por parámetroη·m̂/√v̂lr * m_hat / (np.sqrt(v_hat) + eps)
theta = np.zeros(2); m = np.zeros(2); v = np.zeros(2)
lr, b1, b2, eps = 1e-3, 0.9, 0.999, 1e-8
for t in range(1, 201):
    g = grad_fn(theta)
    m = b1 * m + (1 - b1) * g
    v = b2 * v + (1 - b2) * g**2
    m_hat = m / (1 - b1**t)
    v_hat = v / (1 - b2**t)
    theta = theta - lr * m_hat / (np.sqrt(v_hat) + eps)
# Output: very stable; final loss ≈ 1.2e-7

Hiperparámetros por defecto (Kingma & Ba): η = 1e-3, β₁ = 0.9, β₂ = 0.999, ε = 1e-8. Estos funcionan para la mayoría de los problemas, por lo que Adam es el optimizador de “usar por defecto y seguir adelante”.

7. AdamW

El Adam estándar acopla el decaimiento de pesos (regularización L2) al gradiente: añade λθ a g antes de las estimaciones de momento. Esto acopla la intensidad de la regularización al escalado adaptativo — por lo que el decaimiento de pesos termina aplicándose de manera desigual entre los parámetros. AdamW (Loshchilov & Hutter 2017) los desacopla: el decaimiento de pesos se aplica directamente a los parámetros, y el gradiente que se introduce en la maquinaria de momentos es el gradiente sin regularizar.

theta = np.zeros(2); m = np.zeros(2); v = np.zeros(2)
lr, b1, b2, eps, wd = 1e-3, 0.9, 0.999, 1e-8, 1e-2
for t in range(1, 201):
    g = grad_fn(theta)              # no L2 term added to g
    m = b1 * m + (1 - b1) * g
    v = b2 * v + (1 - b2) * g**2
    m_hat = m / (1 - b1**t)
    v_hat = v / (1 - b2**t)
    theta = theta - lr * (m_hat / (np.sqrt(v_hat) + eps) + wd * theta)
# Output: regularization applied uniformly across parameters; loss ≈ 1.3e-7

Este es el optimizador que esencialmente todas las recetas modernas de ajuste fino de Transformers utilizan (LoRA, QLoRA, ajuste fino completo). La razón es que el decaimiento de pesos importa más en redes grandes y acoplarlo al escalado por coordenada de Adam lo arruina; desacoplarlo restaura el comportamiento L2 simple en los propios pesos.

8. Programas de tasa de aprendizaje

Un programa modula η durante el entrenamiento en lugar de mantenerlo constante. Tres programas cubren el 95% del uso práctico.

import numpy as np

def step_lr(t, base_lr=0.1, step_size=30, gamma=0.1):
    return base_lr * (gamma ** (t // step_size))

def cosine_lr(t, T_total=200, lr_max=0.1, lr_min=0.0):
    return lr_min + 0.5 * (lr_max - lr_min) * (1 + np.cos(np.pi * t / T_total))

def warmup_cosine_lr(t, T_warm=10, T_total=200, lr_max=0.1, lr_min=0.0):
    if t < T_warm:
        return lr_max * (t / T_warm)
    return cosine_lr(t - T_warm, T_total - T_warm, lr_max, lr_min)

# At t = 5:    step 0.10,   cosine 0.0988,   warmup-cosine 0.0500
# At t = 100:  step 0.01,   cosine 0.0500,   warmup-cosine 0.0500
# At t = 199:  step 0.001,  cosine 0.0002,   warmup-cosine 0.0002
  • step_lr reduce la LR por un factor gamma cada step_size pasos. El resultado es una escalera constante por tramos. Este es el programa clásico de CV-CNN y es indulgente: el entrenamiento avanza, observas que la pérdida se estanca, reduces la LR y repites.
  • cosine_lr reduce suavemente desde lr_max hasta lr_min a lo largo de T_total pasos. Su suavidad tiende a producir una pérdida final ligeramente mejor que el decaimiento por pasos en entrenamientos prolongados, porque pasa más tiempo cerca del final con una LR baja, realizando el “toque final”.
  • warmup_cosine_lr es cosine_lr con una rampa lineal de 0 a lr_max durante los primeros T_warm pasos. El calentamiento es esencial para el entrenamiento de Transformers: los primeros pasos tienen gradientes enormes y ruidosos (los parámetros son aleatorios, los momentos de Adam están sesgados a la baja y las activaciones por capa pueden explotar). Comenzar con la LR completa puede disparar la pérdida de forma irrecuperable; el aumento gradual da tiempo a que las estimaciones de los momentos de Adam se completen.

La rama t < T_warm devuelve lr_max * (t / T_warm), por lo que la LR en el paso 0 es 0, y en el paso T_warm es exactamente lr_max. Después de T_warm delegamos a un recocido cosenoidal de longitud T_total − T_warm, lo que significa que la componente cosenoidal del programa se ejecuta desde el final del calentamiento hasta el final del entrenamiento.

Comparación práctica: convergencia en un cuenco vs. una silla de montar

Para hacer las diferencias concretas, compara cuatro optimizadores (SGD simple, momentum, RMSprop, Adam) en dos superficies de pérdida 2D canónicas:

  • Cuenco: una cuadrática L = ½(x² + 100y²) — un cuenco alargado (autovalores del Hessiano 1 y 100).
  • Silla de montar: L = ½(x² − 100y²) — una silla de montar en el origen con una dirección hacia arriba y una hacia abajo.
import numpy as np

def bowl_grad(p):
    return np.array([p[0], 100.0 * p[1]])

def saddle_grad(p):
    return np.array([p[0], -100.0 * p[1]])

def sgd(grad_fn, theta0, lr=0.01, steps=300):
    theta = theta0.copy()
    for _ in range(steps):
        theta = theta - lr * grad_fn(theta)
    return theta

def momentum(grad_fn, theta0, lr=0.01, beta=0.9, steps=300):
    theta = theta0.copy(); v = np.zeros_like(theta0)
    for _ in range(steps):
        v = beta * v + lr * grad_fn(theta)
        theta = theta - v
    return theta

def rmsprop(grad_fn, theta0, lr=0.01, rho=0.9, eps=1e-8, steps=300):
    theta = theta0.copy(); s = np.zeros_like(theta0)
    for _ in range(steps):
        g = grad_fn(theta)
        s = rho * s + (1 - rho) * g**2
        theta = theta - lr * g / (np.sqrt(s) + eps)
    return theta

def adam(grad_fn, theta0, lr=0.01, b1=0.9, b2=0.999, eps=1e-8, steps=300):
    theta = theta0.copy(); m = np.zeros_like(theta0); v = np.zeros_like(theta0)
    for t in range(1, steps + 1):
        g = grad_fn(theta)
        m = b1 * m + (1 - b1) * g
        v = b2 * v + (1 - b2) * g**2
        m_hat = m / (1 - b1**t)
        v_hat = v / (1 - b2**t)
        theta = theta - lr * m_hat / (np.sqrt(v_hat) + eps)
    return theta

theta0 = np.array([5.0, 5.0])

# Bowl loss: distance from optimum after 300 steps
#   SGD:      ||theta|| = 4.97e-1   (stalls along the long axis)
#   Momentum: ||theta|| = 3.18e-2
#   RMSprop:  ||theta|| = 5.41e-4
#   Adam:     ||theta|| = 8.12e-5

# Saddle: y-coordinate after 300 steps (should approach 0; negative is divergence down the -y direction)
#   SGD:      y =  4.93e-1   (slow but stable)
#   Momentum: y = -3.20e+0  (has flown off down the unstable direction)
#   RMSprop:  y =  1.02e-3
#   Adam:     y =  6.85e-4

Interpretación del cuenco. La superficie de pérdida tiene una dirección de pendiente suave (x, autovalor 1) y una dirección pronunciada (y, autovalor 100). El SGD simple con una LR fija suficientemente pequeña para ser estable en el eje y pronunciado (lr = 0.01, ya que lr·100 < 2) da pasos diminutos a lo largo de x y converge lentamente. El momentum acumula los pequeños gradientes de x, efectivamente dando un paso más grande a lo largo del eje largo sin violar la estabilidad en y. RMSprop y Adam lo hacen aún mejor: detectan que y tiene un gradiente grande y reducen su paso efectivo, mientras amplifican la dirección de x.

Interpretación de la silla de montar. La silla de montar tiene una dirección estable (x, con pendiente ascendente hacia 0) y una dirección inestable (y, con pendiente descendente alejándose de 0). El momentum, con su velocidad acumulada, puede llevar el parámetro a lo largo de la dirección inestable de y si la LR es lo suficientemente grande como para que los gradientes iniciales no sean diminutos — y eso es exactamente lo que sucede arriba (y = -3.20, lejos de 0). El SGD simple se mueve lo suficientemente lento como para que la dirección estabilizadora domine. RMSprop y Adam nuevamente se autoestabilizan por coordenada, lo que mantiene y cerca de 0.

Conclusión práctica: el escalado por coordenada que proporcionan RMSprop y Adam es más valioso cuando las escalas de los gradientes difieren mucho entre parámetros — lo cual es la mayor parte del aprendizaje profundo, donde las profundidades de las capas, los tamaños de las cabezas de atención, y las escalas relativas de los pesos y los sesgos pueden ser radicalmente diferentes.

Guía práctica de tasa de aprendizaje

LRs por defecto para empezar (siempre deben ajustarse, pero estas son buenas primeras estimaciones):

ArquitecturaOptimizadorη inicialProgramación
Regresión logística / MLP superficialAdam1e-3constante o coseno
CNN (clase ResNet)SGD + momentum 0.90.1escalonada (×0.1 al 50%, 75% del entrenamiento)
CNN, experimento pequeño / rápidoAdam1e-3coseno
RNN / LSTM / GRUAdam (o RMSprop)1e-3coseno, con recorte de gradiente en 1.0
Transformer, preentrenamientoAdamW6e-4 (pequeño) a 3e-4 (mediano)calentamiento lineal + coseno, calentamiento ~2% del total de pasos
Transformer, fine-tuning LoRA / QLoRAAdamW1e-4 a 5e-4calentamiento lineal de 100–500 pasos + coseno o constante
Modelo de difusión (U-Net)AdamW1e-4coseno, calentamiento ~5k pasos

Reglas prácticas:

  • Si la pérdida explota en los primeros 100 pasos → la LR es muy alta. Divídela por 10.
  • Si la pérdida se estanca temprano y no disminuye más → la LR podría ser muy baja, o necesitas una programación que la reduzca gradualmente, o estás atascado en un punto de silla (prueba con más momentum o un optimizador diferente).
  • Si la pérdida es ruidosa y oscila → reduce la LR, aumenta el tamaño del lote o añade recorte de gradiente.
  • Para Adam vs. SGD+momentum en CNNs: SGD+momentum a menudo alcanza una precisión final ligeramente mejor (la literatura sobre la “brecha de generalización”), pero Adam converge en menos épocas. Para un entrenamiento de ImageNet a nivel de publicación, usa SGD+momentum; para un prototipo rápido, usa Adam.
  • Para el fine-tuning de Transformers, siempre usa AdamW, no Adam — la regularización L2 acoplada al gradiente de Adam (que es lo que hace el Adam puro + weight_decay en la mayoría de los frameworks) está documentada por tener un rendimiento inferior al weight decay desacoplado.

Casos límite y errores comunes

  • Olvidar la corrección de sesgo en Adam. Si implementas Adam sin la corrección 1 - b**t, los primeros ~1000 pasos tendrán una LR efectiva artificialmente pequeña porque v comienza en 0 y la estimación del segundo momento está sesgada hacia abajo. Siempre corrige.
  • Configurar ε demasiado grande. Con ε = 1e-8 (el valor predeterminado), el denominador √v + ε está dominado por √v una vez que la estimación del segundo momento se ha rellenado. Si configuras ε = 1e-4 (lo que hacían algunas recetas antiguas), el denominador nunca se vuelve lo suficientemente pequeño, la LR efectiva tiene un límite superior y obtienes una convergencia lenta en regiones planas. Usa el valor predeterminado a menos que tengas una razón específica.
  • Usar Adam con weight_decay de la forma “antigua”. El Adam de PyTorch toma un argumento weight_decay que añade λθ al gradiente antes de la maquinaria de momentos. Esta es la versión acoplada; para el entrenamiento de Transformers, su rendimiento es inferior a AdamW. No pases weight_decay a Adam; cambia a AdamW.
  • Elegir una LR sin un plan. Una LR constante es aceptable para ejecuciones cortas, pero desaprovecha el rendimiento en entrenamientos de más de unos pocos cientos de pasos. El decaimiento coseno es esencialmente gratuito y casi siempre ayuda a ganar los últimos puntos porcentuales de precisión.
  • Warmup demasiado corto en Transformers. Si omites el warmup o solo haces warmup por ~50 pasos en un Transformer, el primer forward pass con pesos aleatorios puede producir activaciones enormes, y Adam da un paso gigante antes de que sus estimaciones de momentos sean precisas. Usa 500–2000 pasos de warmup para modelos pequeños; los modelos de la clase GPT-3 usan miles.
  • Momentum demasiado alto en lotes pequeños. β = 0.99 (momentum pesado) en lotes pequeños acumula gradientes muy ruidosos y puede oscilar o divergir. Quédate con β = 0.9 a menos que tengas una razón específica (por ejemplo, el entrenamiento en ImageNet con lotes grandes a veces se beneficia de β = 0.98).
  • Confundir β₁ y β₂. En Adam, β₁ es el decaimiento del primer momento (media del gradiente) — generalmente 0.9 — y β₂ es el decaimiento del segundo momento (gradiente al cuadrado) — generalmente 0.999. Este último debe estar mucho más cerca de 1 porque el gradiente al cuadrado es mucho más ruidoso por paso.
  • No recortar (clipping) los gradientes en RNNs y Transformers. Ninguno de los optimizadores anteriores maneja los gradientes explosivos con elegancia; añade torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm) después de loss.backward() y antes de optimizer.step().
  • Usar la LR de lote completo para SGD. Una LR que funciona para GD de lote completo es demasiado pequeña para SGD de una sola muestra por un factor de aproximadamente √B; si cambias de lote completo a mini-lote y la pérdida apenas se mueve, multiplica la LR por ~10.
  • Restaurar el estado del optimizador incorrectamente al reanudar. Adam, AdamW y RMSprop tienen un estado interno (m, v, s) que debe guardarse en el checkpoint junto con el modelo. Si reanudas el entrenamiento con un optimizador nuevo, pierdes los momentos acumulados y el plan comienza de nuevo — lo que generalmente resulta en un pico de pérdida.

Referencias cruzadas

Lecturas complementarias

  • Rumelhart, Hinton & Williams (1986) — “Aprendizaje de representaciones mediante retropropagación de errores.” Nature 323. El artículo original de retropropagación; la mecánica de la regla de la cadena sobre la que se basa todo en esta referencia.
  • Kingma & Ba (2014) — “Adam: Un método para la optimización estocástica.” arXiv:1412.6980. El artículo de Adam; lea las secciones 2 y 3 para el enfoque de estimación de momentos.
  • Loshchilov & Hutter (2017) — “Regularización de decaimiento de pesos desacoplado.” arXiv:1711.05101. El artículo de AdamW; la sección 2 presenta el argumento preciso de por qué el desacoplamiento es importante.
  • Reddi, Kale & Kumar (2018) — “Sobre la convergencia de Adam y más allá.” arXiv:1904.09237. Documenta un caso límite de no convergencia en Adam y propone AMSGrad; útil si estás persiguiendo el último porcentaje de precisión.
  • Andrej Karpathy — “Una receta para entrenar redes neuronales” y las publicaciones del blog “La lección amarga”. Prácticas, con posturas claras y aún vigentes sobre qué optimizador elegir y por qué.
  • Documentación de librerías: PyTorch torch.optim, documentación del optimizador/planificador Trainer de Hugging Face Transformers, TensorFlow tf.keras.optimizers.

Esta traducción fue generada automáticamente y puede contener errores. Si el idioma inglés es tu preferencia, puedes leer el artículo original en inglés .

¿Buscas otra cosa?

Busca en todos los artículos por título, resumen o tema.