<jupyter_start><jupyter_text><jupyter_code># Down grade to tensorflow to 2.2.0 version in order to use tf-explain Grad CAM
!pip install tensorflow==2.2.0
# Import tf-explain in order to import Grad CAM for visualization.
!pip install tf-explain==0.1.0
import keras
import numpy as np
import cv2
import os
import random
import shutil
import pandas as pd
import csv
import zipfile
from keras import optimizers
from keras.models import Sequential, Model, load_model
from keras.layers import Dropout, Flatten, Dense, Input, AveragePooling2D, Reshape, Lambda
from tensorflow.keras.layers import Conv2D, MaxPooling2D, BatchNormalization,TimeDistributed, LSTM, concatenate
from keras.callbacks import ModelCheckpoint
from keras.applications.imagenet_utils import preprocess_input
from keras.preprocessing.image import ImageDataGenerator,save_img, load_img, img_to_array
from keras.initializers import RandomNormal
from sklearn.utils import shuffle
import io
from PIL import Image as pil_image
import keras.backend as k
from IPython.display import Image
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import tensorflow as tf
import datetime
from keras.callbacks import TensorBoard
from keras.applications import ResNet152, InceptionV3, Xception, VGG16, VGG19
from keras.applications.resnet_v2 import ResNet50V2
from keras.utils.vis_utils import plot_model
import tf_explain
from google.colab import drive
drive.mount('/content/drive')
!nvidia-smi #show the allocated GPU
from psutil import virtual_memory
ram_gb = virtual_memory().total / 1e9
print('Your runtime has {:.1f} gigabytes of available RAM\n'.format(ram_gb))

if ram_gb < 20:
  print('To enable a high-RAM runtime, select the Runtime > "Change runtime type"')
  print('menu, and then select High-RAM in the Runtime shape dropdown. Then, ')
  print('re-execute this cell.')
else:
  print('You are using a high-RAM runtime!')
# Add the COVID-CTset to your drive through this link:
#https://drive.google.com/drive/folders/1xdk-mCkxCDNwsMAk2SGv203rY1mrbnPB?usp=sharing
#Install essential libraries
!pip install zipfile36
archive = zipfile.ZipFile("/content/drive/MyDrive/Train&Validation.zip") #Path to the shared data for training and validation
for file in archive.namelist():
     archive.extract(file, './data') #Extract the data
random_seed = 123
random.seed(random_seed)
fold_num=1 #Select Fold Number
#Here we set the data generators for applying data augmentation methods
train_datagen = ImageDataGenerator(horizontal_flip=True,vertical_flip=True,zoom_range=0.05,rotation_range=360,width_shift_range=0.05,height_shift_range=0.05,shear_range=0.05)
test_datagen = ImageDataGenerator()
train_df =pd.read_csv('/content/drive/MyDrive/CSV/train{}.csv'.format(fold_num)) #read train csv file
validation_df = pd.read_csv('/content/drive/MyDrive/CSV/validation{}.csv'.format(fold_num)) #read validation csv file (Validation in the training process)
train_df = shuffle(train_df) #Shuffle the train data
test_df = pd.read_csv('/content/drive/MyDrive/CSV/test{}.csv'.format(fold_num))#read test csv file (For evaluating the final version of the trained network)
shape=(512,512,1) #shape of the dataset images (in TIFF format)
#Create the generators
train_generator = train_datagen.flow_from_dataframe(
      dataframe=train_df,
      directory='data',
      x_col="filename",
      y_col="class",
      target_size=shape[:2],
      batch_size=10,
      class_mode='categorical',color_mode="grayscale",shuffle=True)
validation_generator = test_datagen.flow_from_dataframe(
        dataframe=validation_df,
        directory='data',
        x_col="filename",
        y_col="class",
        target_size=shape[:2],
        batch_size=10,
        class_mode='categorical',color_mode="grayscale",shuffle=True)
test_generator = test_datagen.flow_from_dataframe(
        dataframe=test_df,
        directory='data',
        x_col="filename",
        y_col="class",
        target_size=shape[:2],
        batch_size=10,
        class_mode='categorical',color_mode="grayscale",shuffle=False)
# load entire model and weights
model=keras.models.load_model('/content/drive/MyDrive/Models/resnet152_model.h5')
# import Grad CAM

from tf_explain.core.grad_cam import GradCAM
model.summary()
y_pred=model.predict(test_generator)
ypred=np.argmax(y_pred, axis=1)
# Create dataframe to save classification
import pandas as pd

df = pd.DataFrame() 
df['Images'] = test_generator.filenames
df['classes'] = test_df['class']
df['classes_int'] = test_generator.classes

df['y_pred'] = np.argmax(y_pred, axis=1)

conditions2 = [
    (df['y_pred'] == 0),
    (df['y_pred'] == 1),
    ]
pred_values = ['covid','normal']
df['pred_class'] = np.select(conditions2, pred_values)

# create a list of our conditions
conditions = [
    (df['classes_int'] == 0) & (df['y_pred'] == 0),
    (df['classes_int'] == 0) & (df['y_pred'] == 1),
    (df['classes_int'] == 1) & (df['y_pred'] == 1),
    (df['classes_int'] == 1) & (df['y_pred'] == 0),
    ]
# create a list of the values we want to assign for each condition
values = ['TP', 'FN', 'TN', 'FP']

# create a new column and use np.select to assign values to it using our lists as arguments
df['Prediction'] = np.select(conditions, values)

pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', 20)
pd.set_option('display.width', 100)
print(df)
explainer = GradCAM()
visual_layer='conv5_block3_out'
!mkdir summary
temp_folder ='./summary/'
name_paths = test_generator.filepaths
name_paths[1:10]

number_of_image_per_batch = 20
list_of_random_items = random.sample(name_paths, number_of_image_per_batch)
#print(list_of_random_items)

# You must first create a folder in your Google Drive in order to save your images, 
# then past the path here.
save_folder ="/content/drive/MyDrive/Gradcam Images/resnet152/"
columns = 2
rows = len(list_of_random_items)

input_arrays = []
data_array = []
i = 1
j = 1

for batch in range(50):
  random.seed(random_seed)
  random_seed += 100
  list_of_random_items = random.sample(name_paths, number_of_image_per_batch)
  fig=plt.figure(figsize=(15, 20*rows/2.5))
  i = 1
  j = 1
  for paths in list_of_random_items:
    img = load_img(paths)

    pic = load_img(paths, color_mode='grayscale', target_size=(512,512,1))
    pic_arr = img_to_array(pic)
   
    d = ([pic_arr], None)
    data = ([pic_arr], None)
    grid = explainer.explain(data, model, layer_name=visual_layer, class_index=0) 
    file_save = paths.split('/')[1].replace('.tif','')+ "grad_cam" + ".png"
  
    #print(file_save)
    explainer.save(grid, save_folder + 'batch_'+str(batch), file_save)

    pic_gradCam_path = save_folder + 'batch_'+str(batch)+ '/' + file_save
    pic_gradCam = load_img(pic_gradCam_path)
    j = i+1
    #save image to view

    f = open(paths, 'rb')
    tif = pil_image.open(io.BytesIO(f.read()))
    array = np.array(tif)
    max_val = np.amax(array)
    normalized = (array/max_val)
    im_view = pil_image.fromarray(normalized)
    im_view_path = paths.split('/')[1].replace('.tif','')
    #save_path = save_folder+ 'batch_'+str(batch)+'/' + im_view_path + '_view.tif'
    #im_view.save(save_path)

    #print(save_path)
    image_name = paths.split('/')[1]
    act_class = df.loc[df['Images'] == image_name].classes.tolist()[0]
    pred_class = df.loc[df['Images'] == image_name].pred_class.tolist()[0]
    pred = df.loc[df['Images'] == image_name].Prediction.tolist()[0]

    plt.axis('off')
    fig.add_subplot(rows, columns, i)
    plt.title(image_name+'\n Actual class: '+act_class+'\n Pred Class: '+
              pred_class+'\n Accuracy: '+ pred)
    plt.imshow(pic)
    plt.axis('off')
    fig.add_subplot(rows, columns, i+1)
    fig.tight_layout()
    plt.title(file_save+'\n Actual class: '+act_class+'\n Pred Class: '+
              pred_class+'\n Accuracy: '+ pred)
    plt.imshow(pic_gradCam)

    i = i + 2
  plt.axis('off')
  plt.show()
  fig.savefig(save_folder+'Summary\Batch'+str(batch)+'plot.pdf', dpi = 200)
  plt.savefig(save_folder+'Summary\Batch'+str(batch)+'plot.png', dpi = 200)
  fig.savefig(temp_folder + 'Batch'+str(batch)+'plot.pdf', dpi = 300)
  plt.savefig(temp_folder +'Batch'+str(batch)+'plot.png', dpi = 300)

fig.savefig('plot.pdf', dpi = 300)
from google.colab import files
import shutil
sum_path = 'summary_resnet152'
shutil.make_archive(sum_path, 'zip', temp_folder)

#!zip -r 'sum_path' /content/summary
files.download(sum_path+'.zip')<jupyter_output><empty_output><jupyter_text>This next section is using a pre-trained model that is not trained on any dataset. You just have it look at a picture and let it tell you what is important.

You can find the codes from this resource:
https://keras.io/examples/vision/grad_cam/<jupyter_code>#img_path = '/content/drive/MyDrive/Train&Validation/137covid_patient10_SR_4_IM00068.tif'
img_path ='/content/drive/MyDrive/Train&Validation/137covid_patient118_SR_3_IM00014.tif'# good
img = load_img(img_path)
plt.imshow(img)
plt.show()
model_builder = keras.applications.xception.Xception
img_size = (299,299)
preprocess_input = keras.applications.xception.preprocess_input
decode_predictions = keras.applications.xception.decode_predictions
model_builder.summary()
last_conv_layer_name = "block14_sepconv2_act"
classifier_layer_names = ["avg_pool", "predictions"]
pix=load_img(img_path, color_mode='grayscale', target_size=(512,512))
plt.imshow(pix)
plt.show()
def get_img_array(img_path, size):
    # `img` is a PIL image of size 299x299
    img = load_img(img_path, target_size=size)
    # `array` is a float32 Numpy array of shape (299, 299, 3)
    array = img_to_array(img)
    # We add a dimension to transform our array into a "batch"
    # of size (1, 299, 299, 3)
    array = np.expand_dims(array, axis=0)
    return array


def make_gradcam_heatmap(img_array, model, last_conv_layer_name, classifier_layer_names):
    # First, we create a model that maps the input image to the activations
    # of the last conv layer
    last_conv_layer = model.get_layer(last_conv_layer_name)
    last_conv_layer_model = Model(model.inputs, last_conv_layer.output)

    # Second, we create a model that maps the activations of the last conv
    # layer to the final class predictions
    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 = Model(classifier_input, x)

    # Then, we compute the gradient of the top predicted class for our input image
    # with respect to the activations of the last conv layer
    with tf.GradientTape() as tape:
        # Compute activations of the last conv layer and make the tape watch it
        last_conv_layer_output = last_conv_layer_model(img_array)
        tape.watch(last_conv_layer_output)
        # Compute class predictions
        preds = classifier_model(last_conv_layer_output)
        top_pred_index = tf.argmax(preds[0])
        top_class_channel = preds[:, top_pred_index]

    # This is the gradient of the top predicted class with regard to
    # the output feature map of the last conv layer
    grads = tape.gradient(top_class_channel, last_conv_layer_output)

    # This is a vector where each entry is the mean intensity of the gradient
    # over a specific feature map channel
    pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))

    # We multiply each channel in the feature map array
    # by "how important this channel is" with regard to the top predicted class
    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]

    # The channel-wise mean of the resulting feature map
    # is our heatmap of class activation
    heatmap = np.mean(last_conv_layer_output, axis=-1)

    # For visualization purpose, we will also normalize the heatmap between 0 & 1
    heatmap = np.maximum(heatmap, 0) / np.max(heatmap)
    return heatmap
# Prepare image
img_array = preprocess_input(get_img_array(img_path, size=img_size))

# Make model
model = model_builder(weights="imagenet")

# Print what the top predicted class is
preds = model.predict(img_array)
print("Predicted:", decode_predictions(preds, top=1)[0])

# Generate class activation heatmap
heatmap = make_gradcam_heatmap(img_array, model, last_conv_layer_name, classifier_layer_names)

# Display heatmap
plt.matshow(heatmap)
plt.show()
# We load the original image
img = keras.preprocessing.image.load_img(img_path)
img = keras.preprocessing.image.img_to_array(img)

# 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.4 + img
superimposed_img = keras.preprocessing.image.array_to_img(superimposed_img)

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

# Display Grad CAM
display(Image(save_path))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11231181994335966, 'fraction_numerical': 0.0185571620211656, 'mean_word_length': 4.821691973969632, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 10, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '463633', 'license': 'MIT', 'n_tokens_mistral': 4757, 'n_tokens_neox': 4491, 'n_words': 1132, 'path': 'Reload_Model_Grad_Cam_COVID_ResNet152.ipynb', 'repo_name': 'youavang/Covid-19_CT_Scan_With_Deep_Learning', 'size': '13418'}