# -*- coding: utf-8 -*-
"""GradCam.ipynb

Automatically generated by Colaboratory.

Original file is located at
    https://colab.research.google.com/drive/1cA8LAxfqbc0Q2_91T9Xn6yBtonLVExuZ
"""

import numpy as np
import tensorflow as tf
from tensorflow import keras

# Display
from IPython.display import Image
import matplotlib.pyplot as plt
import matplotlib.cm as cm

import tensorflow_datasets as tfds

dataset = tfds.image_classification.TFFlowers

# Create base model
base_model = keras.applications.Xception(
    weights='imagenet',
    input_shape=(180, 180, 3),
    include_top=False)
# Freeze base model
base_model.trainable = False

# Create new model on top.
inputs = keras.Input(shape=(180, 180, 3))
x = base_model(inputs, training=False)
x = keras.layers.GlobalAveragePooling2D(name='avg_pool')(x)
outputs = keras.layers.Dense(5,name='predictions')(x)
model = keras.Model(inputs, outputs)

import pathlib
dataset_url = "https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz"
data_dir = tf.keras.utils.get_file(origin=dataset_url, 
                                   fname='flower_photos', 
                                   untar=True)
data_dir = pathlib.Path(data_dir)

#download train-dataset (using tf_flowers data-set to test) should be changed to caltech-dataset
batch_size = 32
img_height = 180
img_width = 180

train_ds = tf.keras.preprocessing.image_dataset_from_directory(
  data_dir,
  validation_split=0.2,
  subset="training",
  seed=123,
  image_size=(img_height, img_width),
  batch_size=batch_size)

model.compile(
  optimizer='adam',
  loss=tf.losses.SparseCategoricalCrossentropy(from_logits=True),
  metrics=['accuracy'])

image_batch, label_batch = next(iter(train_ds))

#Train model for 20 epochs
model.fit(image_batch, label_batch,batch_size=32,epochs=20,verbose=2)

#last two layers for our model (depends on number of classes , here we have 5 types of flowers)
last_conv_layer_name = "block14_sepconv2_act"
classifier_layer_names = [
    "avg_pool",
    "predictions",
]

model.summary()

#to test convert img to array
img = image_batch[14]
array = keras.preprocessing.image.img_to_array(img)
array = np.expand_dims(array, axis=0)

array.shape

#show the img
import matplotlib.pyplot as plt
plt.imshow(img.numpy().astype("uint8"))

#function that apply gradient of high class predicted
def make_gradcam_heatmap(
    img_array, model,base_model, last_conv_layer_name,classifier_layer_names
):
    last_conv_layer = base_model.get_layer(last_conv_layer_name)
    last_conv_layer_model = keras.Model(base_model.inputs, last_conv_layer.output)

    classifier_input = keras.Input(shape=last_conv_layer.output.shape[1:])
    x = classifier_input
    for layer_name in classifier_layer_names:
        x = model.get_layer(layer_name)(x)
    classifier_model = keras.Model(classifier_input, x)


    with tf.GradientTape() as tape:
        last_conv_layer_output = last_conv_layer_model(array)
        tape.watch(last_conv_layer_output)
        preds = classifier_model(last_conv_layer_output)
        top_pred_index = tf.argmax(preds[0])
        top_class_channel = tf.convert_to_tensor(preds[0][top_pred_index])

    grads = tape.gradient(top_class_channel, last_conv_layer_output)

    pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))

    last_conv_layer_output = last_conv_layer_output.numpy()[0]
    pooled_grads = pooled_grads.numpy()
    for i in range(pooled_grads.shape[-1]):
        last_conv_layer_output[:, :, i] *= pooled_grads[i]

    heatmap = np.mean(last_conv_layer_output, axis=-1)

    heatmap = np.maximum(heatmap, 0) / np.max(heatmap)
    return heatmap

