LECCIÓN 5 · CONSTRUIR Y ENTRENAR

nn.Module y capas

Hasta ahora movimos tensores a mano. Ahora dejamos que PyTorch organice los pesos por nosotros con capas (nn.Linear) y modelos (nn.Module) — la forma profesional de construir redes.

1. nn.Linear: una capa lista para usar

En el curso de redes, una capa era z = x @ W + b, y tú creabas y gestionabas W y b. nn.Linear(entradas, salidas) hace exactamente eso, pero crea y guarda los pesos por ti (inicializados al azar):

import torch.nn as nn
lin = nn.Linear(3, 2)        # 3 entradas → 2 salidas
print(lin.weight.shape)    # matriz de pesos
print(lin.bias.shape)      # vector de bias
salida realweight shape: (2, 3) bias shape: (2,)

Pasarle una entrada es solo "llamar" a la capa como si fuera una función:

x = torch.tensor([[1.0, 2.0, 3.0]])   # forma (1, 3)
print(lin(x))
salida realtensor([[-0.8219, 0.0526]])
nn.Linear calcula x @ Wᵀ + b internamente. La gran ventaja: sus pesos son parámetros entrenables que PyTorch rastrea automáticamente para el optimizador. Tú ya no creas tensores con requires_grad a mano.

2. nn.Module: agrupar capas en un modelo

Una red es varias capas conectadas. Se define como una clase que hereda de nn.Module, con dos partes: __init__ (declarar las capas) y forward (cómo fluyen los datos):

class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(2, 4)   # capa oculta: 2 → 4
        self.fc2 = nn.Linear(4, 1)   # capa salida:  4 → 1

    def forward(self, x):
        h = torch.relu(self.fc1(x))   # capa 1 + activación
        return self.fc2(h)            # capa 2 (salida)

net = Net()
print(net)
salida realNet( (fc1): Linear(in_features=2, out_features=4, bias=True) (fc2): Linear(in_features=4, out_features=1, bias=True) )
🔑 Tú nunca llamas a forward directamente. Usas net(x) y PyTorch llama a forward por dentro (haciendo trabajo extra necesario). Llamar net.forward(x) a mano es un error común que rompe algunas funcionalidades.

3. Los parámetros: lo que la red aprende

nn.Module rastrea automáticamente todos los pesos y bias de todas sus capas:

sum(p.numel() for p in net.parameters())
salida realtotal params: 17

Comprobemos: capa 1 = (2×4 pesos) + 4 bias = 12; capa 2 = (4×1) + 1 = 5. Total 17. ✅ Esa lista de parameters() es justo lo que le pasarás al optimizador (lección 7) para que los ajuste.

4. ¿Por qué no hacerlo todo a mano?

A mano (curso de redes)Con nn.Module
Creas cada W, b con requires_gradLas capas los crean solas
Tú llevas la cuenta de los parámetros.parameters() los reúne
Inicialización manualInicialización sensata automática
Fácil equivocarse con las formasCapas estándar probadas
Resumen: nn.Linear es una capa (con sus pesos gestionados); nn.Module agrupa capas en un modelo con su forward. Usas net(x) para predecir y net.parameters() para acceder a lo entrenable. En la próxima lección veremos las activaciones y funciones de pérdida que ofrece torch.nn.