TB-Guard-XAI-v2 / run_explainer.py
Vignesh19's picture
Upload run_explainer.py with huggingface_hub
3faff25 verified
Raw
History Blame Contribute Delete
2.07 kB
"""
TB-Guard-XAI Β· End-to-end pipeline example
Image β†’ Preprocess β†’ Ensemble β†’ Grad-CAM++ β†’ Mistral clinical report
"""
import cv2
import torch
import numpy as np
from preprocessing import LungPreprocessor, get_val_transforms
from ensemble_models import load_ensemble
from gradcam import GradCAMPlusPlus
from mistral_explainer import MistralExplainer
def run(image_path: str, checkpoint: str = None, api_key: str = None):
device = "cuda" if torch.cuda.is_available() else "cpu"
# 1. Load model
model = load_ensemble(checkpoint, device=device)
# 2. Preprocess X-ray
preprocessor = LungPreprocessor(image_size=224)
image_np = preprocessor.preprocess(image_path, segment_lung=True) # (224,224) uint8
transforms = get_val_transforms(224)
tensor = transforms(image=image_np)["image"].unsqueeze(0).to(device) # (1,1,224,224)
# 3. Grad-CAM++ β†’ structured output
gcam = GradCAMPlusPlus(model, device=device)
output = gcam.explain(
tensor,
threshold=0.5,
n_mc_samples=20,
# Wire in ExplainabilityValidator results if available:
radiologist_agreement=0.75,
n_radiologists=4,
explanation_valid_votes=3,
)
# 4. Save overlay image
overlay = gcam.heatmap_overlay(image_np, np.zeros((224,224), dtype=np.float32))
cv2.imwrite("gradcam_overlay.png", overlay)
print(f"Overlay saved β†’ gradcam_overlay.png")
# 5. Mistral clinical report
explainer = MistralExplainer(api_key=api_key)
report = explainer.generate_report(output)
report.print_report()
report.save("tb_report.json")
return report
if __name__ == "__main__":
import argparse
p = argparse.ArgumentParser()
p.add_argument("image", help="Path to chest X-ray (PNG/JPG/DICOM)")
p.add_argument("--checkpoint", default=None, help="Path to ensemble .pth weights")
p.add_argument("--api-key", default=None, help="Mistral API key (or set MISTRAL_API_KEY)")
args = p.parse_args()
run(args.image, args.checkpoint, args.api_key)