Commit 69ea3d3d authored by sjjsmuel's avatar sjjsmuel

grad_cam

parent 7753cca2
import pathlib
import PIL
import numpy as np
import cv2
from PIL import Image
from classifier.Resnet152 import Resnet152
import tensorflow as tf
......@@ -10,20 +13,23 @@ img_raw_path = 'data/test_data/'
out = 'out/'
#test_image = img_raw_path + img_name
model_file = 'out/checkpoints/2020.03.17.15.20.50/model.0101-0.455.hdf5'
model_file = 'out/checkpoints/2020.03.25.10.26.51/model.0002-0.319.hdf5'
resnet_file = 'data/resnet152v2_weights_tf_dim_ordering_tf_kernels_notop.h5'
n_classes = 2
img_width = 224
img_height = 224
orig_size = None
channels = 3
class_index = 0
#LAYER_NAME = 'conv5_block3_out'
#LAYER_NAME = 'conv4_block36_out'
#LAYER_NAME = 'conv5_block3_3_conv'
#LAYER_NAME = 'global_average_pooling2d'
#LAYER_NAME = 'conv5_block3_out'
#LAYER_NAME = 'post_bn'
LAYER_NAME = 'post_relu'
#LAYER_NAME = 'global_average_pooling2d'
'''
......@@ -34,70 +40,64 @@ img = tf.image.resize(img, [img_width, img_height])
'''
def run_cam(test_image_name):
# Load image
test_image = img_raw_path + test_image_name
img = tf.keras.preprocessing.image.load_img(test_image, target_size=(img_width, img_height))
img = tf.keras.preprocessing.image.img_to_array(img) / 255
def get_heatmap(img, class_index, eps=1e-8):
with tf.GradientTape() as tape:
conv_outputs, predictions = grad_model(np.array([img]))
loss = predictions[:, np.argmax(predictions[0])]
output = conv_outputs[0]
# print("Conv-out")
# print(output)
# print(tf.reduce_max(output))
#loss = predictions[:, np.argmax(predictions[0])]
loss = predictions[:, class_index]
# print("loss")
# print(loss)
print('Argmax', np.argmax(predictions[0]))
print('Diff', np.max(predictions[0])-np.min(predictions[0]))
print(loss)
grads = tape.gradient(loss, conv_outputs)
grads = tape.gradient(loss, conv_outputs)[0]
castConvOutputs = tf.cast(conv_outputs > 0, "float32")
castGrads = tf.cast(grads > 0, "float32")
guided_grads = castConvOutputs * castGrads * grads
# print("Gradient")
# print(grads)
# 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 = grads * output
output = conv_outputs[0]
guided_grads = guided_grads[0]
weights = tf.reduce_mean(guided_grads, axis=(0, 1))
# weights = tf.reduce_mean(grads, axis=(0, 1))
# weights = grads
#weights = tf.reduce_mean(grads, axis=(0, 1))
#cam = np.zeros(output.shape[0: 2], dtype=np.float32)
cam = np.ones(output.shape[0: 2], dtype=np.float32)
#for i, w in enumerate(weights):
# cam += w * output[:, :, i]
cam = tf.reduce_sum(tf.multiply(weights, output), axis=-1)
for i, w in enumerate(weights):
cam += w * output[:, :, i]
(w, h) = (img.shape[2], img.shape[1])
heatmap = cv2.resize(cam.numpy(), (w,h))
#heatmap = np.maximum(cam, 0) # ReLU
cam = cv2.resize(cam.numpy(), (224, 224))
cam = np.maximum(cam, 0)
print(cam.min())
print(cam.max())
if (cam.max() - cam.min()) != 0:
heatmap = (cam - cam.min()) / (cam.max() - cam.min())
else:
heatmap = cam - cam.min()
print(heatmap.max() - heatmap.min())
numer = heatmap - np.min(heatmap)
denom = (heatmap.max() - heatmap.min()) + eps
heatmap = numer / denom
return (heatmap * 255).astype("uint8")
'''
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)
'''
cam = cv2.applyColorMap(np.uint8(255 * heatmap), cv2.COLORMAP_JET)
img = np.array(img) * 255
output_image = cv2.addWeighted(cv2.cvtColor(img.astype('uint8'), cv2.COLOR_RGB2BGR), 0.5, cam, 1, 0)
#output_image.show()
# cv2.waitKey(0)
cv2.imwrite(out + test_image_name[:-4] + '.png', output_image)
# Create Network
network = Resnet152(n_classes, img_width, img_height, channels, resnet_file)
model = network.get_model()
def apply_heatmap(heatmap, image, alpha=.5, colormap = cv2.COLORMAP_JET):
heatmap = cv2.applyColorMap(heatmap, colormap)
#img = np.array(image) * 255
#img = cv2.resize(image, orig_size)
return cv2.addWeighted(cv2.cvtColor(image.astype('uint8'), cv2.COLOR_RGB2BGR), alpha, heatmap, 1-alpha, 0)
#return cv2.addWeighted(image, alpha, heatmap, 1 - alpha, 0)
model.load_weights(model_file)
# Create Network
#network = Resnet152(n_classes, img_width, img_height, channels, resnet_file)
#model = network.get_model()
#model.load_weights(model_file)
#model = tf.keras.models.load_model(model_file)
model = tf.keras.models.load_model(model_file)
#model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
......@@ -106,12 +106,29 @@ model.load_weights(model_file)
# print(layer.name)
grad_model = tf.keras.models.Model([model.inputs], [model.get_layer(LAYER_NAME).output, model.output])
class_index_map = {'caries/': 0, 'no_caries/': 1}
#Run Cam-Function on all provided examples
for folder in ['caries/', 'no_caries/']:
path = pathlib.Path(img_raw_path+folder)
outpath = pathlib.Path(out+folder)
if not outpath.exists():
outpath.mkdir()
filenames = [item.name for item in path.glob('*') if item.name != '.DS_Store']
class_index = class_index_map[folder]
print(folder, class_index)
for img_name in filenames:
run_cam(folder + img_name)
\ No newline at end of file
# Load image
test_image = img_raw_path + folder + img_name
orig_image = tf.keras.preprocessing.image.load_img(test_image)
orig_size = orig_image.size
# img = img.resize(img, tf.Variable([img_width, img_height], tf.int32))
img = orig_image.resize((img_width, img_height), Image.BILINEAR)
img = tf.keras.preprocessing.image.img_to_array(img) / 255
orig_image = tf.keras.preprocessing.image.img_to_array(orig_image)
heat_map = get_heatmap(img, class_index)
heat_map = cv2.resize(heat_map, orig_size)
image_with_heatmap_applied = apply_heatmap(heat_map, orig_image)
cv2.imwrite(str(outpath) + '/'+ img_name[:-4] + '.png', image_with_heatmap_applied)
print(img_name[:-4], 'written to file.')
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment