Debugging Modelos de Machine Learning: Mis batallas a las 3 AM (y lo que la intuición no te dice)

Debugging Modelos de Machine Learning: Mis batallas a las 3 AM (y lo que la intuición no te dice)

Publicado el

La primera vez que un modelo de Machine Learning me frustró de verdad fue hace años. Era un clasificador de texto y, por más que cambiaba hiperparámetros, el accuracy no pasaba del 55%. Me pasé días moviendo piezas como un mono con un puzzle, sin un plan, esperando que el siguiente ajuste “mágico” lo arreglara. Spoiler: no lo hizo. Acabé descubriendo que el problema estaba en cómo había tokenizado mi texto, algo tan básico que me dio vergüenza. Ese día juré que nunca más debuggearía a ciegas.

Cuando la intuición falla (que es casi siempre)

Olvídate de la idea romántica de que “el modelo aprenderá solo” o que un par de ajustes aquí y allá bastarán. Debuggear modelos de ML no es como debuggear código imperativo, donde un print bien puesto te revela el valor exacto de una variable. Aquí, el error es sistémico, y a menudo, silencioso. Un modelo que no aprende puede ser un síntoma de docenas de problemas subyacentes.

Mi enfoque, forjado a base de noches sin dormir, es siempre metódico. Y sí, tengo una lista mental (y a veces física) de cosas a revisar.

1. Tus Datos Son el Cimiento (y a menudo el problema)

Si mis datos están mal, mi modelo estará mal, punto. No importa la arquitectura de red neuronal más avanzada, si los datos de entrada son basura, la salida también lo será. Antes de mirar el modelo, miro los datos.

  • Distribuciones: ¿Tienen tus características las distribuciones que esperas? Un histograma o un value_counts() pueden revelar valores atípicos o desequilibrios. ¿Hay NaNs donde no deberían?
  • Escalado: ¿Están tus características escaladas correctamente? Me ha pasado que una columna con valores muy grandes dominaba el entrenamiento y convertía el gradiente en una montaña rusa inútil. Yo soy fanático de los StandardScaler o MinMaxScaler.
  • Fugas de Datos (Data Leakage): Este es un clásico y duele. ¿Estás usando información del conjunto de test en tu preprocesamiento o feature engineering? Cuidado. Un preprocesamiento que mira todo el dataset antes de la división train/test es una fuga sutil pero letal.
  • Etiquetado Incorrecto: ¿Estás seguro de que tus etiquetas son correctas? En proyectos donde el etiquetado es manual, los errores humanos son comunes. Una muestra aleatoria manual de 20-30 ejemplos para verificar el etiquetado me ha salvado de muchos dolores de cabeza.
  • Calidad del Preprocesamiento: ¿El texto se tokenizó bien? ¿Las imágenes se redimensionaron sin deformarse? A veces, un simple print(data.shape) o data.describe() al final de la fase de preprocesamiento te puede dar una pista.

Si quieres profundizar en cómo preparar tus datos, escribí sobre ello en Preprocesamiento de Datos en Machine Learning: La Clave para Modelos Confiables. Es un paso que muchos subestiman.

2. El Modelo en Sí: Arquitectura y Configuración

Una vez que estoy razonablemente seguro de que los datos están limpios, paso al modelo.

  • El Modelo Trivial (Baseline): ¿Tu modelo bate a una suposición aleatoria o a un modelo base sencillo? Si tu accuracy es 50% en un problema binario y tu baseline es 50%, tienes un problema. Siempre empiezo con un modelo base simple (Logistic Regression, Decision Tree) para asegurarme de que el problema es abordable y que mis métricas y pipelines funcionan.
  • Complejidad Apropiada: ¿Estás usando un transformer para clasificar dos categorías linealmente separables? A veces, menos es más. Me sorprenden la cantidad de veces que un modelo simple de Scikit-Learn funciona mejor que una red neuronal compleja para ciertos problemas, especialmente con pocos datos.
  • Funciones de Pérdida y Métrica: ¿Tu función de pérdida es la adecuada para tu problema (MSE para regresión, Cross-Entropy para clasificación)? ¿Y estás midiendo el rendimiento con las Métricas de Evaluación Esenciales para Modelos de Machine Learning: Mide su Rendimiento con Precisión? No es lo mismo un accuracy que un F1-score si tienes clases desequilibradas.
  • Parámetros Críticos: Me aseguro de que el learning rate no sea una barbaridad (demasiado alto = divergir, demasiado bajo = no aprender) y que la inicialización de los pesos sea sensata.

3. El Entrenamiento: Vigila al Observador

El proceso de entrenamiento es donde todo cobra vida (o muere).

  • Sobreajuste (Overfitting) y Subajuste (Underfitting): Este es el pan de cada día. Si el modelo aprende demasiado bien de los datos de entrenamiento pero fracasa con los nuevos, estamos ante un Overfitting y Underfitting: Claves para Construir Modelos de Machine Learning Robustos. Graficar las curvas de entrenamiento y validación de la pérdida y la métrica es no negociable. Si la pérdida de entrenamiento baja y la de validación sube, ¡bingo! Overfitting. Si ambas se estancan, underfitting.
  • Gradientes: Si usas redes neuronales, el estado de los gradientes es oro. ¿Son demasiado pequeños (vanishing gradients)? ¿Demasiado grandes (exploding gradients)? Usar torch.autograd.set_detect_anomaly(True) en PyTorch o revisar las normas de los gradientes puede darte pistas.
  • Batch Size: Un tamaño de batch incorrecto puede hacer que el entrenamiento sea inestable o que no converja.
  • Random Seed: Para replicar errores, siempre, siempre, fija el random seed. Es increíble lo frustrante que es intentar depurar un error que aparece y desaparece aleatoriamente.

Mi Proceso Mental Cuando Algo Falla

  1. ¿El modelo aprende algo? Primero, verifico que la pérdida disminuye, incluso si es solo un poco. Si no se mueve, es un problema grave.
  2. ¿Sobreajusta a un batch pequeño? Intento entrenar con un batch extremadamente pequeño (2-4 ejemplos) y sin regularización. Si el modelo no puede sobreajustar perfectamente a esos pocos ejemplos, tengo un problema más fundamental (datos, arquitectura, implementación de la función de pérdida). Si lo hace, entonces el problema es más de generalización, y ahí miro regularización, datos, etc.
  3. Visualiza, Visualiza, Visualiza: No confío solo en los números. Visualizo imágenes, embeddings, árboles de decisión, lo que sea. Ver lo que el modelo “ve” puede revelar errores ocultos.

Una Última Reflexión

Debugging en ML es una habilidad, no un arte místico. Requiere paciencia y un enfoque sistemático. Y sobre todo, no tener miedo a cuestionar cada capa de tu stack, desde cómo preprocesas hasta cómo calculas tu pérdida. A veces, la solución es increíblemente simple y otras, un agujero negro. Pero con un plan, al menos sabes dónde buscar. Y esa, créeme, es la diferencia entre una noche productiva y un dolor de cabeza a las 3 AM.