09

Entrenar bien: lotes, épocas y optimizadores

¿Qué decisiones de entrenamiento separan una red que aprende de una que no?

12 min

Entrenar bien: lotes, épocas y optimizadores

Con voz. Puedes pausar y saltar a cualquier paso.

Lección completa

Subtítulos

En la lección ocho corregimos los pesos con un solo ejemplo. Un modelo real aprende de millones. ¿Cuántos ejemplos conviene mirar antes de dar cada paso?

Voz

Sin voz: la lección avanza sola con subtítulos.

La voz de esta lección está en preparación: por ahora avanza sola con subtítulos.

0:00 / 0:00

Qué lograrás

  • Explicar qué es un lote y por qué se entrena con lotes al azar en lugar de usar todos los ejemplos, y calcular cuántos pasos tiene una época.
  • Distinguir qué hace cada optimizador (SGD, momento y Adam) y por qué cada uno necesita su propia tasa de aprendizaje.
  • Predecir qué hacen el calentamiento y el decaimiento de la tasa, y reconocer qué ajustes son hiperparámetros.

Ideas clave

  1. Con muchos ejemplos no se calcula la pendiente con todos: se estima con un lote al azar (en la lección, 8 de 256). Su flecha sale algo desviada, pero en promedio apunta bien. Eso es el descenso del gradiente estocástico (SGD).
  2. Una época es un recorrido completo por los datos: con N ejemplos y lotes de B, tiene N/B pasos (256 / 8 = 32). Con el mismo trabajo, un lote chico da muchos pasos baratos y ruidosos, y uno grande, pocos pasos exactos; lo mejor suele quedar en medio.
  3. El optimizador convierte la pendiente en un paso. SGD la usa tal cual; el momento suma inercia; Adam además da a cada peso su propio tamaño de paso. Cada uno pide su propia tasa.
  4. La tasa puede cambiar durante el entrenamiento: un calentamiento al inicio evita el salto que lanza el modelo lejos, y un decaimiento al final calma el temblor para que se asiente en el fondo.
  5. Tamaño del lote, tasa, optimizador y calendario son hiperparámetros: los elige una persona, no se aprenden con gradientes, y probarlos cuesta entrenamientos completos.

Lo que mucha gente cree

Creencia común Cuanto más grande el lote, mejor: el gradiente es más exacto, así que se aprende más.

Lo correcto Más exacto no es más eficiente. Con el mismo presupuesto de ejemplos, un lote grande da menos pasos. Y los lotes muy grandes piden reajustar la tasa y calentar para no perder calidad.

Compruébalo

Cuatro preguntas. Sin nota ni cuenta: sirven para ver si la idea quedó.

Concepto¿Por qué sirve entrenar con lotes en lugar de usar todos los ejemplos en cada paso?
CálculoUn conjunto tiene 10 000 ejemplos y se entrena con lotes de 250 durante 3 épocas. ¿Cuántos pasos de actualización se dan en total?
Concepto¿Qué hace Adam además de llevar un momento?
AplicaciónUn equipo duplica el lote y también la tasa, como se recomienda al escalar, pero el error se dispara en los primeros pasos. ¿Qué conviene probar primero?

Por dentroPara quien quiere las fórmulas y el código. No hace falta para seguir el curso.

El gradiente de un lote

Con NN ejemplos y un error por ejemplo ℓi(w)\ell_i(\mathbf{w}), el error total es L(w)=1N∑iℓi(w)L(\mathbf{w})=\tfrac1N\sum_i \ell_i(\mathbf{w}). Un lote B\mathcal{B} de BB ejemplos elegidos al azar da el gradiente aproximado

gB=1B∑i∈B∇ℓi(w),E[gB]=∇L(w)\mathbf{g}_B=\frac1B\sum_{i\in\mathcal{B}}\nabla\ell_i(\mathbf{w}),\qquad \mathbb{E}[\mathbf{g}_B]=\nabla L(\mathbf{w})

Es un estimador sin sesgo. Su varianza es N−BN−1 σ2B\frac{N-B}{N-1}\,\frac{\sigma^2}{B}, con σ2\sigma^2 la varianza del gradiente de un ejemplo: el error cae como 1/B1/\sqrt{B}, mientras que el costo del paso crece como BB. Por eso, para reducir el ruido a la mitad hace falta un lote unas cuatro veces mayor. En la lección, el desvío medio de la flecha (medido con 24 lotes de cada tamaño) fue de 20 %, 10 %, 4 % y 1.7 % con lotes de 2, 8, 32 y 128: cae algo más rápido que 1/B1/\sqrt{B} porque el factor N−BN−1\frac{N-B}{N-1} pesa cuando el lote es una parte grande de los 256 ejemplos. Una época tiene ⌈N/B⌉\lceil N/B\rceil pasos y tras tt pasos se han visto tBtB ejemplos. La idea de actualizar con ruido viene de Robbins y Monro (1951).

Cerca de un mínimo con curvatura hh, el ruido del gradiente (varianza s2=σ2/Bs^2=\sigma^2/B) deja un suelo de error: E[L]≈η s2/4\mathbb{E}[L]\approx \eta\,s^2/4 cuando ηh≪1\eta h\ll 1. Es proporcional a η/B\eta/B: bajar la tasa o subir el lote lo baja. Por eso el decaimiento de la tasa ayuda a asentarse.

Momento

vt+1=β vt+gt,wt+1=wt−η vt+1\mathbf{v}_{t+1}=\beta\,\mathbf{v}_t+\mathbf{g}_t,\qquad \mathbf{w}_{t+1}=\mathbf{w}_t-\eta\,\mathbf{v}_{t+1}

Con β=0.9\beta=0.9 y un gradiente constante, v→g/(1−β)\mathbf{v}\to \mathbf{g}/(1-\beta): el paso efectivo es diez veces mayor; a igual paso efectivo, la tasa del momento sería unas diez veces menor que la de SGD (en la práctica la razón es menor: en el cañón de la lección, 0.02 frente a 0.07). En un cuadrático con curvaturas λmin⁡≤h≤λmax⁡\lambda_{\min}\le h\le\lambda_{\max} y número de condición κ=λmax⁡/λmin⁡\kappa=\lambda_{\max}/\lambda_{\min}, la mejor tasa fija de SGD reduce la distancia al fondo por paso en un factor κ−1κ+1\frac{\kappa-1}{\kappa+1}, y el momento bien ajustado en κ−1κ+1\frac{\sqrt\kappa-1}{\sqrt\kappa+1} (Polyak, 1964). En el cañón de la lección, cerca del fondo, κ≈50\kappa\approx 50: unos 0.960.96 por paso frente a 0.750.75 (en teoría, sin ruido).

Adam

mt=β1mt−1+(1−β1)gt,st=β2st−1+(1−β2) gt2\mathbf{m}_t=\beta_1\mathbf{m}_{t-1}+(1-\beta_1)\mathbf{g}_t,\qquad \mathbf{s}_t=\beta_2\mathbf{s}_{t-1}+(1-\beta_2)\,\mathbf{g}_t^{2}
m^t=mt1−β1 t,s^t=st1−β2 t,wt=wt−1−η m^ts^t+ε\hat{\mathbf{m}}_t=\frac{\mathbf{m}_t}{1-\beta_1^{\,t}},\quad \hat{\mathbf{s}}_t=\frac{\mathbf{s}_t}{1-\beta_2^{\,t}},\qquad \mathbf{w}_t=\mathbf{w}_{t-1}-\eta\,\frac{\hat{\mathbf{m}}_t}{\sqrt{\hat{\mathbf{s}}_t}+\varepsilon}

Todo es por peso (el cuadrado y la raíz actúan componente a componente). Los valores por defecto de Kingma y Ba (2015) son η=0.001\eta=0.001, β1=0.9\beta_1=0.9, β2=0.999\beta_2=0.999 y ε=10−8\varepsilon=10^{-8}. Las correcciones de sesgo compensan que m\mathbf{m} y s\mathbf{s} empiezan en cero. En el primer paso m^/s^=signo⁡(g)\hat{\mathbf{m}}/\sqrt{\hat{\mathbf{s}}}=\operatorname{signo}(\mathbf{g}), así que cada peso se mueve η\eta; en régimen normal el paso de cada peso es del orden de η\eta como máximo. Dos consecuencias: el método es invariante al reescalar cada gradiente por separado (lo dicen sus autores), y cerca de un óptimo la señal frente al ruido baja y los pasos se encogen solos, un «recocido automático» según Kingma y Ba. Con gradientes de lotes ruidosos eso no basta: en la simulación de la lección, con η\eta constante el camino sigue sacudiéndose alrededor del fondo, con una amplitud que crece con η\eta, y bajar η\eta al final lo calma.

Calendarios de la tasa

ηt=ηmax⁡min⁡ ⁣(1,t+1Tw)(calentamiento lineal)\eta_t=\eta_{\max}\min\!\Big(1,\frac{t+1}{T_w}\Big)\quad\text{(calentamiento lineal)}
ηt=ηmin⁡+12(ηmax⁡−ηmin⁡)(1+cos⁡π t−TwT−Tw)(decaimiento coseno, de Loshchilov y Hutter, 2017)\eta_t=\eta_{\min}+\tfrac12(\eta_{\max}-\eta_{\min})\Big(1+\cos\pi\,\frac{t-T_w}{T-T_w}\Big)\quad\text{(decaimiento coseno, de Loshchilov y Hutter, 2017)}

