Grad-Cam para detectar neumonía en rayos X

Resumen

Visualizar neumonía en radiografías con redes neuronales deja de ser una caja negra cuando aplicas Grad-Cam. Esta técnica te muestra exactamente qué zonas de la imagen está mirando tu modelo en PyTorch para tomar una decisión, y por qué eso importa tanto en aplicaciones médicas.

¿Qué es Grad-Cam y para qué sirve en redes neuronales?

Grad-Cam es una técnica de interpretabilidad que te permite ver qué detecta la última capa de convolución de tu red neuronal. En lugar de confiar ciegamente en la predicción, generas un mapa de calor que resalta las regiones donde el modelo hizo foco para decidir si una radiografía corresponde a una persona sana o con neumonía.

¿Qué hace Grad-Cam? Genera un mapa de calor sobre la imagen original que muestra en rojo las zonas de mayor interés para la red y en azul las de menor relevancia. Así entiendes en qué se basa la predicción.

En PyTorch no viene incluido de fábrica, así que necesitas implementarlo desde cero. Lo importante no es memorizar el código, sino entender el porqué: te ayuda a vos, como humano, a focalizar en las áreas que la red consideró relevantes [04:30].

¿Qué dependencias necesitas para implementar Grad-Cam en PyTorch?

Antes de escribir la clase, instalas e importas tres librerías clave que se encargan de manipular la imagen y construir la visualización [00:18]:

  • OpenCV: para crear el mapa de calor y aplicar el resize.
  • TorchVision functional: para trabajar con tensores e imágenes dentro del flujo de PyTorch.
  • Pillow: para cargar y procesar las imágenes originales.

Estas tres herramientas trabajan en conjunto y son la base sobre la que se monta toda la visualización posterior.

¿Cómo se construye la clase Grad-Cam paso a paso?

La implementación arranca definiendo una clase que recibe el modelo entrenado y la capa de convolución a analizar [01:30]. El modelo se pone en modo evaluación, igual que cuando hacés inferencias o predicciones, y se limpian los hooks para poder analizar varias imágenes en secuencia.

El flujo interno se resume así:

  1. Obtener los gradientes de la capa de convolución elegida.
  2. Construir el mapa de calor a partir de esos gradientes.
  3. Normalizar el mapa para que el rojo y el azul no queden saturados y la lectura sea fluida.

Luego se crea una función auxiliar que toma la imagen original y la superpone con el mapa de color. Para esto necesitas desnormalizar la imagen usando los mismos valores de media y desviación estándar que aplicaste en el data augmentation de la etapa de preprocesamiento [02:35]. Si cambiás esas transformaciones, también tenés que actualizar esta función.

¿Cómo se aplica el mapa de calor con OpenCV?

Con OpenCV se hace un resize del mapa para que coincida con el tamaño de la imagen original y luego se aplica una paleta de colores donde el rojo marca alta intensidad y el azul baja [03:10]. La superposición final se visualiza con matplotlib.

¿Cómo identificar la última capa de convolución según la arquitectura?

Acá está uno de los puntos más prácticos. La capa que le pasás a Grad-Cam cambia según la arquitectura que entrenaste, y elegir mal la capa rompe toda la visualización [04:00].

  • Arquitectura uno (red básica): una sola convolución, función de activación, pooling, flatten y linear. La capa de interés es la cero.
  • Arquitectura dos (red más compleja): dos convoluciones intercaladas con activaciones y pooling. La última convolución está en la posición tres.
  • Arquitectura tres (transfer learning con ResNet 50): la capa de interés es layer 4, convolución 3.

¿Cómo encuentro la última capa de convolución en una red preentrenada? Imprimí la arquitectura del modelo cargado y bajá hasta el final. En ResNet 50 vas a encontrar layer4 y dentro la conv3, que es la última capa convolucional antes del clasificador.

Este detalle conecta con el concepto de transfer learning, donde reutilizás una red entrenada en millones de imágenes (como ResNet 50) y la adaptás a tu problema específico de clasificación de radiografías.

¿Qué muestran los mapas de calor en radiografías de tórax?

Al ejecutar Grad-Cam sobre el modelo entrenado con ResNet 50, le pasás el modelo, las clases, el device y la cantidad de imágenes que querés visualizar. El resultado es revelador.

En una radiografía normal, el modelo focaliza en zonas específicas con rojo intenso y deja en azul las áreas que no aportan información. En los casos de neumonía, el rojo se concentra de forma muy marcada en regiones puntuales, muchas veces sobre bordes y texturas del tejido pulmonar, que es lo que la red aprendió a asociar con la patología [05:50].

¿Cómo aplicar Grad-Cam a tus propias imágenes?

Más allá de la carpeta de validación, podés cargar tus propias radiografías con la función GradCamFromPath. Le pasás la ruta de la imagen y devuelve la visualización con el mapa de calor [06:40].

El flujo es:

  1. Aplicar el pipeline de preprocesamiento (las mismas transformaciones de data augmentation de la parte dos).
  2. Cargar la imagen y poner el modelo en modo evaluación.
  3. Calcular el Grad-Cam y mostrar la clase predicha junto al mapa de calor.

Probado con una radiografía etiquetada como bacteria, el modelo predice neumonía y resalta en rojo la zona exacta que motivó la decisión.

¿Reemplaza Grad-Cam el diagnóstico médico? No. Es una herramienta para potenciar las decisiones de los doctores, ofrecer una segunda mirada y reducir errores en el diagnóstico, no para sustituir el criterio clínico.

Si ya entrenaste tu modelo de clasificación de neumonía, contame en los comentarios qué zonas resaltó tu Grad-Cam y si coincidieron con lo que esperabas.