MastoLens AI: de modelos de visión computacional a un demo web para análisis de mastografías
Cómo llevé un proyecto de visión por computadora aplicada a mamografías desde la preparación de datasets y entrenamiento de modelos hasta un live demo funcional con YOLO, Docker, autenticación, colas de procesamiento y controles básicos de seguridad.
Inició como experimentos con mamografías y Google Coral terminó con un demo funcional
Durante los últimos meses estuve trabajando en una línea de proyectos alrededor del análisis asistido por IA sobre mamografías y todo este trabajo dejó varios productos que me gustaría compartir. Lo que empezó como una exploración técnica para entrenar modelos con datasets públicos terminó convirtiéndose en algo mucho más amplio: un sistema que combina preparación de datos, pruebas con distintas arquitecturas, optimización para edge y una demo funcional publicada como parte de mi portafolio.
Este post resume ese recorrido, los retos reales que encontré y las decisiones técnicas que me llevaron de los experimentos iniciales a una versión funcional para demostración.

El reto empezó antes del modelo
En proyectos de visión por computadora suele hablarse mucho del entrenamiento y poco de la parte más pesada: conseguir, organizar y normalizar los datos.
En este caso trabajé con varios datasets de mamografías públicas. Eso implicó lidiar con formatos distintos, estructuras de carpetas diferentes, imágenes DICOM, JPEG y metadatos dispersos. En una etapa del proyecto armé una estrategia específica para descargar datasets grandes desde notebook y scripts, porque hacer esto manualmente una y otra vez se vuelve costoso en tiempo, almacenamiento y errores operativos.
Ese trabajo previo fue importante por dos razones. La primera es que me permitió estandarizar los datos para usarlos con distintos enfoques de entrenamiento. La segunda es que me obligó a pensar en el proyecto como un sistema reproducible y no como una sola libreta de experimentos.
Aunque consulté varios repositorios de imágenes y algunos sólo aportaron ideas, considero que los más relevantes para este ejercicio fueron:
1) CBIS-DDSM
- Fuente oficial: The Cancer Imaging Archive (TCIA).
- Qué es: una versión curada y estandarizada del DDSM para mamografías de cribado. Incluye casos normales, benignos y malignos con verificación patológica.
- Tamaño aproximado: 2,620 estudios, 6,775 series DICOM y 10,239 imágenes.
- Para qué sirve en el proyecto: está planteado como el dataset primario para entrenamiento del modelo y para tareas de detección y diagnóstico asistido por computadora.
2) ViNDR-Mammo
- Fuente oficial: PhysioNet.
- Qué es: un dataset de mamografías digitales de cribado creado con datos del Vietnam National Cancer Hospital y Vinmec. Está pensado para benchmarking y validación en una población distinta a la de muchos datasets occidentales.
- Tamaño aproximado: 20,000 imágenes DICOM de 5,000 pacientes.
- Para qué sirve en el proyecto: aparece como dataset secundario para validación, comparación de modelos y evaluación cruzada entre poblaciones.
3) RSNA Breast Cancer Detection
- Fuente oficial: Kaggle Competitions, organizado por RSNA.
- Qué es: un dataset de competición para detección de cáncer de mama con anotaciones expertas y casos clínicos reales.
- Tamaño aproximado: 54,706 imágenes DICOM de 11,913 pacientes.
- Para qué sirve en el proyecto: se documenta como dataset para entrenamiento, benchmarking y evaluación en una escala más grande, aunque con un reto fuerte de desbalance de clases.