Dos recetas reales: el transformer original (Vaswani et al., 2017) usó Adam con β2=0.98\beta_2=0.98 y calentó durante 4000 pasos; GPT-3 (Brown et al., 2020) usó Adam con β2=0.95\beta_2=0.95, calentamiento lineal durante los primeros 375 millones de tokens y decaimiento coseno hasta el 10 % del valor máximo a lo largo de 260 mil millones de tokens. Además, su lote creció de 32 mil tokens hasta el valor final (3.2 millones en el modelo de 175 mil millones de parámetros) durante los primeros 4 a 12 mil millones de tokens, según el tamaño del modelo, y de su texto del rastreo web vio solo 0.44 épocas (tabla 2.2). Al aumentar el lote, Goyal et al. (2017) proponen multiplicar la tasa por el mismo factor y calentar: con esa regla entrenaron ResNet-50 con lotes de 8192 imágenes en 256 GPU, en una hora, sin pérdida de exactitud.

Hiperparámetros

Los pesos w\mathbf{w} se aprenden con ∇L\nabla L; los hiperparámetros (η\eta, BB, β\beta, TwT_w, el optimizador…) fijan cómo se aprende y no tienen gradiente a su alcance. Se eligen probando: en espacios de varias dimensiones, probar combinaciones al azar suele rendir más por prueba que recorrer una cuadrícula (Bergstra y Bengio, 2012).

En código

import math

# Ocho ejemplos fijos de y ≈ 2x + 1. Los lotes se toman en orden para que el
# resultado sea reproducible (en la práctica se baraja en cada época).
X = [0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5]
Y = [1.2, 1.8, 3.1, 4.1, 4.9, 6.2, 6.9, 8.1]

def grad(w, b, idx):                       # gradiente del error cuadrático medio del lote
    n = len(idx)
    gw = sum(2 * (w * X[i] + b - Y[i]) * X[i] for i in idx) / n
    gb = sum(2 * (w * X[i] + b - Y[i]) for i in idx) / n
    return [gw, gb]

def entrenar(opt, eta, B, epocas, beta=0.9, b1=0.9, b2=0.999, eps=1e-8):
    p = [0.0, 0.0]                         # pesos: w y b
    v = [0.0, 0.0]; m = [0.0, 0.0]; s = [0.0, 0.0]; t = 0
    for _ in range(epocas):                # una época = recorrer todos los lotes
        for ini in range(0, len(X), B):
            g = grad(p[0], p[1], range(ini, min(ini + B, len(X))))
            t += 1
            if opt == "sgd":
                paso = [eta * gi for gi in g]
            elif opt == "momento":
                v = [beta * vi + gi for vi, gi in zip(v, g)]
                paso = [eta * vi for vi in v]
            else:                          # Adam
                m = [b1 * mi + (1 - b1) * gi for mi, gi in zip(m, g)]
                s = [b2 * si + (1 - b2) * gi * gi for si, gi in zip(s, g)]
                paso = [eta * (mi / (1 - b1 ** t)) / (math.sqrt(si / (1 - b2 ** t)) + eps)
                        for mi, si in zip(m, s)]
            p = [pi - di for pi, di in zip(p, paso)]
    return [round(pi, 3) for pi in p]

# la solución exacta de mínimos cuadrados es [1.998, 1.042]
for opt, eta in [("sgd", 0.05), ("momento", 0.005), ("adam", 0.3)]:
    print(opt, entrenar(opt, eta, B=4, epocas=50))
# sgd [1.999, 1.033]
# momento [2.008, 1.043]
# adam [1.993, 1.028]

En un problema tan pequeño y bien condicionado, SGD ya basta: las diferencias aparecen en paisajes como el cañón, y cada optimizador necesitó su propia tasa.

Lo que viene

Bajar el error de entrenamiento no basta: hay que medir con datos que el modelo no vio. De eso trata la lección 10 (generalizar y evaluar), que añade la parada temprana y el decaimiento de pesos como formas de regularizar.

Lente de decisión

Qué significa esta idea si tu trabajo es decidir, no programar.

  • «Entrenamos con la configuración por defecto» no es una respuesta suficiente. Pregunta qué tasa, lote, optimizador y calendario se usaron y cuántas pruebas hicieron para llegar a ellos: cada prueba fue un entrenamiento completo.
  • Duplicar las GPU no siempre divide por dos el tiempo: más allá de cierto tamaño, un lote mayor ya no ahorra pasos (el «lote crítico», McCandlish et al., 2018), y obliga a reajustar la tasa y a calentar.
  • Una pérdida que se dispara al inicio apunta a una tasa demasiado alta o a falta de calentamiento; una que oscila al final, a falta de decaimiento. Son ajustes de configuración, no motivos para comprar más cómputo.
  • Compara optimizadores con la tasa de cada uno ajustada, no a igual valor: así se engaña con facilidad. Pide también que registren la semilla y la configuración, porque dos corridas iguales dan resultados algo distintos.

Términos de la lección

Transcripción completa
ComentariosConversación pública de esta lección: dudas, datos por revisar, ideas.

Los comentarios viven en GitHub Discussions, en el repositorio público del curso; para escribir se necesita una cuenta de GitHub. Se cargan desde giscus.app al abrir esta sección. Las personas que revisan el curso los leen, y si un cambio se acepta, se aplica en los dos idiomas. Abrir el hilo en GitHub

Fuentes