English · Español
Lab 03 — Implementar y graficar cinco programaciones de tasa de aprendizaje¶
🇪🇸 Cinco curvas en los mismos ejes: constante, escalonada, coseno, warmup→coseno, WSD. Las dibujas, las anotas, y eliges una para Fase 18.
Objetivo¶
Implementa cinco funciones de programación de LR en src/minigrad/schedules.py y grafícalas en un único chart. A ojo, identifica la que usarás en el bucle de entrenamiento de la Fase 18 y justifícala en 3-5 frases.
Planteamiento¶
matplotlib,numpy.- El archivo de teoría
04-lr-schedules-and-warmup.mdpara las fórmulas.
Tareas¶
Parte A — Implementa las programaciones¶
import numpy as np
def constant(t, eta_0=1.0):
return eta_0
def step_decay(t, eta_0=1.0, step=1000, gamma=0.1):
return eta_0 * (gamma ** (t // step))
def cosine(t, eta_0=1.0, eta_min=0.0, T_total=10000):
if t >= T_total:
return eta_min
return eta_min + 0.5 * (eta_0 - eta_min) * (1 + np.cos(np.pi * t / T_total))
def warmup_cosine(t, eta_0=1.0, eta_min=0.0, T_warm=500, T_total=10000):
if t < T_warm:
return eta_0 * (t / T_warm)
return cosine(t - T_warm, eta_0, eta_min, T_total - T_warm)
def wsd(t, eta_0=1.0, eta_min=0.0, T_warm=500, T_stable=7000, T_total=10000):
if t < T_warm:
return eta_0 * (t / T_warm)
if t < T_stable:
return eta_0
# Decaimiento lineal de eta_0 a eta_min sobre [T_stable, T_total]
if t >= T_total:
return eta_min
frac = (t - T_stable) / (T_total - T_stable)
return eta_0 * (1 - frac) + eta_min * frac
Todas toman t y devuelven η_t. Funciones puras — sin estado interno.
Parte B — Graficar¶
import matplotlib.pyplot as plt
T_total = 10000
ts = np.arange(T_total + 1)
schedules = {
"constant": [constant(t) for t in ts],
"step (γ=0.1 @ T=1000)": [step_decay(t) for t in ts],
"cosine": [cosine(t, T_total=T_total) for t in ts],
"warmup→cosine (T_warm=500)": [warmup_cosine(t, T_warm=500, T_total=T_total) for t in ts],
"WSD (T_warm=500, T_stable=7000)": [wsd(t, T_warm=500, T_stable=7000, T_total=T_total) for t in ts],
}
plt.figure(figsize=(10, 6))
for name, vals in schedules.items():
plt.plot(ts, vals, label=name, linewidth=2)
plt.xlabel("Step")
plt.ylabel("Learning rate (relative to η_0)")
plt.legend(loc="lower left")
plt.title("LR schedules (η_0 = 1.0, T_total = 10,000 steps)")
plt.grid(True, alpha=0.3)
plt.savefig("lr_schedules.png", dpi=150)
Parte C — Anotar¶
Para cada programación, añade 2-3 frases a experiments/04-lr-schedules/INTERPRETATION.md:
- Constante: Cuándo la usarías. (Mayormente: como baseline.)
- Decaimiento escalonado: Por qué aparecen "escalones" en la curva de pérdida. Cuándo la programación manual gana a la automática.
- Coseno: Suave y sin parámetros (dado
T_total). El default para entrenamiento sin warmup. - Warmup→Coseno: El default de los transformers. Argumento de condicionamiento de la Hessiana (según teoría 04).
- WSD: Cuándo quieres publicar un checkpoint sin comprometerte con
T_totalpor adelantado.
Parte D — Elige una para la Fase 18¶
En 3-5 frases, declara qué programación usarás en la Fase 18 (el bucle de entrenamiento de Mini-GPT). Justifica por: - El optimizador que estás usando (Adam — así que el warmup ayuda por la razón de la estimación de varianza). - El tamaño del modelo (pequeño — pero el argumento sigue aplicando). - La duración del entrenamiento (~10K pasos — suficiente para que importe el decaimiento en coseno).
La respuesta esperada: warmup→coseno con T_warm = 500. Confirma o argumenta lo contrario.
Parte E — Verificar propiedades¶
Añade unit tests en tests/test_schedules.py:
def test_constant_is_constant():
assert constant(0) == constant(5000) == constant(99999)
def test_warmup_starts_at_zero():
assert warmup_cosine(0, T_warm=500) == 0.0
def test_warmup_ends_at_peak():
# En t = T_warm, la fase de warmup termina; cosine empieza en su pico
assert abs(warmup_cosine(500, T_warm=500, T_total=10000) - 1.0) < 1e-9
def test_cosine_ends_at_eta_min():
assert abs(cosine(10000, T_total=10000) - 0.0) < 1e-9
def test_step_decay_drops():
assert step_decay(999) == 1.0
assert step_decay(1000) == 0.1
assert step_decay(1999) == 0.1
assert step_decay(2000) == 0.01
def test_wsd_three_phases():
s = wsd(t=100, T_warm=500, T_stable=7000) # warmup
assert 0 < s < 1
assert wsd(3000, T_warm=500, T_stable=7000) == 1.0 # estable
assert wsd(10000, T_warm=500, T_stable=7000, T_total=10000) == 0.0 # decaído
Entregable¶
src/minigrad/schedules.py— las cinco funciones.tests/test_schedules.py— los unit tests de arriba (extendidos según sea necesario).experiments/04-lr-schedules/lr_schedules.png— el chart.experiments/04-lr-schedules/INTERPRETATION.md— anotaciones y la elección para la Fase-18.manifest.json.
Aceptación¶
- La gráfica se renderiza limpiamente con las cinco curvas en los mismos ejes.
- Cada curva es visualmente distinta.
- Las curvas warmup→cosine y WSD suben visiblemente desde
0duranteT_warmpasos. - Todos los unit tests pasan.
- La "elección para la Fase 18" está justificada, no solo enunciada.
Escollos¶
T_totalen cosine vs warmup→cosine. Enwarmup_cosine, el cosine corre sobreT_total - T_warmpasos (ya que los primerosT_warmpasos son warmup). Si usasT_totaldirectamente en el cosine interno, la curva termina antes del pasoT_total.- División entera.
t // stepes lo que quiere el step-decay.t / stepdaría un decaimiento continuo — no la forma de escalera. - Off-by-one en
t = T_warm. Que el borde pertenezca a "warmup" o a "cosine" es una elección de convención. Sé consistente. - Eje log-LR al graficar. Algunas referencias muestran la LR en eje y logarítmico. Para una comparación cualitativa lado a lado, lineal es más claro.
- Olvidar las tres fases de WSD. WSD tiene tres: warmup, estable, decaimiento. Saltarse la fase estable lo hace idéntico a warmup→cosine.
Ampliación¶
- Añade una programación one-cycle (Smith): sube en rampa, alcanza pico en algún punto del medio, baja en rampa. Grafica.
- Añade decaimiento-lineal-con-warmup (usado por algunos entrenamientos estilo BERT). Grafica.
- Demuestra el efecto: entrena un modelo minúsculo (o usa una función 2D sintética) con
warmup→cosinevsconstant. Muestra cómo divergen las curvas de pérdida.
Fin de los labs de la Fase 4. Tiempo de escribir PHASE_04_REPORT.md y prepararse para la Fase 5.
Siguiente: Fase 05 — Probabilidad y teoría de la información.