Documentación pública del proyecto
Para que el proyecto sea más útil como parte de mi portafolio, preparé una documentación técnica pública en GitHub. La intención es documentar la arquitectura, las decisiones de inteligencia artificial, la seguridad y los aprendizajes del proyecto.
El repositorio incluye:
docs/
├── 00-overview/
│ └── Introducción, alcance del demo y notas de IA responsable.
├── 01-datasets/
│ └── Descarga y preprocesamiento de CBIS-DDSM, ViNDR-Mammo y RSNA.
├── 02-data-pipeline/
│ └── Pipeline de ingestión y normalización de DICOM a 8 bits.
├── 03-modeling/
│ └── Comparativas de modelos, objetivos y balanceo de clases.
├── 04-edge-and-coral/
│ └── Cuantización INT8 y compilación para Coral Edge TPU.
├── 05-demo-web/
│ └── Arquitectura web con Flask, Redis y RQ Worker.
├── 06-security-and-privacy/
│ └── STRIDE, JWT, CSRF, rate limiting y aislamiento de imágenes.
├── 07-engineering-lessons/
│ └── Decisiones de ingeniería y retos de GPU/CUDA.
├── 08-repository-map/
│ └── Mapeo de repositorios, dependencias y flujo del ecosistema.
└── 09-appendix/
└── Comandos de referencia, glosario y troubleshooting.
templates/
├── dataset-card.md
├── decision-record.md
└── experiment-card.md
assets/
└── diagrams/
├── architecture.mmd
├── data-pipeline.mmd
├── inference-flow.mmd
├── security-flow.mmd
└── repository-map.mmd
La documentación está pensada para mostrar:
- Arquitectura general del sistema.
- Pipeline de procesamiento de imágenes médicas.
- Conversión de DICOM de 16 bits a imágenes RGB de 8 bits.
- Realce de contraste mediante CLAHE.
- Inferencia asíncrona con Flask, Redis y RQ Worker.
- División de datos a nivel paciente para reducir riesgo de data leakage.
- Cuantización INT8 para Google Coral Edge TPU.
- Modelado de amenazas con STRIDE.
- Protección contra Path Traversal, CSRF y abuso de carga de imágenes.
- Autenticación mediante OTP y JWT.
- Decisiones técnicas documentadas con ADRs.
- Retos reales de TensorFlow, CUDA/GPU y despliegue local.
De una base experimental a una arquitectura más seria
La evolución del proyecto dejó varias capas que todavía se notan en los repositorios.
Una de las primeras capas está orientada al entrenamiento, conversión de datasets y pruebas con distintas familias de modelos. Ahí aparecen rutas para trabajar con formatos tipo YOLO y COCO, modelos de detección y también una primera web app para inferencia.
Después vino una etapa más modular, donde intenté ordenar el proyecto alrededor de componentes reutilizables. En esa fase empecé a separar configuración, carga de datos, entrenamiento y despliegue. También exploré variantes más orientadas a edge, incluyendo una línea de trabajo con Google Coral TPU, TFLite y modelos más ligeros.
Ese paso fue importante porque cambió el objetivo. Dejé de pensar únicamente en entrenar el modelo más complejo posible y empecé a preguntarme qué arquitectura tenía más sentido para una demo real, para un entorno con recursos limitados y para un flujo más mantenible.
Por qué la versión funcional terminó en YOLO
Aunque el proyecto pasó por varios enfoques, la versión funcional que sí logré integrar de extremo a extremo terminó apoyándose en YOLO.
La razón fue práctica. Para una demo operativa importan mucho la madurez del ecosistema, la facilidad de integración, la estabilidad de inferencia y la claridad de la documentación disponible en el momento. En una investigación uno puede perseguir la arquitectura más reciente. En una demo funcional, lo que más pesa es cerrar el ciclo completo sin romper el sistema en cada paso.
Con YOLO conseguí algo que me interesaba más para esta fase del proyecto: una ruta razonable entre modelo entrenado, inferencia reproducible, despliegue en contenedor y visualización de resultados para usuario final.
Además, la versión que quedó integrada usa dos modelos en conjunto para inferencia, lo que me permitió experimentar con una lógica de ensemble ligera dentro del demo.
El demo no es solo una interfaz
La parte que más valor tiene para mi portafolio es haber convertido la inferencia en un flujo usable.
La demo incorpora un mecanismo de acceso con correo y código de verificación, control de créditos para limitar uso, cola de trabajos para no bloquear la aplicación web, almacenamiento privado por análisis, generación de reportes PDF y muestras curadas para enseñar el sistema sin depender de datos sensibles del usuario.
Ese tipo de decisiones no suelen lucirse tanto como una métrica bonita, pero acercan mucho más el proyecto a un escenario real. En vez de quedarse en un notebook, el sistema ya resuelve problemas de sesión, seguridad básica, procesamiento asíncrono, persistencia y presentación de resultados.
También me interesó cuidar el preprocesamiento. En imágenes médicas pequeñas diferencias de lectura importan, así que la conversión desde DICOM y el manejo de intensidades no podían dejarse como un detalle secundario.

