|
import tensorflow as tf |
|
from tensorflow.keras.models import load_model, Model |
|
import cv2 |
|
import matplotlib.pyplot as plt |
|
import numpy as np |
|
import matplotlib.cm as cm |
|
|
|
class GradCam: |
|
def __init__(self, model, img, last_conv_layer_name, pred_index=None): |
|
self.model = model |
|
self.img_path = img |
|
self.last_conv_layer_name = last_conv_layer_name |
|
|
|
|
|
def make_gradcam_heatmap(self, pred_index=None): |
|
|
|
|
|
img_array= self.img_path |
|
grad_model = tf.keras.models.Model( |
|
[self.model.inputs], [self.model.get_layer(self.last_conv_layer_name).output, self.model.output] |
|
) |
|
|
|
|
|
|
|
with tf.GradientTape() as tape: |
|
last_conv_layer_output, preds = grad_model(img_array) |
|
if pred_index is None: |
|
pred_index = tf.argmax(preds[0]) |
|
class_channel = preds[:, pred_index] |
|
|
|
|
|
|
|
grads = tape.gradient(class_channel, last_conv_layer_output) |
|
|
|
|
|
|
|
pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2)) |
|
|
|
|
|
|
|
last_conv_layer_output = last_conv_layer_output[0] |
|
heatmap = last_conv_layer_output @ pooled_grads[..., tf.newaxis] |
|
heatmap = tf.squeeze(heatmap) |
|
|
|
|
|
heatmap = tf.maximum(heatmap, 0) / tf.math.reduce_max(heatmap) |
|
return heatmap.numpy() |
|
|
|
|
|
def save_and_display_gradcam(self, cam_path="cam.jpg", alpha=0.4): |
|
heatmap = self.make_gradcam_heatmap() |
|
|
|
|
|
img = self.img_path |
|
|
|
|
|
heatmap = np.uint8(255 * heatmap) |
|
|
|
|
|
jet = cm.get_cmap("jet") |
|
jet_colors = jet(np.arange(512))[:, :3] |
|
jet_heatmap = jet_colors[heatmap] |
|
|
|
|
|
jet_heatmap = tf.keras.preprocessing.image.array_to_img(jet_heatmap) |
|
jet_heatmap = jet_heatmap.resize((img.shape[1], img.shape[0])) |
|
jet_heatmap = tf.keras.preprocessing.image.img_to_array(jet_heatmap) |
|
|
|
|
|
superimposed_img = jet_heatmap * alpha + img |
|
superimposed_img = tf.keras.preprocessing.image.array_to_img(superimposed_img) |
|
|
|
|
|
superimposed_img.save(cam_path) |
|
plt.imshow(superimposed_img) |
|
plt.axis('off') |
|
plt.show() |
|
plt.savefig(path) |
|
|
|
|
|
|
|
|