Dos piezas que ya conoces del curso de redes, ahora en su versión PyTorch: las activaciones (la chispa no-lineal) y las pérdidas (cómo se mide el error). Saber elegir la pérdida correcta es media batalla.
nn.Linear crea una capa con pesos y bias. nn.Module agrupa capas en un modelo. Usas net(x) para predecir y net.parameters() para el optimizador. Hoy añadimos los dos ingredientes que faltaban: activaciones (no-linealidad) y funciones de pérdida (medir el error).
PyTorch las ofrece como funciones (torch.relu) o como capas (nn.ReLU()).
Apliquémoslas a un mismo vector para ver su efecto:
z = torch.tensor([-2.0, -0.5, 0.0, 0.5, 2.0])
torch.relu(z)
torch.sigmoid(z)
torch.tanh(z)
Error cuadrático medio: el promedio de (predicción − objetivo)².
pred = torch.tensor([2.5, 0.0, 2.0])
target = torch.tensor([3.0, -0.5, 2.0])
loss_fn = nn.MSELoss()
loss_fn(pred, target)
1) error de cada elemento (pred − target):
2.5 − 3.0 = -0.5
0.0 − (-0.5) = 0.5
2.0 − 2.0 = 0.0
2) elevar cada error al cuadrado:
(-0.5)² = 0.25
( 0.5)² = 0.25
( 0.0)² = 0.00
3) promediar (sumar y dividir entre 3):
(0.25 + 0.25 + 0.00) / 3 = 0.50 / 3 = 0.16667 ✓
Úsala cuando la salida es un valor continuo (precio, temperatura… nuestro proyecto tabular).
La pérdida estrella en clasificación. Recibe los logits — los números crudos que salen de la última capa, antes de convertirlos en probabilidades (pueden ser negativos, mayores que 1, cualquier valor) — y el índice de la clase correcta (0, 1, 2…). Castiga mucho estar seguro y equivocado:
logits = torch.tensor([[2.0, 0.5, 0.1]]) # puntajes para 3 clases
ce = nn.CrossEntropyLoss()
ce(logits, torch.tensor([0])) # clase correcta = 0 (la de mayor logit)
ce(logits, torch.tensor([2])) # clase correcta = 2 (la de menor logit)
Logits = [2.0, 0.5, 0.1]
PASO 1 — softmax (convierte logits en probabilidades):
a) exponenciar cada logit:
e^2.0 = 7.389056
e^0.5 = 1.648721
e^0.1 = 1.105171
b) sumar: 7.389056 + 1.648721 + 1.105171 = 10.142948
c) dividir cada uno entre la suma:
p₀ = 7.389056 / 10.142948 = 0.728492
p₁ = 1.648721 / 10.142948 = 0.162549
p₂ = 1.105171 / 10.142948 = 0.108960
PASO 2 — tomar −ln de la probabilidad de la clase correcta:
clase 0: −ln(0.728492) = 0.3168 ✓ (prob alta → pérdida baja)
clase 2: −ln(0.108960) = 2.2168 ✓ (prob baja → pérdida alta)
0, 1, 2…),
no un "vector one-hot" (un vector con un 1 en la posición de la clase y ceros en el resto, como [0,0,1] para la clase 2 — CrossEntropyLoss no quiere eso, solo quiere el número 2).
Fíjate cómo cuando el modelo "apuesta" por la clase correcta la pérdida es baja (0.32), y cuando apuesta fuerte por la equivocada se dispara (2.22).
| Tarea | Salida de la red | Pérdida |
|---|---|---|
| Regresión (un número) | 1 neurona, sin activación | nn.MSELoss |
| Clasificación binaria | 1 neurona + sigmoid | nn.BCELoss |
| Clasificación multiclase | N neuronas (logits) | nn.CrossEntropyLoss |
MSELoss para regresión, CrossEntropyLoss para clasificación (pásale logits crudos e índice de clase, no vector one-hot). Ya tienes modelo + pérdida.
Falta quién ajuste los pesos: el optimizador, y el bucle de entrenamiento — la próxima lección.