LECCIÓN 7 · CONSTRUIR Y ENTRENAR

Optimizadores y el bucle de entrenamiento

Aquí se junta TODO. El optimizador automatiza la regla w = w − lr·gradiente, y el bucle de entrenamiento es el ciclo de 5 pasos que repetirás en cada proyecto de PyTorch de tu vida.

Recuerda de la lección anterior: nn.Module agrupa capas. MSELoss mide el error en regresión, CrossEntropyLoss en clasificación. Ya tienes modelo y forma de medir el error. Hoy añadimos quién ajusta los pesos.

1. ¿Qué hace un optimizador?

En el curso de redes, actualizabas cada peso a mano con w = w − lr·gradiente. Un optimizador de torch.optim hace eso por todos los parámetros de la red de una sola llamada. Le pasas qué parámetros ajustar y el learning rate:

opt = torch.optim.SGD(net.parameters(), lr=0.1)   # descenso de gradiente
opt = torch.optim.Adam(net.parameters(), lr=0.001)  # más inteligente y popular

2. Un optimizador en acción (cálculo real)

Minimicemos L = (w − 3)² (mínimo en w = 3) empezando en w = 1, con SGD y lr = 0.1:

w = torch.tensor([1.0], requires_grad=True)
opt = torch.optim.SGD([w], lr=0.1)

for step in range(3):
    opt.zero_grad()       # 1. limpiar gradientes
    L = (w - 3)**2      # 2. calcular pérdida
    L.backward()         # 3. gradientes (autograd)
    opt.step()           # 4. actualizar w
salida realstep 0: w=1.0000 L=4.0000 grad=-4.0000 step 1: w=1.4000 L=2.5600 grad=-3.2000 step 2: w=1.7200 L=1.6384 grad=-2.5600 w final: 1.976
✍️ A mano: L=(w−3)², su derivada es dL/dw = 2(w−3), lr=0.1
regla en cada paso:  w_nuevo = w − lr · gradiente

PASO 0  (w = 1.0):
   L    = (1 − 3)²      = (-2)²  = 4.0000
   grad = 2·(1 − 3)     = 2·(-2) = -4.0000
   w    = 1 − 0.1·(-4)  = 1 + 0.4 = 1.4000

PASO 1  (w = 1.4):
   L    = (1.4 − 3)²    = (-1.6)² = 2.5600
   grad = 2·(1.4 − 3)   = 2·(-1.6) = -3.2000
   w    = 1.4 − 0.1·(-3.2) = 1.4 + 0.32 = 1.7200

PASO 2  (w = 1.72):
   L    = (1.72 − 3)²   = (-1.28)² = 1.6384
   grad = 2·(1.72 − 3)  = 2·(-1.28) = -2.5600
   w    = 1.72 − 0.1·(-2.56) = 1.72 + 0.256 = 1.9760

Cada número coincide con la salida real. Mira cómo w sube hacia 3 mientras L baja: está aprendiendo. El gradiente negativo "empuja" a w hacia arriba.

3. El bucle de entrenamiento: los 5 pasos sagrados

Este patrón es idéntico en casi todos los proyectos de PyTorch. Memorízalo (en la lección 9 lo verás con datos reales y salida real; aquí lo fijamos como patrón):

for epoca in range(num_epocas):
    opt.zero_grad()              # 1. ❌ borrar gradientes del paso anterior
    pred = net(X)                # 2. ▶️ forward: predecir
    loss = loss_fn(pred, Y)      # 3. 📏 medir el error
    loss.backward()             # 4. 🔄 backward: gradientes (autograd)
    opt.step()                  # 5. ✅ actualizar los pesos
PasoQué haceDe tu curso de redes
zero_grad()Pone gradientes a 0(evita la acumulación, lección 4)
net(X)Forward passLecciones 1–4 de redes
loss_fn(...)Función de pérdidaLección 5 de redes
backward()BackpropagationLección 7 de redes
step()w = w − lr·gradLección 8 de redes
⚠️ El olvido más común: saltarse zero_grad(). Sin él, los gradientes se acumulan entre pasos (lo viste en la lección 4) y el entrenamiento se vuelve un caos. Siempre va primero.

4. Lo que aprendiste

Lo que aprendiste hoy: el optimizador (SGD o Adam) automatiza la actualización de todos los pesos con opt.step(). El bucle de entrenamiento siempre sigue el mismo ritual de 5 pasos: zero_grad → forward → loss → backward → step. Este es el corazón de cualquier proyecto de PyTorch.

Hasta ahora entrenamos con todos los datos a la vez. Con datasets grandes hay que ir por lotes — para eso están Dataset y DataLoader, la próxima lección.