Redes Neuronales — Módulo 7: overfitting y regularización — que la red generalice, no memorice
Séptimo módulo del curso de Redes Neuronales: la diferencia entre overfitting y underfitting, por qué necesitas un split train/validation/test, y las técnicas para que la red generalice — dropout, weight decay, batch normalization y early stopping — con código en PyTorch.
☰ Índice del contenido
En el Módulo 6 montamos el training loop y logramos que la loss bajara época tras época. Suena a victoria — pero hay una trampa. Una red lo bastante grande puede hacer bajar la loss de train hasta casi cero memorizando las respuestas del conjunto de entrenamiento, sin haber aprendido nada útil. Es como un estudiante que se sabe de memoria las respuestas del ensayo pero se hunde en la prueba real. Este módulo es sobre detectar y combatir ese engaño: el problema central de todo entrenamiento, y las técnicas para que la red generalice en vez de memorizar.
La tesis del módulo
Una loss baja en train no vale nada si la red falla con datos nuevos. El objetivo real del entrenamiento no es memorizar el pasado, es generalizar al futuro. Todo el arte de la regularización es un solo pacto: sacrificar un poco de rendimiento en train a cambio de que la red funcione con lo que nunca vio.
Overfitting y underfitting
Dos formas de fallar, opuestas entre sí:
- Overfitting (sobreajuste): la red memoriza el training set — incluido su ruido y sus casualidades — y falla en datos nuevos. Loss de train bajísima, loss real alta. El estudiante que se aprendió el solucionario de memoria.
- Underfitting (subajuste): la red es demasiado simple o entrenó demasiado poco, y ni siquiera captura el patrón del training set. Falla en train y en datos nuevos. El estudiante que no estudió.
En el medio está el punto dulce: suficiente capacidad y entrenamiento para captar el patrón real, sin tanto como para memorizar el ruido.
Cómo lo detectas: train / validation / test
No puedes medir si la red generaliza mirando solo los datos con los que entrenó — ahí siempre parecerá buena. Por eso el dataset se parte en tres:
- Train (entrenamiento): con estos datos la red ajusta sus pesos. Los ve una y otra vez.
- Validation (validación): datos que la red no usa para ajustar pesos, pero que revisas durante el entrenamiento para vigilar si está generalizando y para elegir hiperparámetros (learning rate, cuántas capas, etc.).
- Test (prueba): datos que se tocan una sola vez, al final, para el veredicto honesto. Si los usas para decidir cosas, dejan de ser imparciales.
El síntoma del overfitting salta a la vista comparando dos curvas: la loss de train sigue bajando mientras la loss de validation se estanca y empieza a subir. Esa brecha que se abre es la firma del overfitting.
loss
│
│oo validation sube = overfit
│ oo ...ooooooo validation
│ oo ...oooo
│ ooooo ▲
│ ..... │ brecha = overfitting
│ .....txx ▼
│ xxxxxxxxxxxxxxx train (sigue bajando)
│
└───────────.───────────────► épocas
punto óptimo (aquí conviene detenerse)
Mientras las dos curvas bajan juntas, todo bien. En el momento en que la de validation se despega y sube, la red dejó de aprender el patrón general y empezó a memorizar. Ese punto marca dónde deberías haber parado — y eso es exactamente lo que hace una de las técnicas de abajo.
Las técnicas de regularización
Regularización es cualquier técnica que le pone freno a la red para que no memorice. Las cuatro grandes:
- Dropout: durante el entrenamiento, apaga al azar un porcentaje de neuronas en cada paso (típico: 20–50%). Así ninguna neurona puede depender demasiado de otra específica, y la red se ve forzada a repartir el conocimiento — como un equipo que ensaya con jugadores rotando, para que no dependa de una sola estrella.
- Weight decay / L2 (decaimiento de pesos): añade a la loss una penalización por tener pesos grandes, empujándolos hacia valores chicos. Pesos pequeños significan una función más suave y simple, que memoriza menos. “L2” es el nombre matemático de esa penalización.
- Batch normalization (normalización por lotes): normaliza las salidas de una capa dentro de cada batch (las centra y escala) para que los números que fluyen por la red se mantengan en un rango estable. Estabiliza y acelera el entrenamiento, y de paso regulariza un poco.
- Early stopping (parada temprana): vigila la loss de validation y detiene el entrenamiento en cuanto deja de mejorar, antes de que empiece a subir. Es aprovechar directamente la curva del diagrama de arriba: parar en el punto óptimo.
Hay una quinta, data augmentation (aumento de datos): generar variaciones artificiales de los datos (rotar, recortar, cambiar brillo de imágenes) para que la red vea más diversidad. La mencionamos aquí, pero la veremos a fondo en el curso de imágenes.
Qué ataca cada técnica
| Técnica | Qué hace | Qué problema ataca |
|---|---|---|
| Dropout | Apaga neuronas al azar en train | Co-dependencia entre neuronas |
| Weight decay / L2 | Penaliza pesos grandes | Funciones demasiado complejas |
| Batch normalization | Estabiliza los valores entre capas | Entrenamiento inestable + algo de overfit |
| Early stopping | Para cuando validation empeora | Entrenar de más y memorizar |
| Data augmentation | Crea más variedad de datos | Pocos datos / poca diversidad |
En código: dropout y weight decay
Las dos técnicas más fáciles de agregar. El dropout va dentro del modelo; el weight decay, en el optimizer.
import torch
import torch.nn as nn
class MiRed(nn.Module):
def __init__(self):
super().__init__()
self.capa1 = nn.Linear(784, 256)
self.bn = nn.BatchNorm1d(256) # batch normalization
self.drop = nn.Dropout(0.3) # dropout: apaga 30% de neuronas
self.capa2 = nn.Linear(256, 10)
def forward(self, x):
x = torch.relu(self.bn(self.capa1(x)))
x = self.drop(x) # solo actúa en modo train
return self.capa2(x)
modelo = MiRed()
# weight decay = L2. Va como parámetro del optimizer, no en el modelo.
optimizer = torch.optim.Adam(
modelo.parameters(),
lr=0.001,
weight_decay=1e-4, # penaliza pesos grandes
)
Ojo: dropout y batch normalization se comportan distinto en entrenamiento que en evaluación. Por eso hay que avisarle a PyTorch en qué modo está:
modelo.train()antes de entrenar (dropout activo),modelo.eval()antes de validar o predecir (dropout apagado, batchnorm usa estadísticas fijas). Olvidar elmodelo.eval()al evaluar da métricas peores y ruidosas, y es un error clásico difícil de cazar.
Errores comunes
- Mirar solo la loss de train. Es la métrica que siempre mejora. Sin validation no tienes forma de saber si la red generaliza o memoriza. Vigila las dos curvas.
- Usar el test set para decidir. El test es sagrado: se toca una vez, al final. Si ajustas hiperparámetros mirándolo, tus números finales mienten.
- Olvidar
modelo.eval()al validar/predecir. Deja dropout y batchnorm en modo entrenamiento y ensucia todas tus métricas de evaluación. - Apilar toda la regularización de golpe. Meter dropout altísimo + weight decay fuerte + early stopping agresivo puede llevarte al otro extremo: underfitting. Agrega técnicas de a poco y mide.
- Combatir overfitting cuando en realidad es underfitting. Si train y validation son ambas malas, el problema es capacidad o entrenamiento insuficiente, no exceso. Más regularización solo empeora eso.
- Creer que más datos siempre es la respuesta. Ayuda muchísimo, pero no siempre está disponible; por eso existen las otras técnicas. Data augmentation es el punto medio: más datos “gratis” a partir de los que ya tienes.
La frase para llevarse
“Entrenar no es memorizar el pasado, es prepararse para el futuro. La loss de train te dice cuánto memorizaste; la de validation, cuánto realmente aprendiste.”
Qué viene
Módulo 8: tu primera red en PyTorch, de principio a fin. Cerramos el bloque juntando todo — dataset, modelo, loss, optimizer, training loop con batches y evaluación en el test set — en un programa completo que entrena de verdad. La teoría de los módulos 1 al 7 convertida en código que corre.
Material relacionado
Preguntas sobre este curso
Regístrate gratis para hacer preguntas y guardar tu progreso.
✉ Entérate de lo nuevo
Recibe un aviso cuando publique nuevos cursos, workshops o investigaciones. Sin spam.