Lo más difícil del proyecto
Hubo varios retos que valen la pena mencionar porque son el tipo de problemas que rara vez aparecen en una demo final.
1. El peso de los datasets
Descargar varios datasets médicos grandes no es trivial. El problema además del tamaño es que entran en juego credenciales, formatos distintos, reintentos, organización de carpetas y el tiempo necesario para rehacer el entorno cuando algo falla.
2. La heterogeneidad de los formatos
Trabajar con DICOM, JPEG, anotaciones distintas y convenciones diferentes obliga a crear una capa de normalización. Sin eso, comparar modelos o reutilizar pipelines se vuelve muy difícil.
3. La infraestructura del entrenamiento
Entre CUDA, versiones de bibliotecas, diferencias entre GPU y CPU y conversiones hacia edge, la parte de entorno fue una fuente constante de fricción. En la línea de Google Coral, por ejemplo, el proyecto deja ver que la optimización para Edge TPU era prometedora, pero todavía tenía retos abiertos de conversión y compatibilidad. Esta parte se puede llegar a complicar porque por ejemplo, cuando lo desarrollé y todavía hasta julio 2026, no existen versiones de las bibliotecas de todos los componentes para las últimas versiones de python y hay incompatibilidades entre ellas. Por eso recomiendo no utilizar la última versión disponible, sino versiones más estables, al menos en una etapa inicial, ya que facilita mucho el flujo de desarrollo.
4. Llevar la investigación a una demo real
Llevar la investigación a un demo real implicó empaquetar un modelo y también exigió pensar en seguridad desde la aplicación: control de acceso por correo con verificación temporal, rate limiting, validación de archivos DICOM e imagen, almacenamiento privado por análisis, autorización por usuario y cabeceras defensivas para la superficie web. Al mismo tiempo, el proyecto deja ver varias lecciones de endurecimiento: los endpoints de observabilidad no deberían quedar completamente expuestos, la autenticación por código necesita controles adicionales contra fuerza bruta, el rate limiting detrás de proxy debe configurarse con cuidado y el contenedor aún requiere una política de menor privilegio. Esa transición entre experimento funcional y demo pública endurecida fue una parte importante del trabajo de ingeniería.

Qué aprendí
Este proyecto me dejó cuatro aprendizajes principales.
El primero, es que en IA aplicada casi nunca basta con entrenar. La parte de datos, despliegue, inferencia y producto pesa tanto como el modelo.
El segundo, es que una arquitectura más nueva no siempre es la mejor elección para una versión funcional. A veces, la mejor decisión es trabajar con una base más madura y cerrar el flujo completo. Hay que tener cuidado con las brechas de seguridad de las versiones viejas.
El tercero, es que documentar y modularizar a tiempo ahorra mucho esfuerzo después. Hay que considerar desde un inicio, sin hacer sobre ingeniería, una arquitectura que pueda escalar fácilmente ya que cuando el proyecto crece, la diferencia entre un experimento interesante y un sistema mantenible está en cómo organizas el código. La sobre ingeniería te puede frenar, pero te frena mucho más una base que le cuesta escalar.
El cuarto, es que un buen proyecto de portafolio no necesita fingir que ya es un producto clínico. Tiene más valor explicar con honestidad qué funciona, qué está en desarrollo y qué aprendiste al construirlo, por tal motivo, he comenzado a desplegar demos de los trabajos de IA que he implementado donde se puedan probar los modelos que he desarrollado.

Estado actual
Hoy este trabajo ya me permite mostrar varias cosas con una sola línea narrativa:
- Preparación y normalización de datasets médicos.
- Entrenamiento y comparación de distintas arquitecturas.
- Exploración de despliegue edge con Google Coral.
- Integración de inferencia en una aplicación real.
- Despliegue containerizado.
- Controles básicos de acceso, procesamiento asíncrono y reportes.
Todavía hay espacio para seguir mejorándolo. Me interesa reforzar la parte de evaluación, limpiar aún más la reproducibilidad, documentar mejor la evolución entre repositorios y revisar nuevas variantes de modelo cuando tenga sentido práctico integrarlas.
Cierre
Este proyecto nació como una investigación técnica y terminó convirtiéndose en una demo funcional que me ayudó a unir visión por computadora, backend, despliegue y experiencia de usuario en una sola pieza de portafolio.
Eso es precisamente lo que más valoro de este trabajo, representa el proceso completo de convertir una idea de IA aplicada en un sistema que ya se puede usar, explicar y mejorar.