🧠 De MNIST a Producción: Construyendo un Sistema Completo de Reconocimiento de Dígitos con Deep Learning

Introducción

El reconocimiento de dígitos manuscritos es uno de los problemas clásicos del Machine Learning. Aunque pueda parecer sencillo, ha sido históricamente clave para el desarrollo de técnicas modernas de visión por computadora.

En este artículo presento un sistema completo de clasificación de dígitos basado en el dataset MNIST, llevado más allá del típico ejemplo académico: desde el preprocesamiento hasta el despliegue en una aplicación interactiva.


📚 El dataset MNIST: mucho más que un ejemplo

El dataset MNIST (Modified National Institute of Standards and Technology) contiene 70,000 imágenes de dígitos manuscritos (0-9) en escala de grises (28×28 píxeles).

Fue popularizado por Yann LeCun y su equipo en los años 90 como benchmark estándar para evaluar algoritmos de clasificación.

¿Por qué sigue siendo relevante?

  • Es el “Hello World” del Deep Learning.
  • Permite comparar arquitecturas de forma controlada.
  • Es ideal para experimentar con CNNs y Transfer Learning.
  • Sirve como base educativa para entender visión por computadora.

Para este proyecto, utilicé una versión disponible en Kaggle, facilitando su integración en el pipeline.


🧩 Arquitectura del sistema

El sistema no es solo un modelo, sino un pipeline completo:

  1. Entrada de usuario
    • Dibujo o subida de imagen
  2. Preprocesamiento
    • Normalización
    • Binarización
    • Inversión de fondo
    • Centrado y resize a 28×28
  3. Modelo
    • Red neuronal basada en ResNet18
  4. Inferencia
    • Predicción + probabilidades
  5. Visualización
    • Activaciones internas
    • Gráficos de confianza
  6. Interfaz
    • Aplicación interactiva con Gradio

🔍 Preprocesamiento: el verdadero protagonista

Uno de los mayores retos no fue el modelo, sino el preprocesamiento.

Las imágenes de entrada pueden venir en distintos formatos:

  • Dibujos a mano
  • Diferentes fondos
  • Distintas escalas

Para solucionarlo, implementé un pipeline robusto:

  • Conversión a escala de grises
  • Normalización de intensidades
  • Binarización automática
  • Inversión de fondo (si es necesario)
  • Recorte al bounding box del dígito
  • Centrado y padding
  • Redimensionado a 28×28

Este paso es crítico: un mal preprocesamiento degrada drásticamente la precisión del modelo.


🧠 Modelo: Transfer Learning con ResNet18

En lugar de entrenar una CNN desde cero, utilicé Transfer Learning con ResNet18.

Ventajas:

  • Aprovecha características aprendidas en ImageNet
  • Reduce el tiempo de entrenamiento
  • Mejora la generalización

Aunque MNIST es un dataset simple, usar una arquitectura como ResNet permite:

  • Mayor profundidad sin degradación
  • Mejor captura de patrones complejos
  • Mayor robustez ante variaciones

👁️ Interpretabilidad: viendo cómo piensa la red

Una de las partes más interesantes del proyecto es la visualización de activaciones.

¿Qué son las activaciones?

Son las respuestas de los filtros de la red ante una imagen. En las primeras capas, suelen detectar:

  • Bordes
  • Líneas
  • Curvaturas

Visualizarlas permite entender:

  • Qué partes del dígito son relevantes
  • Cómo la red construye representaciones internas
  • Por qué se producen ciertos errores

Esto convierte el modelo en algo más que una “caja negra”.


📊 Resultados y predicciones

El sistema no solo devuelve un dígito, sino:

  • Probabilidad para cada clase (0-9)
  • Nivel de confianza
  • Segunda mejor predicción (Top-2)
  • Explicación textual

Esto es importante porque en muchos casos (por ejemplo, 3 vs 8), el modelo puede tener ambigüedad.


⚙️ Ingeniería y despliegue

El proyecto está diseñado como un sistema reproducible:

  • Separación entre entrenamiento e inferencia
  • Carga de pesos mediante .pth
  • Pipeline consistente (evitando load_learner)
  • Interfaz desarrollada con Gradio
  • Despliegue en Hugging Face Spaces
  • Landing page en GitHub

Además, se incorporaron buenas prácticas como:

  • Modularidad del código
  • Visualización de etapas intermedias
  • Manejo de errores de entrada
  • Documentación del flujo completo

🧱 Problemas encontrados (y soluciones)

Durante el desarrollo surgieron varios retos interesantes:

1. Inconsistencia en imágenes de entrada
→ Solucionado con un preprocesado robusto y adaptable

2. Activaciones que no se visualizaban
→ Uso correcto de hooks en la capa inicial del modelo

3. Confusión entre dígitos similares
→ Introducción de confianza y segunda predicción

4. Integración con Gradio
→ Reestructuración de tabs y control de outputs


📈 ¿Qué aporta este proyecto?

Más allá de MNIST, este proyecto demuestra:

  • Cómo llevar un modelo de ML a una aplicación real
  • La importancia del preprocesamiento
  • El valor del Transfer Learning incluso en problemas simples
  • Cómo mejorar la interpretabilidad de redes neuronales
  • Cómo estructurar un proyecto end-to-end

🚀 Próximos pasos

Algunas mejoras futuras incluyen:

  • Métricas en tiempo real (accuracy, latency)
  • Comparación entre modelos (CNN vs ResNet)
  • Grad-CAM para interpretabilidad avanzada
  • Data augmentation interactiva
  • Dashboard de rendimiento

En definitiva

Este proyecto transforma un problema clásico en un sistema completo de Machine Learning listo para producción.

Demuestra que incluso los datasets más simples pueden ser una excelente base para construir soluciones robustas, interpretables y bien diseñadas.


Si te interesa el código o probar la aplicación, puedes encontrar el proyecto completo en GitHub y Hugging Face.

/RECONOCEDOR DE DIGITOS

Carrusel: Proyecto ML End-to-End: Clasificador de Dígitos MNIST de Silvia Antón

Deja un comentario

Soy Silvia

Bienvenido/a a El taller de datos, mi acogedor rincón en internet dedicado a todo lo relacionado con mi aprendizaje de este mundo analítico. Aquí te invito a acompañarme en un viaje de creatividad, artesanía y todo hecho a mano con un toque de amor. ¡Vamos a ponernos creativos!