| """ |
| explainability/gradcam.py |
| ------------------------- |
| Implements Grad-CAM for ViT using pytorch-grad-cam. |
| """ |
|
|
| import numpy as np |
| import torch |
| import cv2 |
| from pytorch_grad_cam import GradCAM |
| from pytorch_grad_cam.utils.image import show_cam_on_image |
|
|
| def reshape_transform(tensor, height=14, width=14): |
| """ |
| Reshape transform specifically for ViT models. |
| Removes the CLS token and reshapes the sequence of patch tokens |
| back into a 2D spatial feature map. |
| """ |
| |
| result = tensor[:, 1:, :].reshape(tensor.size(0), |
| height, width, tensor.size(2)) |
|
|
| |
| result = result.transpose(2, 3).transpose(1, 2) |
| return result |
|
|
| def generate_gradcam_heatmap( |
| model, |
| image_tensor: torch.Tensor, |
| target_class: int, |
| original_image: np.ndarray = None, |
| image_size: int = 224, |
| ) -> np.ndarray: |
| """ |
| Generate a Grad-CAM heatmap for a given target class. |
| |
| Args: |
| model: Trained ChestViT model |
| image_tensor: Normalized (1, 3, 224, 224) torch tensor |
| target_class: Index of the disease to explain (0-13) |
| original_image: Original RGB image in [0, 255] for overlay |
| |
| Returns: |
| heatmap_overlay: (224, 224, 3) RGB image with Grad-CAM overlay |
| """ |
| model.eval() |
|
|
| |
| |
| target_layers = [model.vit.encoder.layer[-1].layernorm_before] |
|
|
| |
| cam = GradCAM(model=model, |
| target_layers=target_layers, |
| reshape_transform=reshape_transform) |
|
|
| |
| |
| |
| from pytorch_grad_cam.utils.model_targets import ClassifierOutputTarget |
| targets = [ClassifierOutputTarget(target_class)] |
|
|
| |
| grayscale_cam = cam(input_tensor=image_tensor, |
| targets=targets) |
|
|
| grayscale_cam = grayscale_cam[0, :] |
|
|
| if original_image is not None: |
| |
| rgb_img = np.float32(original_image) / 255 |
| |
| if rgb_img.shape[:2] != (image_size, image_size): |
| rgb_img = cv2.resize(rgb_img, (image_size, image_size)) |
|
|
| visualization = show_cam_on_image(rgb_img, grayscale_cam, use_rgb=True) |
| return visualization |
|
|
| return grayscale_cam |
|
|