Pipeline modular para medir el balance multimodal con SHAP en modelos tipo CLIP (incluye PubMedCLIP, WhyXrayCLIP, Rclip y BiomedCLIP) sobre datasets médicos como ROCO (Image-Sentence Alignment) y VQA-Med 2019 (Visual Question Answering). Diseñado para ejecución local con datasets descargados desde Google Drive u orígenes oficiales.
🚀 Instalación en un solo click: Ejecuta
./setup.shy tendrás todo listo automáticamente. Ver Instalación Rápida.
Esta versión utiliza instalación con
pyproject.tomly uso depip install -e ..
Si quieres configurar todo el entorno en un solo comando, usa el script de instalación automática:
git clone https://github.com/Alberto-97sc/mmshap_medclip.git
cd mmshap_medclip
./setup.sh
┌─────────────────────────────────────────────────────────┐
│ ./setup.sh │
└─────────────────────────────────────────────────────────┘
│
┌───────────────────┼───────────────────┐
▼ ▼ ▼
[Verificar Python] [Configurar Git] [Instalar deps]
│ │ │
└───────────────────┼───────────────────┘
│
▼
[Descargar dataset]
│
▼
[Convertir scripts a notebooks]
│
▼
✅ ¡LISTO!
El script setup.sh automatiza completamente la configuración del proyecto en 5 pasos:
🐍 Verifica e instala Python3 (si no está presente en el sistema)
📝 Configura Git con las credenciales del proyecto
user.name: Alberto-97scuser.email: [email protected]📦 Instala todas las dependencias
pip install -e .)📥 Descarga automática de datasets médicos
scripts/download_dataset.py para obtener ROCO en data/dataset_roco.zipscripts/download_vqa_med_2019.py para guardar data/VQA-Med-2019.zip (solo si cuentas con permisos de ImageCLEF)📓 Convierte scripts a notebooks Jupyter
.ipynb en el directorio experiments/Cuando ejecutes ./setup.sh, verás algo similar a esto:
╔════════════════════════════════════════════════════════════════╗
║ Inicializando proyecto mmshap_medclip ║
╚════════════════════════════════════════════════════════════════╝
🐍 [1/5] Verificando instalación de Python...
✅ Python ya está instalado (versión 3.12.12)
📝 [2/5] Configurando Git...
✅ Git configurado correctamente
Usuario: Alberto-97sc
Email: [email protected]
📦 [3/5] Instalando dependencias...
→ Actualizando pip...
→ Instalando mmshap_medclip con soporte para notebooks...
✅ Dependencias instaladas correctamente
✓ Paquete mmshap_medclip en modo editable
✓ Dependencias para notebooks (jupytext, jupyter)
📥 [4/5] Descargando datasets desde Google Drive...
📥 [4.1/5] Dataset ROCO → data/dataset_roco.zip
✅ Descarga completada
📥 [4.2/5] Dataset VQA-Med 2019 → data/VQA-Med-2019.zip
✅ Descarga completada (o se reutiliza el archivo existente)
📓 [5/5] Convirtiendo scripts a notebooks Jupyter...
✅ Notebooks creados en experiments/
- experiments/pubmedclip_roco_isa.ipynb
- experiments/whyxrayclip_roco_isa.ipynb
- experiments/rclip_roco_isa.ipynb
- experiments/biomedclip_roco_isa.ipynb
╔════════════════════════════════════════════════════════════════╗
║ ✅ INSTALACIÓN COMPLETADA EXITOSAMENTE ║
╚════════════════════════════════════════════════════════════════╝
Una vez completada la instalación, solo necesitas:
# Ejecutar un experimento directamente
python3 experiments/pubmedclip_roco_isa.py
python3 experiments/whyxrayclip_roco_isa.py
python3 experiments/rclip_roco_isa.py
O usar los notebooks generados:
# Iniciar Jupyter Notebook
jupyter notebook
# Luego abrir: experiments/pubmedclip_roco_isa.ipynb
# Seleccionar cualquier kernel de Python 3.12
sudo si Python no está instaladoSi deseas modificar la configuración de Git, edita las siguientes líneas en setup.sh:
git config user.name "TuUsuario"
git config user.email "[email protected]"
Error: Permission denied al ejecutar ./setup.sh
# Dar permisos de ejecución al script
chmod +x setup.sh
./setup.sh
Error: Python no se instaló automáticamente
sudo para instalar Pythonsudo apt-get install python3 python3-pip # Debian/Ubuntu
# o
sudo yum install python3 python3-pip # RedHat/CentOS
Error al descargar el dataset
data/dataset_roco.zipError de importación en notebooks
mmshap_medclip/
├── src/mmshap_medclip/
│ ├── __init__.py
│ ├── comparison.py # compara 4 modelos ISA + batch SHAP
│ ├── comparison_vqa.py # comparador PubMedCLIP vs BioMedCLIP en VQA-Med
│ ├── devices.py # manejo de device (CUDA/CPU)
│ ├── registry.py # registro de modelos y datasets
│ ├── models.py # wrappers de CLIP (PubMedCLIP, WhyXrayCLIP, RCLIP, BioMedCLIP)
│ ├── io_utils.py # cargar configs YAML
│ ├── metrics.py # MM-score, IScore
│ ├── datasets/
│ │ ├── __init__.py
│ │ ├── base.py # interfaz DatasetBase
│ │ ├── roco.py # loader ROCO (lee ZIP local)
│ │ └── vqa_med_2019.py # loader VQA-Med 2019 (splits Training/Val/Test)
│ ├── tasks/
│ │ ├── __init__.py
│ │ ├── isa.py # tarea Image-Sentence Alignment
│ │ ├── vqa.py # tarea VQA + SHAP + visualizaciones
│ │ ├── utils.py # prepare_batch, token lengths, etc.
│ │ └── whyxrayclip.py # utilidades específicas WhyXrayCLIP
│ ├── shap_tools/
│ │ ├── masker.py # build_masker (BOS/EOS safe)
│ │ ├── predictor.py # predictor ISA
│ │ └── vqa_predictor.py # predictor especializado para VQA
│ └── vis/
│ └── heatmaps.py # mapas de calor imagen+texto
├── experiments/
│ ├── analyze_batch_results.py # dashboard estadístico desde batch_shap_results.csv
│ ├── biomedclip_roco_isa.py
│ ├── compare_all_models.py # comparador 4 modelos ISA (script/notebook)
│ ├── compare_vqa_models.py # comparador VQA
│ ├── pubmedclip_roco_isa.py
│ ├── rclip_roco_isa.py
│ ├── README_compare_models.md # guía detallada del comparador
│ └── whyxrayclip_roco_isa.py
├── outputs/
│ ├── analysis/ # dashboards (tabla_iscore_promedio.png, etc.)
│ ├── isa_heatmaps/ # >100 heatmaps ISA (png)
│ └── vqa_heatmaps/ # 80+ heatmaps VQA
├── configs/
│ ├── roco_isa_pubmedclip.yaml
│ ├── roco_isa_whyxrayclip.yaml
│ ├── roco_isa_rclip.yaml
│ ├── roco_isa_biomedclip.yaml
│ └── vqa_med_2019_pubmedclip.yaml
├── scripts/
│ ├── download_dataset.py # descarga ROCO
│ └── download_vqa_med_2019.py # descarga VQA-Med 2019 (ZIP completo)
├── data/ # carpeta para datasets (no versionada)
├── documentation_tecnica.md
├── REPORTE_TECNICO_MM_SHAP_MEDCLIP.md
├── setup.sh # script de instalación automática (un solo click)
├── pyproject.toml # configuración del proyecto y dependencias
├── test_alpha_adjustment.py
└── README.md
El directorio experiments/ contiene scripts completos listos para ejecutar localmente o convertir a notebooks:
pubmedclip_roco_isa.pyconfigs/roco_isa_pubmedclip.yamlwhyxrayclip_roco_isa.pyconfigs/roco_isa_whyxrayclip.yamlrclip_roco_isa.pyconfigs/roco_isa_rclip.yamlbiomedclip_roco_isa.pyconfigs/roco_isa_biomedclip.yamlcompare_vqa_models.py.py y .ipynb para ejecución directa o notebookvqa_med_2019 que arma candidatos por categoríacompare_all_models.pysrc/mmshap_medclip/comparison.py (usa load_all_models, run_shap_on_all_models, plot_comparison_simple y save_comparison).outputs/comparison_sample_XX.png) y resúmenes JSON.experiments/README_compare_models.md.analyze_batch_results.pyoutputs/batch_shap_results.csv generado con comparison.batch_shap_analysis.outputs/analysis/ (dashboard_completo.png, boxplot_iscore.png, balance_score_comparison.png, tablas CSV, etc.).Todos los experimentos incluyen:
src/mmshap_medclip/comparison.py)load_all_models, run_shap_on_all_models y plot_comparison_simple permiten levantar los 4 modelos médicos y generar una figura conjunta (imagen + texto coloreado) con métricas logit/TScore/IScore.plot_individual_heatmaps y save_comparison facilitan guardar PNG/JSON en outputs/.analyze_multiple_samples resume SHAP de varios índices y devuelve un DataFrame.batch_shap_analysis ejecuta SHAP en rangos grandes de muestras, es idempotente (retoma donde se quedó, detecta NaN y vuelve a procesar) y escribe outputs/batch_shap_results.csv, que luego usa el notebook de análisis.from mmshap_medclip.comparison import load_all_models, batch_shap_analysis
from mmshap_medclip.devices import get_device
from mmshap_medclip.io_utils import load_config
from mmshap_medclip.registry import build_dataset
device = get_device()
cfg = load_config("configs/roco_isa_pubmedclip.yaml")
dataset = build_dataset(cfg["dataset"])
models = load_all_models(device)
df = batch_shap_analysis(
models=models,
dataset=dataset,
device=device,
start_idx=0,
end_idx=500,
csv_path="outputs/batch_shap_results.csv",
)
src/mmshap_medclip/comparison_vqa.py)load_vqa_models levanta PubMedCLIP y BioMedCLIP, respetando las preferencias de visualización de cada wrapper.run_vqa_shap_on_models usa tasks.vqa.run_vqa_one para explicar simultáneamente ambos modelos sobre la misma pregunta (usa los candidatos generados por datasets.vqa_med_2019).plot_vqa_comparison normaliza automáticamente los grids de parches (todos quedan en 7×7) y crea colorbars independientes para texto e imagen.experiments/compare_vqa_models.py y los heatmaps en outputs/vqa_heatmaps/ se apoyan en este módulo.batch_shap_analysis + experiments/analyze_batch_results.py conforman el flujo de análisis masivo: primero se genera un CSV con los SHAP por modelo, luego el notebook produce tablas y gráficos listos para reportes.estadisticas_descriptivas.csv, metricas_balance_multimodal.csv, etc.) como figuras (dashboard_completo.png, ranking_balance_modelos.png, ...) directamente en outputs/analysis/.outputs/analysis/ contiene gráficas y tablas ya renderizadas:
balance_score_comparison.png, ranking_balance_modelos.png → ranking visual del modelo más balanceado.boxplot_iscore.png, violinplot_iscore.png, boxplots_iscore_tscore.png, violinplots_iscore_tscore.png → distribución detallada de IScores/TScores.heatmap_correlaciones.png, scatter_iscore_vs_tscore.png, scatter_caption_length_vs_iscore.png → correlaciones entre modelos y con la longitud del caption.tabla_iscore_promedio.png y el dashboard_completo.png listos para presentaciones.outputs/isa_heatmaps/ agrupa más de 100 PNG con los heatmaps ISA generados por compare_all_models.py (uno por modelo y muestra).outputs/vqa_heatmaps/ incluye 88 visualizaciones VQA (PubMedCLIP y BioMedCLIP) con grids normalizados y palabras coloreadas.estadisticas_descriptivas.csv, metricas_balance_multimodal.csv, analisis_estadisticos_inferenciales.csv, etc.) dentro de outputs/analysis/ cada vez que se ejecuta el flujo de análisis.💡 Recomendación: Si prefieres configurar todo automáticamente, usa el script de instalación rápida en su lugar.
Esta sección describe cómo instalar manualmente el proyecto paso a paso. Útil si quieres tener más control sobre cada etapa o si el script automático no funciona en tu sistema.
git clone https://github.com/Alberto-97sc/mmshap_medclip.git
cd mmshap_medclip
Instalación básica:
pip install -e .
💡 Esto instala las dependencias incluyendo
gdown, pero NO descarga el dataset. El dataset se descarga en el paso siguiente.
Instalación con soporte para notebooks (recomendado):
pip install -e ".[notebooks]"
Instalación con herramientas de desarrollo (opcional):
pip install -e ".[dev]"
Instalación completa (notebooks + dev):
pip install -e ".[notebooks,dev]"
💡 Poola opción
-einstala el paquete en modo editable, permitiendo que cualquier cambio ensrc/se refleje inmediatamente sin necesidad de reinstalar.
El repositorio incluye scripts automáticos para descargar el dataset desde Google Drive:
# Descargar dataset usando gdown (más confiable)
python scripts/download_dataset.py
Este script:
data/ si no existegdowndata/dataset_roco.zipSi el script automático no funciona, puedes descargar manualmente:
data/dataset_roco.zip# Instalar gdown si no está instalado
pip install gdown
# Descargar directamente
gdown 1eRUC8F8PtXffa9iArJnyB8AMqlPNoSwc -O data/dataset_roco.zip
⚠️ El conjunto VQA-Med 2019 requiere registro en ImageCLEF. El script y las instrucciones suponen que ya cuentas con permisos para descargar el ZIP oficial. El loader soporta los splits Training / Validation / Test y las categorías C1–C4 (Modality, Plane, Organ System, Abnormality).
python scripts/download_vqa_med_2019.py
El script:
data/ si no existe.VQA-Med-2019.zip vía gdown (no lo descomprime).ImageClef-2019-VQA-Med-Training.zip o los sub-zips correspondientes.ImageClef-2019-VQA-Med-Training.zip o el paquete completo VQA-Med-2019.zip.data/. Se soportan ambas rutas:
data/ImageClef-2019-VQA-Med-Training.zipdata/VQA-Med-2019.zip (el loader abrirá automáticamente el ZIP interno correcto para el split seleccionado)ImageClef-2019-VQA-Med-Training/
├── QAPairsByCategory/
│ ├── C1_Modality_train.txt
│ ├── C2_Plane_train.txt
│ ├── C3_Organ_train.txt
│ └── C4_Abnormality_train.txt
└── Train_images/
├── xxx.jpg
└── ...
configs/vqa_med_2019_pubmedclip.yaml):
dataset:
name: vqa_med_2019
params:
zip_path: data/ImageClef-2019-VQA-Med-Training.zip # o data/VQA-Med-2019.zip
split: Training
images_subdir: Train_images
n_rows: all
📊 Split seleccionado: TRAINING
📁 Archivos a leer para split TRAINING: ['C1_Modality_train.txt', ...]
📊 Construyendo candidatos por categoría...
Si aparece un error sobre candidatos vacíos o rutas inválidas, revisa que los archivos C1–C4 estén dentro de QAPairsByCategory/ y que las imágenes residan en la carpeta correcta (Train_images, Val_images o VQAMed2019_Test_Images según el split).Los scripts en experiments/ están en formato Jupytext (.py), lo que permite versionarlos fácilmente y convertirlos a notebooks Jupyter.
# Convertir un script específico (ejemplo con PubMedCLIP)
jupytext --to notebook experiments/pubmedclip_roco_isa.py
# Convertir otro script (ejemplo con Rclip)
jupytext --to notebook experiments/rclip_roco_isa.py
# Convertir todos los scripts
jupytext --to notebook experiments/*.py
Esto generará archivos .ipynb que puedes abrir con Jupyter Notebook o JupyterLab.
# Actualizar un notebook específico
jupytext --sync experiments/pubmedclip_roco_isa.py
jupytext --sync experiments/rclip_roco_isa.py
# O actualizar todos
jupytext --sync experiments/*.py
# Convertir un notebook específico de vuelta a script
jupytext --to py:percent experiments/pubmedclip_roco_isa.ipynb
jupytext --to py:percent experiments/rclip_roco_isa.ipynb
# 1. Clonar y configurar todo automáticamente
git clone https://github.com/Alberto-97sc/mmshap_medclip.git
cd mmshap_medclip
./setup.sh
# 2. Ejecutar cualquier experimento directamente
python3 experiments/pubmedclip_roco_isa.py
python3 experiments/whyxrayclip_roco_isa.py
python3 experiments/rclip_roco_isa.py
python3 experiments/biomedclip_roco_isa.py
# 1. Descargar datasets necesarios
python3 scripts/download_dataset.py
# (opcional) python3 scripts/download_vqa_med_2019.py # solo si usarás VQA-Med
# 2. Ejecutar experimento con PubMedCLIP
python3 experiments/pubmedclip_roco_isa.py
# 3. Ejecutar experimento con WhyXrayCLIP
python3 experiments/whyxrayclip_roco_isa.py
# 4. Ejecutar experimento con Rclip
python3 experiments/rclip_roco_isa.py
# 5. Ejecutar experimento con BiomedCLIP
python3 experiments/biomedclip_roco_isa.py
# Si usaste setup.sh, los notebooks ya están creados:
jupyter notebook
# Abrir cualquiera de los notebooks disponibles:
# - experiments/pubmedclip_roco_isa.ipynb
# - experiments/whyxrayclip_roco_isa.ipynb
# - experiments/rclip_roco_isa.ipynb
# - experiments/biomedclip_roco_isa.ipynb
# Seleccionar cualquier kernel de Python 3.12
# Si instalaste manualmente, convierte primero:
jupytext --to notebook experiments/*.py
jupyter notebook
Nuevo: Ahora puedes comparar los 4 modelos en la misma muestra con un solo script:
# Ejecutar comparación
python3 experiments/compare_all_models.py
# O como notebook
jupytext --to notebook experiments/compare_all_models.py
jupyter notebook experiments/compare_all_models.ipynb
Características:
Ejemplo de uso programático:
from mmshap_medclip.comparison import (
load_all_models,
run_shap_on_all_models,
plot_comparison_simple,
print_summary
)
from mmshap_medclip.devices import get_device
from mmshap_medclip.io_utils import load_config
from mmshap_medclip.registry import build_dataset
# Setup
device = get_device()
cfg = load_config("configs/roco_isa_pubmedclip.yaml")
dataset = build_dataset(cfg["dataset"])
# Cargar los 4 modelos
models = load_all_models(device)
# Analizar muestra 154
results, image, caption = run_shap_on_all_models(
models, sample_idx=154, dataset=dataset, device=device
)
# Visualizar comparación
fig = plot_comparison_simple(results, image, caption, sample_idx=154)
plt.show()
# Imprimir resumen
print_summary(results)
Ver documentación completa en: experiments/README_compare_models.md
# 1. Asegúrate de tener data/VQA-Med-2019.zip o ImageClef-2019-VQA-Med-Training.zip
# 2. Ejecuta el comparador VQA (script o notebook)
python3 experiments/compare_vqa_models.py
# o
jupytext --to notebook experiments/compare_vqa_models.py
jupyter notebook experiments/compare_vqa_models.ipynb
Qué hace este flujo:
vqa_med_2019 (solo split Training, categorías C1–C3)outputs/vqa/ y analizar múltiples índices en batchConsejo: modifica
dataset_paramsyMUESTRA_A_ANALIZARdirectamente en el notebook/script para apuntar a otra ruta de dataset o a otra muestra específica.
Ejemplo con PubMedCLIP:
from mmshap_medclip.io_utils import load_config
from mmshap_medclip.devices import get_device
from mmshap_medclip.registry import build_dataset, build_model
from mmshap_medclip.tasks.isa import run_isa_one
# Cargar configuración
cfg = load_config("configs/roco_isa_pubmedclip.yaml")
# Obtener device (CUDA si está disponible)
device = get_device()
# Cargar dataset y modelo
dataset = build_dataset(cfg["dataset"])
model = build_model(cfg["model"], device=device)
print(f"Dataset cargado: {len(dataset)} muestras")
print(f"Device: {device}")
# Ejecutar evaluación en una muestra
sample = dataset[154]
image, caption = sample['image'], sample['text']
res = run_isa_one(model, image, caption, device, explain=True, plot=True)
print(f"logit={res['logit']:.4f} TScore={res['tscore']:.2%} IScore={res['iscore']:.2%}")
Ejemplo con Rclip (similar para WhyXrayCLIP):
from mmshap_medclip.io_utils import load_config
from mmshap_medclip.devices import get_device
from mmshap_medclip.registry import build_dataset, build_model
from mmshap_medclip.tasks.isa import run_isa_one
# Cargar configuración de Rclip
cfg = load_config("configs/roco_isa_rclip.yaml")
# Obtener device (CUDA si está disponible)
device = get_device()
# Cargar dataset y modelo
dataset = build_dataset(cfg["dataset"])
model = build_model(cfg["model"], device=device)
print(f"Dataset cargado: {len(dataset)} muestras")
print(f"Device: {device}")
# Ejecutar evaluación en una muestra
sample = dataset[154]
image, caption = sample['image'], sample['text']
res = run_isa_one(model, image, caption, device, explain=True, plot=True)
print(f"logit={res['logit']:.4f} TScore={res['tscore']:.2%} IScore={res['iscore']:.2%}")
configs/roco_isa_pubmedclip.yamlexperiment_name: demo_roco_sample
device: auto
dataset:
name: roco
params:
zip_path: data/dataset_roco.zip
split: validation
n_rows: all
columns:
image_key: name
caption_key: caption
images_subdir: all_data/validation/radiology/images
model:
name: pubmedclip-vit-b32
params: {}
configs/roco_isa_whyxrayclip.yamlexperiment_name: demo_roco_whyxrayclip
device: auto
dataset:
name: roco
params:
zip_path: data/dataset_roco.zip
split: validation
n_rows: all
columns:
image_key: name
caption_key: caption
images_subdir: all_data/validation/radiology/images
model:
name: whyxrayclip
params:
model_name: hf-hub:yyupenn/whyxrayclip
tokenizer_name: ViT-L-14
configs/roco_isa_rclip.yamlexperiment_name: demo_roco_rclip
device: auto
dataset:
name: roco
params:
zip_path: data/dataset_roco.zip
split: validation
n_rows: all
columns:
image_key: name
caption_key: caption
images_subdir: all_data/validation/radiology/images
model:
name: rclip
params:
model_name: kaveh/rclip
configs/roco_isa_biomedclip.yamlexperiment_name: demo_roco_biomedclip
device: auto
dataset:
name: roco
params:
zip_path: data/dataset_roco.zip
split: validation
n_rows: all
columns:
image_key: name
caption_key: caption
images_subdir: all_data/validation/radiology/images
model:
name: biomedclip
params:
model_name: hf-hub:microsoft/BiomedCLIP-PubMedBERT_256-vit_base_patch16_224
configs/vqa_med_2019_pubmedclip.yamlexperiment_name: vqa_med_2019_pubmedclip
device: auto
dataset:
name: vqa_med_2019
params:
zip_path: data/ImageClef-2019-VQA-Med-Training.zip # o data/VQA-Med-2019.zip
split: Training
images_subdir: Train_images
n_rows: all
model:
name: pubmedclip-vit-b32
params: {}
MIT
Proyecto de tesis: Medición del balance multimodal con SHAP en CLIP médico
Pipeline modular para medir el balance multimodal con SHAP en modelos tipo CLIP (incluye PubMedCLIP, WhyXrayCLIP, Rclip y BiomedCLIP) sobre datasets médicos como ROCO (Image-Sentence Alignment) y VQA-Med 2019 (Visual Question Answering). Diseñado para ejecución local con datasets descargados desde Google Drive u orígenes oficiales.
🚀 Instalación en un solo click: Ejecuta
./setup.shy tendrás todo listo automáticamente. Ver Instalación Rápida.
Esta versión utiliza instalación con
pyproject.tomly uso depip install -e ..
Si quieres configurar todo el entorno en un solo comando, usa el script de instalación automática:
git clone https://github.com/Alberto-97sc/mmshap_medclip.git
cd mmshap_medclip
./setup.sh
┌─────────────────────────────────────────────────────────┐
│ ./setup.sh │
└─────────────────────────────────────────────────────────┘
│
┌───────────────────┼───────────────────┐
▼ ▼ ▼
[Verificar Python] [Configurar Git] [Instalar deps]
│ │ │
└───────────────────┼───────────────────┘
│
▼
[Descargar dataset]
│
▼
[Convertir scripts a notebooks]
│
▼
✅ ¡LISTO!
El script setup.sh automatiza completamente la configuración del proyecto en 5 pasos:
🐍 Verifica e instala Python3 (si no está presente en el sistema)
📝 Configura Git con las credenciales del proyecto
user.name: Alberto-97scuser.email: [email protected]📦 Instala todas las dependencias
pip install -e .)📥 Descarga automática de datasets médicos
scripts/download_dataset.py para obtener ROCO en data/dataset_roco.zipscripts/download_vqa_med_2019.py para guardar data/VQA-Med-2019.zip (solo si cuentas con permisos de ImageCLEF)📓 Convierte scripts a notebooks Jupyter
.ipynb en el directorio experiments/Cuando ejecutes ./setup.sh, verás algo similar a esto:
╔════════════════════════════════════════════════════════════════╗
║ Inicializando proyecto mmshap_medclip ║
╚════════════════════════════════════════════════════════════════╝
🐍 [1/5] Verificando instalación de Python...
✅ Python ya está instalado (versión 3.12.12)
📝 [2/5] Configurando Git...
✅ Git configurado correctamente
Usuario: Alberto-97sc
Email: [email protected]
📦 [3/5] Instalando dependencias...
→ Actualizando pip...
→ Instalando mmshap_medclip con soporte para notebooks...
✅ Dependencias instaladas correctamente
✓ Paquete mmshap_medclip en modo editable
✓ Dependencias para notebooks (jupytext, jupyter)
📥 [4/5] Descargando datasets desde Google Drive...
📥 [4.1/5] Dataset ROCO → data/dataset_roco.zip
✅ Descarga completada
📥 [4.2/5] Dataset VQA-Med 2019 → data/VQA-Med-2019.zip
✅ Descarga completada (o se reutiliza el archivo existente)
📓 [5/5] Convirtiendo scripts a notebooks Jupyter...
✅ Notebooks creados en experiments/
- experiments/pubmedclip_roco_isa.ipynb
- experiments/whyxrayclip_roco_isa.ipynb
- experiments/rclip_roco_isa.ipynb
- experiments/biomedclip_roco_isa.ipynb
╔════════════════════════════════════════════════════════════════╗
║ ✅ INSTALACIÓN COMPLETADA EXITOSAMENTE ║
╚════════════════════════════════════════════════════════════════╝
Una vez completada la instalación, solo necesitas:
# Ejecutar un experimento directamente
python3 experiments/pubmedclip_roco_isa.py
python3 experiments/whyxrayclip_roco_isa.py
python3 experiments/rclip_roco_isa.py
O usar los notebooks generados:
# Iniciar Jupyter Notebook
jupyter notebook
# Luego abrir: experiments/pubmedclip_roco_isa.ipynb
# Seleccionar cualquier kernel de Python 3.12
sudo si Python no está instaladoSi deseas modificar la configuración de Git, edita las siguientes líneas en setup.sh:
git config user.name "TuUsuario"
git config user.email "[email protected]"
Error: Permission denied al ejecutar ./setup.sh
# Dar permisos de ejecución al script
chmod +x setup.sh
./setup.sh
Error: Python no se instaló automáticamente
sudo para instalar Pythonsudo apt-get install python3 python3-pip # Debian/Ubuntu
# o
sudo yum install python3 python3-pip # RedHat/CentOS
Error al descargar el dataset
data/dataset_roco.zipError de importación en notebooks
mmshap_medclip/
├── src/mmshap_medclip/
│ ├── __init__.py
│ ├── comparison.py # compara 4 modelos ISA + batch SHAP
│ ├── comparison_vqa.py # comparador PubMedCLIP vs BioMedCLIP en VQA-Med
│ ├── devices.py # manejo de device (CUDA/CPU)
│ ├── registry.py # registro de modelos y datasets
│ ├── models.py # wrappers de CLIP (PubMedCLIP, WhyXrayCLIP, RCLIP, BioMedCLIP)
│ ├── io_utils.py # cargar configs YAML
│ ├── metrics.py # MM-score, IScore
│ ├── datasets/
│ │ ├── __init__.py
│ │ ├── base.py # interfaz DatasetBase
│ │ ├── roco.py # loader ROCO (lee ZIP local)
│ │ └── vqa_med_2019.py # loader VQA-Med 2019 (splits Training/Val/Test)
│ ├── tasks/
│ │ ├── __init__.py
│ │ ├── isa.py # tarea Image-Sentence Alignment
│ │ ├── vqa.py # tarea VQA + SHAP + visualizaciones
│ │ ├── utils.py # prepare_batch, token lengths, etc.
│ │ └── whyxrayclip.py # utilidades específicas WhyXrayCLIP
│ ├── shap_tools/
│ │ ├── masker.py # build_masker (BOS/EOS safe)
│ │ ├── predictor.py # predictor ISA
│ │ └── vqa_predictor.py # predictor especializado para VQA
│ └── vis/
│ └── heatmaps.py # mapas de calor imagen+texto
├── experiments/
│ ├── analyze_batch_results.py # dashboard estadístico desde batch_shap_results.csv
│ ├── biomedclip_roco_isa.py
│ ├── compare_all_models.py # comparador 4 modelos ISA (script/notebook)
│ ├── compare_vqa_models.py # comparador VQA
│ ├── pubmedclip_roco_isa.py
│ ├── rclip_roco_isa.py
│ ├── README_compare_models.md # guía detallada del comparador
│ └── whyxrayclip_roco_isa.py
├── outputs/
│ ├── analysis/ # dashboards (tabla_iscore_promedio.png, etc.)
│ ├── isa_heatmaps/ # >100 heatmaps ISA (png)
│ └── vqa_heatmaps/ # 80+ heatmaps VQA
├── configs/
│ ├── roco_isa_pubmedclip.yaml
│ ├── roco_isa_whyxrayclip.yaml
│ ├── roco_isa_rclip.yaml
│ ├── roco_isa_biomedclip.yaml
│ └── vqa_med_2019_pubmedclip.yaml
├── scripts/
│ ├── download_dataset.py # descarga ROCO
│ └── download_vqa_med_2019.py # descarga VQA-Med 2019 (ZIP completo)
├── data/ # carpeta para datasets (no versionada)
├── documentation_tecnica.md
├── REPORTE_TECNICO_MM_SHAP_MEDCLIP.md
├── setup.sh # script de instalación automática (un solo click)
├── pyproject.toml # configuración del proyecto y dependencias
├── test_alpha_adjustment.py
└── README.md
El directorio experiments/ contiene scripts completos listos para ejecutar localmente o convertir a notebooks:
pubmedclip_roco_isa.pyconfigs/roco_isa_pubmedclip.yamlwhyxrayclip_roco_isa.pyconfigs/roco_isa_whyxrayclip.yamlrclip_roco_isa.pyconfigs/roco_isa_rclip.yamlbiomedclip_roco_isa.pyconfigs/roco_isa_biomedclip.yamlcompare_vqa_models.py.py y .ipynb para ejecución directa o notebookvqa_med_2019 que arma candidatos por categoríacompare_all_models.pysrc/mmshap_medclip/comparison.py (usa load_all_models, run_shap_on_all_models, plot_comparison_simple y save_comparison).outputs/comparison_sample_XX.png) y resúmenes JSON.experiments/README_compare_models.md.analyze_batch_results.pyoutputs/batch_shap_results.csv generado con comparison.batch_shap_analysis.outputs/analysis/ (dashboard_completo.png, boxplot_iscore.png, balance_score_comparison.png, tablas CSV, etc.).Todos los experimentos incluyen:
src/mmshap_medclip/comparison.py)load_all_models, run_shap_on_all_models y plot_comparison_simple permiten levantar los 4 modelos médicos y generar una figura conjunta (imagen + texto coloreado) con métricas logit/TScore/IScore.plot_individual_heatmaps y save_comparison facilitan guardar PNG/JSON en outputs/.analyze_multiple_samples resume SHAP de varios índices y devuelve un DataFrame.batch_shap_analysis ejecuta SHAP en rangos grandes de muestras, es idempotente (retoma donde se quedó, detecta NaN y vuelve a procesar) y escribe outputs/batch_shap_results.csv, que luego usa el notebook de análisis.from mmshap_medclip.comparison import load_all_models, batch_shap_analysis
from mmshap_medclip.devices import get_device
from mmshap_medclip.io_utils import load_config
from mmshap_medclip.registry import build_dataset
device = get_device()
cfg = load_config("configs/roco_isa_pubmedclip.yaml")
dataset = build_dataset(cfg["dataset"])
models = load_all_models(device)
df = batch_shap_analysis(
models=models,
dataset=dataset,
device=device,
start_idx=0,
end_idx=500,
csv_path="outputs/batch_shap_results.csv",
)
src/mmshap_medclip/comparison_vqa.py)load_vqa_models levanta PubMedCLIP y BioMedCLIP, respetando las preferencias de visualización de cada wrapper.run_vqa_shap_on_models usa tasks.vqa.run_vqa_one para explicar simultáneamente ambos modelos sobre la misma pregunta (usa los candidatos generados por datasets.vqa_med_2019).plot_vqa_comparison normaliza automáticamente los grids de parches (todos quedan en 7×7) y crea colorbars independientes para texto e imagen.experiments/compare_vqa_models.py y los heatmaps en outputs/vqa_heatmaps/ se apoyan en este módulo.batch_shap_analysis + experiments/analyze_batch_results.py conforman el flujo de análisis masivo: primero se genera un CSV con los SHAP por modelo, luego el notebook produce tablas y gráficos listos para reportes.estadisticas_descriptivas.csv, metricas_balance_multimodal.csv, etc.) como figuras (dashboard_completo.png, ranking_balance_modelos.png, ...) directamente en outputs/analysis/.outputs/analysis/ contiene gráficas y tablas ya renderizadas:
balance_score_comparison.png, ranking_balance_modelos.png → ranking visual del modelo más balanceado.boxplot_iscore.png, violinplot_iscore.png, boxplots_iscore_tscore.png, violinplots_iscore_tscore.png → distribución detallada de IScores/TScores.heatmap_correlaciones.png, scatter_iscore_vs_tscore.png, scatter_caption_length_vs_iscore.png → correlaciones entre modelos y con la longitud del caption.tabla_iscore_promedio.png y el dashboard_completo.png listos para presentaciones.outputs/isa_heatmaps/ agrupa más de 100 PNG con los heatmaps ISA generados por compare_all_models.py (uno por modelo y muestra).outputs/vqa_heatmaps/ incluye 88 visualizaciones VQA (PubMedCLIP y BioMedCLIP) con grids normalizados y palabras coloreadas.estadisticas_descriptivas.csv, metricas_balance_multimodal.csv, analisis_estadisticos_inferenciales.csv, etc.) dentro de outputs/analysis/ cada vez que se ejecuta el flujo de análisis.💡 Recomendación: Si prefieres configurar todo automáticamente, usa el script de instalación rápida en su lugar.
Esta sección describe cómo instalar manualmente el proyecto paso a paso. Útil si quieres tener más control sobre cada etapa o si el script automático no funciona en tu sistema.
git clone https://github.com/Alberto-97sc/mmshap_medclip.git
cd mmshap_medclip
Instalación básica:
pip install -e .
💡 Esto instala las dependencias incluyendo
gdown, pero NO descarga el dataset. El dataset se descarga en el paso siguiente.
Instalación con soporte para notebooks (recomendado):
pip install -e ".[notebooks]"
Instalación con herramientas de desarrollo (opcional):
pip install -e ".[dev]"
Instalación completa (notebooks + dev):
pip install -e ".[notebooks,dev]"
💡 Poola opción
-einstala el paquete en modo editable, permitiendo que cualquier cambio ensrc/se refleje inmediatamente sin necesidad de reinstalar.
El repositorio incluye scripts automáticos para descargar el dataset desde Google Drive:
# Descargar dataset usando gdown (más confiable)
python scripts/download_dataset.py
Este script:
data/ si no existegdowndata/dataset_roco.zipSi el script automático no funciona, puedes descargar manualmente:
data/dataset_roco.zip# Instalar gdown si no está instalado
pip install gdown
# Descargar directamente
gdown 1eRUC8F8PtXffa9iArJnyB8AMqlPNoSwc -O data/dataset_roco.zip
⚠️ El conjunto VQA-Med 2019 requiere registro en ImageCLEF. El script y las instrucciones suponen que ya cuentas con permisos para descargar el ZIP oficial. El loader soporta los splits Training / Validation / Test y las categorías C1–C4 (Modality, Plane, Organ System, Abnormality).
python scripts/download_vqa_med_2019.py
El script:
data/ si no existe.VQA-Med-2019.zip vía gdown (no lo descomprime).ImageClef-2019-VQA-Med-Training.zip o los sub-zips correspondientes.ImageClef-2019-VQA-Med-Training.zip o el paquete completo VQA-Med-2019.zip.data/. Se soportan ambas rutas:
data/ImageClef-2019-VQA-Med-Training.zipdata/VQA-Med-2019.zip (el loader abrirá automáticamente el ZIP interno correcto para el split seleccionado)ImageClef-2019-VQA-Med-Training/
├── QAPairsByCategory/
│ ├── C1_Modality_train.txt
│ ├── C2_Plane_train.txt
│ ├── C3_Organ_train.txt
│ └── C4_Abnormality_train.txt
└── Train_images/
├── xxx.jpg
└── ...
configs/vqa_med_2019_pubmedclip.yaml):
dataset:
name: vqa_med_2019
params:
zip_path: data/ImageClef-2019-VQA-Med-Training.zip # o data/VQA-Med-2019.zip
split: Training
images_subdir: Train_images
n_rows: all
📊 Split seleccionado: TRAINING
📁 Archivos a leer para split TRAINING: ['C1_Modality_train.txt', ...]
📊 Construyendo candidatos por categoría...
Si aparece un error sobre candidatos vacíos o rutas inválidas, revisa que los archivos C1–C4 estén dentro de QAPairsByCategory/ y que las imágenes residan en la carpeta correcta (Train_images, Val_images o VQAMed2019_Test_Images según el split).Los scripts en experiments/ están en formato Jupytext (.py), lo que permite versionarlos fácilmente y convertirlos a notebooks Jupyter.
# Convertir un script específico (ejemplo con PubMedCLIP)
jupytext --to notebook experiments/pubmedclip_roco_isa.py
# Convertir otro script (ejemplo con Rclip)
jupytext --to notebook experiments/rclip_roco_isa.py
# Convertir todos los scripts
jupytext --to notebook experiments/*.py
Esto generará archivos .ipynb que puedes abrir con Jupyter Notebook o JupyterLab.
# Actualizar un notebook específico
jupytext --sync experiments/pubmedclip_roco_isa.py
jupytext --sync experiments/rclip_roco_isa.py
# O actualizar todos
jupytext --sync experiments/*.py
# Convertir un notebook específico de vuelta a script
jupytext --to py:percent experiments/pubmedclip_roco_isa.ipynb
jupytext --to py:percent experiments/rclip_roco_isa.ipynb
# 1. Clonar y configurar todo automáticamente
git clone https://github.com/Alberto-97sc/mmshap_medclip.git
cd mmshap_medclip
./setup.sh
# 2. Ejecutar cualquier experimento directamente
python3 experiments/pubmedclip_roco_isa.py
python3 experiments/whyxrayclip_roco_isa.py
python3 experiments/rclip_roco_isa.py
python3 experiments/biomedclip_roco_isa.py
# 1. Descargar datasets necesarios
python3 scripts/download_dataset.py
# (opcional) python3 scripts/download_vqa_med_2019.py # solo si usarás VQA-Med
# 2. Ejecutar experimento con PubMedCLIP
python3 experiments/pubmedclip_roco_isa.py
# 3. Ejecutar experimento con WhyXrayCLIP
python3 experiments/whyxrayclip_roco_isa.py
# 4. Ejecutar experimento con Rclip
python3 experiments/rclip_roco_isa.py
# 5. Ejecutar experimento con BiomedCLIP
python3 experiments/biomedclip_roco_isa.py
# Si usaste setup.sh, los notebooks ya están creados:
jupyter notebook
# Abrir cualquiera de los notebooks disponibles:
# - experiments/pubmedclip_roco_isa.ipynb
# - experiments/whyxrayclip_roco_isa.ipynb
# - experiments/rclip_roco_isa.ipynb
# - experiments/biomedclip_roco_isa.ipynb
# Seleccionar cualquier kernel de Python 3.12
# Si instalaste manualmente, convierte primero:
jupytext --to notebook experiments/*.py
jupyter notebook
Nuevo: Ahora puedes comparar los 4 modelos en la misma muestra con un solo script:
# Ejecutar comparación
python3 experiments/compare_all_models.py
# O como notebook
jupytext --to notebook experiments/compare_all_models.py
jupyter notebook experiments/compare_all_models.ipynb
Características:
Ejemplo de uso programático:
from mmshap_medclip.comparison import (
load_all_models,
run_shap_on_all_models,
plot_comparison_simple,
print_summary
)
from mmshap_medclip.devices import get_device
from mmshap_medclip.io_utils import load_config
from mmshap_medclip.registry import build_dataset
# Setup
device = get_device()
cfg = load_config("configs/roco_isa_pubmedclip.yaml")
dataset = build_dataset(cfg["dataset"])
# Cargar los 4 modelos
models = load_all_models(device)
# Analizar muestra 154
results, image, caption = run_shap_on_all_models(
models, sample_idx=154, dataset=dataset, device=device
)
# Visualizar comparación
fig = plot_comparison_simple(results, image, caption, sample_idx=154)
plt.show()
# Imprimir resumen
print_summary(results)
Ver documentación completa en: experiments/README_compare_models.md
# 1. Asegúrate de tener data/VQA-Med-2019.zip o ImageClef-2019-VQA-Med-Training.zip
# 2. Ejecuta el comparador VQA (script o notebook)
python3 experiments/compare_vqa_models.py
# o
jupytext --to notebook experiments/compare_vqa_models.py
jupyter notebook experiments/compare_vqa_models.ipynb
Qué hace este flujo:
vqa_med_2019 (solo split Training, categorías C1–C3)outputs/vqa/ y analizar múltiples índices en batchConsejo: modifica
dataset_paramsyMUESTRA_A_ANALIZARdirectamente en el notebook/script para apuntar a otra ruta de dataset o a otra muestra específica.
Ejemplo con PubMedCLIP:
from mmshap_medclip.io_utils import load_config
from mmshap_medclip.devices import get_device
from mmshap_medclip.registry import build_dataset, build_model
from mmshap_medclip.tasks.isa import run_isa_one
# Cargar configuración
cfg = load_config("configs/roco_isa_pubmedclip.yaml")
# Obtener device (CUDA si está disponible)
device = get_device()
# Cargar dataset y modelo
dataset = build_dataset(cfg["dataset"])
model = build_model(cfg["model"], device=device)
print(f"Dataset cargado: {len(dataset)} muestras")
print(f"Device: {device}")
# Ejecutar evaluación en una muestra
sample = dataset[154]
image, caption = sample['image'], sample['text']
res = run_isa_one(model, image, caption, device, explain=True, plot=True)
print(f"logit={res['logit']:.4f} TScore={res['tscore']:.2%} IScore={res['iscore']:.2%}")
Ejemplo con Rclip (similar para WhyXrayCLIP):
from mmshap_medclip.io_utils import load_config
from mmshap_medclip.devices import get_device
from mmshap_medclip.registry import build_dataset, build_model
from mmshap_medclip.tasks.isa import run_isa_one
# Cargar configuración de Rclip
cfg = load_config("configs/roco_isa_rclip.yaml")
# Obtener device (CUDA si está disponible)
device = get_device()
# Cargar dataset y modelo
dataset = build_dataset(cfg["dataset"])
model = build_model(cfg["model"], device=device)
print(f"Dataset cargado: {len(dataset)} muestras")
print(f"Device: {device}")
# Ejecutar evaluación en una muestra
sample = dataset[154]
image, caption = sample['image'], sample['text']
res = run_isa_one(model, image, caption, device, explain=True, plot=True)
print(f"logit={res['logit']:.4f} TScore={res['tscore']:.2%} IScore={res['iscore']:.2%}")
configs/roco_isa_pubmedclip.yamlexperiment_name: demo_roco_sample
device: auto
dataset:
name: roco
params:
zip_path: data/dataset_roco.zip
split: validation
n_rows: all
columns:
image_key: name
caption_key: caption
images_subdir: all_data/validation/radiology/images
model:
name: pubmedclip-vit-b32
params: {}
configs/roco_isa_whyxrayclip.yamlexperiment_name: demo_roco_whyxrayclip
device: auto
dataset:
name: roco
params:
zip_path: data/dataset_roco.zip
split: validation
n_rows: all
columns:
image_key: name
caption_key: caption
images_subdir: all_data/validation/radiology/images
model:
name: whyxrayclip
params:
model_name: hf-hub:yyupenn/whyxrayclip
tokenizer_name: ViT-L-14
configs/roco_isa_rclip.yamlexperiment_name: demo_roco_rclip
device: auto
dataset:
name: roco
params:
zip_path: data/dataset_roco.zip
split: validation
n_rows: all
columns:
image_key: name
caption_key: caption
images_subdir: all_data/validation/radiology/images
model:
name: rclip
params:
model_name: kaveh/rclip
configs/roco_isa_biomedclip.yamlexperiment_name: demo_roco_biomedclip
device: auto
dataset:
name: roco
params:
zip_path: data/dataset_roco.zip
split: validation
n_rows: all
columns:
image_key: name
caption_key: caption
images_subdir: all_data/validation/radiology/images
model:
name: biomedclip
params:
model_name: hf-hub:microsoft/BiomedCLIP-PubMedBERT_256-vit_base_patch16_224
configs/vqa_med_2019_pubmedclip.yamlexperiment_name: vqa_med_2019_pubmedclip
device: auto
dataset:
name: vqa_med_2019
params:
zip_path: data/ImageClef-2019-VQA-Med-Training.zip # o data/VQA-Med-2019.zip
split: Training
images_subdir: Train_images
n_rows: all
model:
name: pubmedclip-vit-b32
params: {}
MIT
Proyecto de tesis: Medición del balance multimodal con SHAP en CLIP médico