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:
- Entrada de usuario
- Dibujo o subida de imagen
- Preprocesamiento
- Normalización
- Binarización
- Inversión de fondo
- Centrado y resize a 28×28
- Modelo
- Red neuronal basada en ResNet18
- Inferencia
- Predicción + probabilidades
- Visualización
- Activaciones internas
- Gráficos de confianza
- 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.
Carrusel: Proyecto ML End-to-End: Clasificador de Dígitos MNIST de Silvia Antón







Deja un comentario