array = keras.preprocessing.image.img_to_array(image_batch[14])
array = np.expand_dims(array, axis=0)
preds = model.predict(array)
top_pred_index = tf.argmax(preds[0])
print(preds)

top_class_channel = tf.convert_to_tensor(preds[0][top_pred_index])
class_names = np.array(sorted([item.name for item in data_dir.glob('*') if item.name != "LICENSE.txt"]))

print("Classes :" ,class_names)
print("Predicted :",class_names[int(tf.argmax(preds[0]))] )

heatmap = make_gradcam_heatmap(
    array, model, base_model, last_conv_layer_name, classifier_layer_names
)

# Display heatmap
plt.matshow(heatmap)
plt.show()

# We rescale heatmap to a range 0-255
heatmap = np.uint8(255 * heatmap)

# We use jet colormap to colorize heatmap
jet = cm.get_cmap("jet")

# We use RGB values of the colormap
jet_colors = jet(np.arange(256))[:, :3]
jet_heatmap = jet_colors[heatmap]

# We create an image with RGB colorized heatmap
jet_heatmap = keras.preprocessing.image.array_to_img(jet_heatmap)
jet_heatmap = jet_heatmap.resize((img.shape[1], img.shape[0]))
jet_heatmap = keras.preprocessing.image.img_to_array(jet_heatmap)

# Superimpose the heatmap on original image
superimposed_img = jet_heatmap * 0.6 + img
superimposed_img = keras.preprocessing.image.array_to_img(superimposed_img)

# Save the superimposed image
save_path = "fgbcf.jpg"
superimposed_img.save(save_path)

# Display Grad CAM
display(Image(save_path))
a8c7ea366dbd1af7845305cca25f7b8aaf4b83a5
<mask token>


def make_gradcam_heatmap(img_array, model, base_model, last_conv_layer_name,
    classifier_layer_names):
    last_conv_layer = base_model.get_layer(last_conv_layer_name)
    last_conv_layer_model = keras.Model(base_model.inputs, last_conv_layer.
        output)
    classifier_input = keras.Input(shape=last_conv_layer.output.shape[1:])
    x = classifier_input
    for layer_name in classifier_layer_names:
        x = model.get_layer(layer_name)(x)
    classifier_model = keras.Model(classifier_input, x)
    with tf.GradientTape() as tape:
        last_conv_layer_output = last_conv_layer_model(array)
        tape.watch(last_conv_layer_output)
        preds = classifier_model(last_conv_layer_output)
        top_pred_index = tf.argmax(preds[0])
        top_class_channel = tf.convert_to_tensor(preds[0][top_pred_index])
    grads = tape.gradient(top_class_channel, last_conv_layer_output)
    pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))
    last_conv_layer_output = last_conv_layer_output.numpy()[0]
    pooled_grads = pooled_grads.numpy()
    for i in range(pooled_grads.shape[-1]):
        last_conv_layer_output[:, :, i] *= pooled_grads[i]
    heatmap = np.mean(last_conv_layer_output, axis=-1)
    heatmap = np.maximum(heatmap, 0) / np.max(heatmap)
    return heatmap


<mask token>

<mask token>
model.compile(optimizer='adam', loss=tf.losses.
    SparseCategoricalCrossentropy(from_logits=True), metrics=['accuracy'])
<mask token>
model.fit(image_batch, label_batch, batch_size=32, epochs=20, verbose=2)
<mask token>
model.summary()
<mask token>
array.shape
<mask token>
plt.imshow(img.numpy().astype('uint8'))


def make_gradcam_heatmap(img_array, model, base_model, last_conv_layer_name,
    classifier_layer_names):
    last_conv_layer = base_model.get_layer(last_conv_layer_name)
    last_conv_layer_model = keras.Model(base_model.inputs, last_conv_layer.
        output)
    classifier_input = keras.Input(shape=last_conv_layer.output.shape[1:])
    x = classifier_input
    for layer_name in classifier_layer_names:
        x = model.get_layer(layer_name)(x)
    classifier_model = keras.Model(classifier_input, x)
    with tf.GradientTape() as tape:
        last_conv_layer_output = last_conv_layer_model(array)
        tape.watch(last_conv_layer_output)
        preds = classifier_model(last_conv_layer_output)
        top_pred_index = tf.argmax(preds[0])
        top_class_channel = tf.convert_to_tensor(preds[0][top_pred_index])
    grads = tape.gradient(top_class_channel, last_conv_layer_output)
    pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))
    last_conv_layer_output = last_conv_layer_output.numpy()[0]
    pooled_grads = pooled_grads.numpy()
    for i in range(pooled_grads.shape[-1]):
        last_conv_layer_output[:, :, i] *= pooled_grads[i]
    heatmap = np.mean(last_conv_layer_output, axis=-1)
    heatmap = np.maximum(heatmap, 0) / np.max(heatmap)
    return heatmap


<mask token>
print(preds)
<mask token>
print('Classes :', class_names)
print('Predicted :', class_names[int(tf.argmax(preds[0]))])
<mask token>
plt.matshow(heatmap)
plt.show()
<mask token>
superimposed_img.save(save_path)
display(Image(save_path))

<mask token>
dataset = tfds.image_classification.TFFlowers
base_model = keras.applications.Xception(weights='imagenet', input_shape=(
    180, 180, 3), include_top=False)
base_model.trainable = False
inputs = keras.Input(shape=(180, 180, 3))
x = base_model(inputs, training=False)
x = keras.layers.GlobalAveragePooling2D(name='avg_pool')(x)
outputs = keras.layers.Dense(5, name='predictions')(x)
model = keras.Model(inputs, outputs)
<mask token>
dataset_url = (
    'https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz'
    )
data_dir = tf.keras.utils.get_file(origin=dataset_url, fname=
    'flower_photos', untar=True)
data_dir = pathlib.Path(data_dir)
batch_size = 32
img_height = 180
img_width = 180
train_ds = tf.keras.preprocessing.image_dataset_from_directory(data_dir,
    validation_split=0.2, subset='training', seed=123, image_size=(
    img_height, img_width), batch_size=batch_size)
model.compile(optimizer='adam', loss=tf.losses.
    SparseCategoricalCrossentropy(from_logits=True), metrics=['accuracy'])
image_batch, label_batch = next(iter(train_ds))
model.fit(image_batch, label_batch, batch_size=32, epochs=20, verbose=2)
last_conv_layer_name = 'block14_sepconv2_act'
classifier_layer_names = ['avg_pool', 'predictions']
model.summary()
img = image_batch[14]
array = keras.preprocessing.image.img_to_array(img)
array = np.expand_dims(array, axis=0)
array.shape
<mask token>
plt.imshow(img.numpy().astype('uint8'))


def make_gradcam_heatmap(img_array, model, base_model, last_conv_layer_name,
    classifier_layer_names):
    last_conv_layer = base_model.get_layer(last_conv_layer_name)
    last_conv_layer_model = keras.Model(base_model.inputs, last_conv_layer.
        output)
    classifier_input = keras.Input(shape=last_conv_layer.output.shape[1:])
    x = classifier_input
    for layer_name in classifier_layer_names:
        x = model.get_layer(layer_name)(x)
    classifier_model = keras.Model(classifier_input, x)
    with tf.GradientTape() as tape:
        last_conv_layer_output = last_conv_layer_model(array)
        tape.watch(last_conv_layer_output)
        preds = classifier_model(last_conv_layer_output)
        top_pred_index = tf.argmax(preds[0])
        top_class_channel = tf.convert_to_tensor(preds[0][top_pred_index])
    grads = tape.gradient(top_class_channel, last_conv_layer_output)
    pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))
    last_conv_layer_output = last_conv_layer_output.numpy()[0]
    pooled_grads = pooled_grads.numpy()
    for i in range(pooled_grads.shape[-1]):
        last_conv_layer_output[:, :, i] *= pooled_grads[i]
    heatmap = np.mean(last_conv_layer_output, axis=-1)
    heatmap = np.maximum(heatmap, 0) / np.max(heatmap)
    return heatmap


array = keras.preprocessing.image.img_to_array(image_batch[14])
array = np.expand_dims(array, axis=0)
preds = model.predict(array)
top_pred_index = tf.argmax(preds[0])
print(preds)
top_class_channel = tf.convert_to_tensor(preds[0][top_pred_index])
class_names = np.array(sorted([item.name for item in data_dir.glob('*') if 
    item.name != 'LICENSE.txt']))
print('Classes :', class_names)
print('Predicted :', class_names[int(tf.argmax(preds[0]))])
heatmap = make_gradcam_heatmap(array, model, base_model,
    last_conv_layer_name, classifier_layer_names)
plt.matshow(heatmap)
plt.show()
heatmap = np.uint8(255 * heatmap)
jet = cm.get_cmap('jet')
jet_colors = jet(np.arange(256))[:, :3]
jet_heatmap = jet_colors[heatmap]
jet_heatmap = keras.preprocessing.image.array_to_img(jet_heatmap)
jet_heatmap = jet_heatmap.resize((img.shape[1], img.shape[0]))
jet_heatmap = keras.preprocessing.image.img_to_array(jet_heatmap)
superimposed_img = jet_heatmap * 0.6 + img
superimposed_img = keras.preprocessing.image.array_to_img(superimposed_img)
save_path = 'fgbcf.jpg'
superimposed_img.save(save_path)
display(Image(save_path))

<mask token>
import numpy as np
import tensorflow as tf
from tensorflow import keras
from IPython.display import Image
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import tensorflow_datasets as tfds
dataset = tfds.image_classification.TFFlowers
base_model = keras.applications.Xception(weights='imagenet', input_shape=(
    180, 180, 3), include_top=False)
base_model.trainable = False
inputs = keras.Input(shape=(180, 180, 3))
x = base_model(inputs, training=False)
x = keras.layers.GlobalAveragePooling2D(name='avg_pool')(x)
outputs = keras.layers.Dense(5, name='predictions')(x)
model = keras.Model(inputs, outputs)
import pathlib
dataset_url = (
    'https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz'
    )
data_dir = tf.keras.utils.get_file(origin=dataset_url, fname=
    'flower_photos', untar=True)
data_dir = pathlib.Path(data_dir)
batch_size = 32
img_height = 180
img_width = 180
train_ds = tf.keras.preprocessing.image_dataset_from_directory(data_dir,
    validation_split=0.2, subset='training', seed=123, image_size=(
    img_height, img_width), batch_size=batch_size)
model.compile(optimizer='adam', loss=tf.losses.
    SparseCategoricalCrossentropy(from_logits=True), metrics=['accuracy'])
image_batch, label_batch = next(iter(train_ds))
model.fit(image_batch, label_batch, batch_size=32, epochs=20, verbose=2)
last_conv_layer_name = 'block14_sepconv2_act'
classifier_layer_names = ['avg_pool', 'predictions']
model.summary()
img = image_batch[14]
array = keras.preprocessing.image.img_to_array(img)
array = np.expand_dims(array, axis=0)
array.shape
import matplotlib.pyplot as plt
plt.imshow(img.numpy().astype('uint8'))


def make_gradcam_heatmap(img_array, model, base_model, last_conv_layer_name,
    classifier_layer_names):
    last_conv_layer = base_model.get_layer(last_conv_layer_name)
    last_conv_layer_model = keras.Model(base_model.inputs, last_conv_layer.
        output)
    classifier_input = keras.Input(shape=last_conv_layer.output.shape[1:])
    x = classifier_input
    for layer_name in classifier_layer_names:
        x = model.get_layer(layer_name)(x)
    classifier_model = keras.Model(classifier_input, x)
    with tf.GradientTape() as tape:
        last_conv_layer_output = last_conv_layer_model(array)
        tape.watch(last_conv_layer_output)
        preds = classifier_model(last_conv_layer_output)
        top_pred_index = tf.argmax(preds[0])
        top_class_channel = tf.convert_to_tensor(preds[0][top_pred_index])
    grads = tape.gradient(top_class_channel, last_conv_layer_output)
    pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))
    last_conv_layer_output = last_conv_layer_output.numpy()[0]
    pooled_grads = pooled_grads.numpy()
    for i in range(pooled_grads.shape[-1]):
        last_conv_layer_output[:, :, i] *= pooled_grads[i]
    heatmap = np.mean(last_conv_layer_output, axis=-1)
    heatmap = np.maximum(heatmap, 0) / np.max(heatmap)
    return heatmap


array = keras.preprocessing.image.img_to_array(image_batch[14])
array = np.expand_dims(array, axis=0)
preds = model.predict(array)
top_pred_index = tf.argmax(preds[0])
print(preds)
top_class_channel = tf.convert_to_tensor(preds[0][top_pred_index])
class_names = np.array(sorted([item.name for item in data_dir.glob('*') if 
    item.name != 'LICENSE.txt']))
print('Classes :', class_names)
print('Predicted :', class_names[int(tf.argmax(preds[0]))])
heatmap = make_gradcam_heatmap(array, model, base_model,
    last_conv_layer_name, classifier_layer_names)
plt.matshow(heatmap)
plt.show()
heatmap = np.uint8(255 * heatmap)
jet = cm.get_cmap('jet')
jet_colors = jet(np.arange(256))[:, :3]
jet_heatmap = jet_colors[heatmap]
jet_heatmap = keras.preprocessing.image.array_to_img(jet_heatmap)
jet_heatmap = jet_heatmap.resize((img.shape[1], img.shape[0]))
jet_heatmap = keras.preprocessing.image.img_to_array(jet_heatmap)
superimposed_img = jet_heatmap * 0.6 + img
superimposed_img = keras.preprocessing.image.array_to_img(superimposed_img)
save_path = 'fgbcf.jpg'
superimposed_img.save(save_path)
display(Image(save_path))

# -*- coding: utf-8 -*-
"""GradCam.ipynb

Automatically generated by Colaboratory.

Original file is located at
    https://colab.research.google.com/drive/1cA8LAxfqbc0Q2_91T9Xn6yBtonLVExuZ
"""

import numpy as np
import tensorflow as tf
from tensorflow import keras

# Display
from IPython.display import Image
import matplotlib.pyplot as plt
import matplotlib.cm as cm

import tensorflow_datasets as tfds

dataset = tfds.image_classification.TFFlowers

# Create base model
base_model = keras.applications.Xception(
    weights='imagenet',
    input_shape=(180, 180, 3),
    include_top=False)
# Freeze base model
base_model.trainable = False

# Create new model on top.
inputs = keras.Input(shape=(180, 180, 3))
x = base_model(inputs, training=False)
x = keras.layers.GlobalAveragePooling2D(name='avg_pool')(x)
outputs = keras.layers.Dense(5,name='predictions')(x)
model = keras.Model(inputs, outputs)

import pathlib
dataset_url = "https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz"
data_dir = tf.keras.utils.get_file(origin=dataset_url, 
                                   fname='flower_photos', 
                                   untar=True)
data_dir = pathlib.Path(data_dir)

#download train-dataset (using tf_flowers data-set to test) should be changed to caltech-dataset
batch_size = 32
img_height = 180
img_width = 180

train_ds = tf.keras.preprocessing.image_dataset_from_directory(
  data_dir,
  validation_split=0.2,
  subset="training",
  seed=123,
  image_size=(img_height, img_width),
  batch_size=batch_size)

model.compile(
  optimizer='adam',
  loss=tf.losses.SparseCategoricalCrossentropy(from_logits=True),
  metrics=['accuracy'])

image_batch, label_batch = next(iter(train_ds))

#Train model for 20 epochs
model.fit(image_batch, label_batch,batch_size=32,epochs=20,verbose=2)

#last two layers for our model (depends on number of classes , here we have 5 types of flowers)
last_conv_layer_name = "block14_sepconv2_act"
classifier_layer_names = [
    "avg_pool",
    "predictions",
]

model.summary()

#to test convert img to array
img = image_batch[14]
array = keras.preprocessing.image.img_to_array(img)
array = np.expand_dims(array, axis=0)

array.shape

#show the img
import matplotlib.pyplot as plt
plt.imshow(img.numpy().astype("uint8"))

#function that apply gradient of high class predicted
def make_gradcam_heatmap(
    img_array, model,base_model, last_conv_layer_name,classifier_layer_names
):
    last_conv_layer = base_model.get_layer(last_conv_layer_name)
    last_conv_layer_model = keras.Model(base_model.inputs, last_conv_layer.output)

    classifier_input = keras.Input(shape=last_conv_layer.output.shape[1:])
    x = classifier_input
    for layer_name in classifier_layer_names:
        x = model.get_layer(layer_name)(x)
    classifier_model = keras.Model(classifier_input, x)


    with tf.GradientTape() as tape:
        last_conv_layer_output = last_conv_layer_model(array)
        tape.watch(last_conv_layer_output)
        preds = classifier_model(last_conv_layer_output)
        top_pred_index = tf.argmax(preds[0])
        top_class_channel = tf.convert_to_tensor(preds[0][top_pred_index])

    grads = tape.gradient(top_class_channel, last_conv_layer_output)

    pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))

    last_conv_layer_output = last_conv_layer_output.numpy()[0]
    pooled_grads = pooled_grads.numpy()
    for i in range(pooled_grads.shape[-1]):
        last_conv_layer_output[:, :, i] *= pooled_grads[i]

    heatmap = np.mean(last_conv_layer_output, axis=-1)

    heatmap = np.maximum(heatmap, 0) / np.max(heatmap)
    return heatmap

array = keras.preprocessing.image.img_to_array(image_batch[14])
array = np.expand_dims(array, axis=0)
preds = model.predict(array)
top_pred_index = tf.argmax(preds[0])
print(preds)

top_class_channel = tf.convert_to_tensor(preds[0][top_pred_index])
class_names = np.array(sorted([item.name for item in data_dir.glob('*') if item.name != "LICENSE.txt"]))

print("Classes :" ,class_names)
print("Predicted :",class_names[int(tf.argmax(preds[0]))] )

heatmap = make_gradcam_heatmap(
    array, model, base_model, last_conv_layer_name, classifier_layer_names
)

# Display heatmap
plt.matshow(heatmap)
plt.show()

# We rescale heatmap to a range 0-255
heatmap = np.uint8(255 * heatmap)

# We use jet colormap to colorize heatmap
jet = cm.get_cmap("jet")

# We use RGB values of the colormap
jet_colors = jet(np.arange(256))[:, :3]
jet_heatmap = jet_colors[heatmap]

# We create an image with RGB colorized heatmap
jet_heatmap = keras.preprocessing.image.array_to_img(jet_heatmap)
jet_heatmap = jet_heatmap.resize((img.shape[1], img.shape[0]))
jet_heatmap = keras.preprocessing.image.img_to_array(jet_heatmap)

# Superimpose the heatmap on original image
superimposed_img = jet_heatmap * 0.6 + img
superimposed_img = keras.preprocessing.image.array_to_img(superimposed_img)

# Save the superimposed image
save_path = "fgbcf.jpg"
superimposed_img.save(save_path)

# Display Grad CAM
display(Image(save_path))