Skip to content

Instantly share code, notes, and snippets.

@RaphaelMeudec
Created July 18, 2019 15:11
Show Gist options
  • Star 32 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save RaphaelMeudec/e9a805fa82880876f8d89766f0690b54 to your computer and use it in GitHub Desktop.
Save RaphaelMeudec/e9a805fa82880876f8d89766f0690b54 to your computer and use it in GitHub Desktop.
Grad CAM implementation with Tensorflow 2
import cv2
import numpy as np
import tensorflow as tf
IMAGE_PATH = './cat.jpg'
LAYER_NAME = 'block5_conv3'
CAT_CLASS_INDEX = 281
img = tf.keras.preprocessing.image.load_img(IMAGE_PATH, target_size=(224, 224))
img = tf.keras.preprocessing.image.img_to_array(img)
model = tf.keras.applications.vgg16.VGG16(weights='imagenet', include_top=True)
grad_model = tf.keras.models.Model([model.inputs], [model.get_layer(LAYER_NAME).output, model.output])
with tf.GradientTape() as tape:
conv_outputs, predictions = grad_model(np.array([img]))
loss = predictions[:, CAT_CLASS_INDEX]
output = conv_outputs[0]
grads = tape.gradient(loss, conv_outputs)[0]
gate_f = tf.cast(output > 0, 'float32')
gate_r = tf.cast(grads > 0, 'float32')
guided_grads = tf.cast(output > 0, 'float32') * tf.cast(grads > 0, 'float32') * grads
weights = tf.reduce_mean(guided_grads, axis=(0, 1))
cam = np.ones(output.shape[0: 2], dtype = np.float32)
for i, w in enumerate(weights):
cam += w * output[:, :, i]
cam = cv2.resize(cam.numpy(), (224, 224))
cam = np.maximum(cam, 0)
heatmap = (cam - cam.min()) / (cam.max() - cam.min())
cam = cv2.applyColorMap(np.uint8(255*heatmap), cv2.COLORMAP_JET)
output_image = cv2.addWeighted(cv2.cvtColor(img.astype('uint8'), cv2.COLOR_RGB2BGR), 0.5, cam, 1, 0)
cv2.imwrite('cam.png', output_image)
@HakanKARASU
Copy link

it would be great to provide some information on that

@ErolCitak
Copy link

Hi, may I demand some clue about how to predict gradcam output not just a single image per time but also for multiple images at once?

Thanks

@HakanKARASU
Copy link

HakanKARASU commented Sep 1, 2021 via email

@JoanaNRocha
Copy link

Hi, may I demand some clue about how to predict gradcam output not just a single image per time but also for multiple images at once?

Thanks

The easiest way would be to put this code into a function, using the image path as argument (if you want to test different models, add them as argument as well). Then, simply create a 'for' loop for all the image paths you want to analyze.

@ErolCitak
Copy link

Hi, may I demand some clue about how to predict gradcam output not just a single image per time but also for multiple images at once?
Thanks

The easiest way would be to put this code into a function, using the image path as argument (if you want to test different models, add them as argument as well). Then, simply create a 'for' loop for all the image paths you want to analyze.

Thank you for your response. Actually, I was wondering that what should I do or how should I approach this problem if I want to use my gpu to extract for example 20 images at once, otherwise in for loop solution I have to feed every image one by one.

@JoanaNRocha
Copy link

Hi, may I demand some clue about how to predict gradcam output not just a single image per time but also for multiple images at once?
Thanks

The easiest way would be to put this code into a function, using the image path as argument (if you want to test different models, add them as argument as well). Then, simply create a 'for' loop for all the image paths you want to analyze.

Thank you for your response. Actually, I was wondering that what should I do or how should I approach this problem if I want to use my gpu to extract for example 20 images at once, otherwise in for loop solution I have to feed every image one by one.

Create a list containing the image paths for the 20 images you want to analyze, and then iterate on that list using the 'for' loop.

@Tixi3
Copy link

Tixi3 commented Jan 25, 2022

Hello and thank you very much for this code, it really saved me :)
I have a question regarding CAT_CLASS_INDEX = 281. What does it mean? How do you get that value? And what changes I may have to do if I want to implement this code to dogs pictures or for example medicine images?

@RaphaelMeudec
Copy link
Author

The model is a pretrained VGG that has been trained on imagenet. Imagenet has 1000 classes (the last layer of the VGG is a dense one with 1000 outputs), and the index that has been used during training for cat is the 281-th. The list is available here.

For your case, you just need to know which index is used for the "dog" and then pass the according index.

@Tixi3
Copy link

Tixi3 commented Jan 25, 2022

I see! Thank you very much :)

@Corne173
Copy link

How would you find the feature importance for in terms of the RGB colour channels? Here you get pixel importance, which is a combination of the RGB input. I'm very interest in the answer as it relates to a problem I have where I want to find the grad cam for a multivariate time series

@sneh-debug
Copy link

@RaphaelMeudec Hi. what if the input size is 192,152,4 where 4 is number of 2D slices? how can we obtain for each of the image??

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment