-
Notifications
You must be signed in to change notification settings - Fork 0
/
grad-cam_benchmark_w_images.py
82 lines (68 loc) · 3.74 KB
/
grad-cam_benchmark_w_images.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
from pytorch_grad_cam import GradCAM, GradCAMPlusPlus, EigenGradCAM, AblationCAM, RandomCAM
import cv2
from PIL import Image
import numpy as np
from pytorch_grad_cam.utils.image import show_cam_on_image, preprocess_image
from pytorch_grad_cam.utils.model_targets import ClassifierOutputSoftmaxTarget
from pytorch_grad_cam.utils.model_targets import ClassifierOutputTarget
from pytorch_grad_cam.metrics.road import ROADCombined
from torchvision import models
import imutils
import torch
# Showing the metrics on top of the CAM :
def visualize_score(visualization, score, name, percentiles):
visualization = cv2.putText(visualization, name, (10, 20),
cv2.FONT_HERSHEY_SIMPLEX, 0.4, (255, 255, 255), 1, cv2.LINE_AA)
visualization = cv2.putText(visualization, "(Least first - Most first)/2", (10, 40),
cv2.FONT_HERSHEY_SIMPLEX, 0.3, (255, 255, 255), 1, cv2.LINE_AA)
visualization = cv2.putText(visualization, f"Percentiles: {percentiles}", (10, 55),
cv2.FONT_HERSHEY_SIMPLEX, 0.4, (255, 255, 255), 1, cv2.LINE_AA)
visualization = cv2.putText(visualization, "Remove and Debias", (10, 70),
cv2.FONT_HERSHEY_SIMPLEX, 0.4, (255, 255, 255), 1, cv2.LINE_AA)
visualization = cv2.putText(visualization, f"{score:.5f}", (10, 85),
cv2.FONT_HERSHEY_SIMPLEX, 0.4, (255, 255, 255), 1, cv2.LINE_AA)
return visualization
def benchmark(model, input_tensor, target_layers, eigen_smooth=False, aug_smooth=False, category=281):
methods = [("GradCAM", GradCAM(model=model, target_layers=target_layers, use_cuda=True)),
("GradCAM++", GradCAMPlusPlus(model=model, target_layers=target_layers, use_cuda=True)),
("EigenGradCAM", EigenGradCAM(model=model, target_layers=target_layers, use_cuda=True)),
("AblationCAM", AblationCAM(model=model, target_layers=target_layers, use_cuda=True)),
("RandomCAM", RandomCAM(model=model, target_layers=target_layers, use_cuda=True))]
cam_metric = ROADCombined(percentiles=[20, 40, 60, 80])
targets = [ClassifierOutputTarget(category)]
metric_targets = [ClassifierOutputSoftmaxTarget(category)]
visualizations = []
percentiles = [10, 50, 90]
for name, cam_method in methods:
with cam_method:
attributions = cam_method(input_tensor=input_tensor,
targets=targets, eigen_smooth=eigen_smooth, aug_smooth=aug_smooth)
attribution = attributions[0, :]
scores = cam_metric(input_tensor, attributions, metric_targets, model)
score = scores[0]
visualization = show_cam_on_image(cat_and_dog, attribution, use_rgb=True)
visualization = visualize_score(visualization, score, name, percentiles)
visualizations.append(visualization)
return Image.fromarray(np.hstack(visualizations))
model = models.resnet50(pretrained=True)
model.eval()
model.cuda()
# device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
images_path = "images"
import os
import sys
sys.path.append(os.getcwd())
from utils import list_images
images_path = list(list_images(images_path))
count = 0
for image_path in images_path:
cat_and_dog = np.array(Image.open(image_path))
cat_and_dog = imutils.resize(cat_and_dog, 224, 224)
cat_and_dog = np.float32(cat_and_dog) / 255
input_tensor = preprocess_image(cat_and_dog, mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
target_layers = [model.layer4]
input_tensor = input_tensor.cuda()
np.random.seed(42)
output = benchmark(model, input_tensor, target_layers, eigen_smooth=False, aug_smooth=False)
output.save(f"output/grad-cam_benchmark{count}.png")
count += 1