Download scripts/validation/generate_heatmaps.py from deboraJ23/AI_MRI: direct link, hf CLI and curl.
- Browser
- Download file 2.96 kB
-
https://huggingface.co/deboraJ23/AI_MRI/resolve/main/scripts/validation/generate_heatmaps.py
- Command line
-
hf download hf://deboraJ23/AI_MRI/scripts/validation/generate_heatmaps.py
-
curl -L -o generate_heatmaps.py https://huggingface.co/deboraJ23/AI_MRI/resolve/main/scripts/validation/generate_heatmaps.py
2.96 kB
| from pathlib import Path | |
| import torch | |
| import torch.nn as nn | |
| import torchio as tio | |
| import matplotlib.pyplot as plt | |
| import numpy as np | |
| from auto_detect_breast_mri.config import resolve_path | |
| from auto_detect_breast_mri.models.resnets import model_names | |
| from auto_detect_breast_mri.data.breast_mri_dataset import BreastMRISubjects | |
| # Paths come from the site config (see config.example.yaml). | |
| path_base = resolve_path(None, "data_root", "root folder of the NIfTI data") | |
| split_root = resolve_path(None, "split_root", "folder holding the split files") | |
| model_root = resolve_path(None, "model_root", "folder holding the checkpoints", required=False) \ | |
| or resolve_path(None, "output_root", "folder holding the checkpoints") | |
| batch_size = 1 | |
| pre_image_shape = (32, 512, 512) | |
| heatmap_size = (32, 256, 256) | |
| # Get Model | |
| model_name = 'resnet18_abrv' | |
| protocol = ['Dyn_0', 'Sub_1'] | |
| model_path = str(Path(model_root) / "malignity_{}.pth".format(model_name)) | |
| model = model_names.get(model_name) | |
| checkpoint = torch.load(model_path) | |
| model.load_state_dict(checkpoint) | |
| model.eval() | |
| # Register forward hook | |
| target_layer = model.layer4[-1] # Choose the target layer | |
| activation = {} | |
| def get_activation(name): | |
| def hook(model, input, output): | |
| activation[name] = output.detach() | |
| return hook | |
| target_layer.register_forward_hook(get_activation('target_layer')) | |
| # forward pass | |
| data_set = BreastMRISubjects(path_base, str(Path(split_root) / "fold0" / "stratified_evaluation_set-f0-0.csv"), | |
| protocol=protocol) | |
| data_loader = tio.SubjectsLoader(data_set, batch_size=batch_size, shuffle=False, num_workers=16) | |
| for batch_id, batch in enumerate(data_loader): | |
| data = batch['image']['data'] | |
| ground_truth = batch['label'] | |
| path = batch['path'] | |
| output = model(data) | |
| # Calculate gradients | |
| model.zero_grad() | |
| one_hot = torch.zeros_like(output) | |
| one_hot[0, output.argmax()] = 1.0 | |
| output.backward(gradient=one_hot, retain_graph=True) | |
| # Weighted sum of feature maps | |
| grads = activation['target_layer'].grad.mean(dim=(2, 3), keepdim=True) | |
| heatmap = torch.sum(grads * activation['target_layer'], dim=1, keepdim=True) | |
| heatmap = nn.functional.relu(heatmap) | |
| # Resize the heatmap to match the original image size | |
| heatmap = nn.functional.interpolate(heatmap, size=heatmap_size, mode="bilinear", align_corners=False) | |
| heatmap = heatmap / heatmap.max() # Normalize | |
| heatmap = heatmap.squeeze().numpy() # transform to numpy array | |
| # Display the original image and Grad-CAM heatmap | |
| plt.figure(figsize=(10, 5)) | |
| plt.subplot(1, 2, 1) | |
| plt.imshow(np.transpose(data[0, 0, 16].squeeze().numpy(), (1, 2, 0))) | |
| plt.title('Original Image') | |
| plt.subplot(1, 2, 2) | |
| plt.imshow(heatmap[0, 0, 16], cmap='viridis') # TODO maybe only 0, 16 ? | |
| plt.title('Grad-CAM Heatmap') | |
| plt.show() | |