{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport pandas as pd\nfrom PIL import Image\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport random\nfrom collections import defaultdict\nimport seaborn as sns\nfrom keras.preprocessing.image import ImageDataGenerator\nimport tensorflow as tf\nimport tensorflow_addons as tfa","metadata":{"execution":{"iopub.status.busy":"2022-10-17T14:27:16.846828Z","iopub.execute_input":"2022-10-17T14:27:16.847218Z","iopub.status.idle":"2022-10-17T14:27:22.635791Z","shell.execute_reply.started":"2022-10-17T14:27:16.847123Z","shell.execute_reply":"2022-10-17T14:27:22.634886Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_path = \"../input/skin-lesion-analysis-toward-melanoma-detection/skin-lesions/train\"\ntest_path = \"../input/skin-lesion-analysis-toward-melanoma-detection/skin-lesions/test\"\nval_path = \"../input/skin-lesion-analysis-toward-melanoma-detection/skin-lesions/valid\"\n\n","metadata":{"execution":{"iopub.status.busy":"2022-10-17T14:27:22.637144Z","iopub.execute_input":"2022-10-17T14:27:22.637472Z","iopub.status.idle":"2022-10-17T14:27:22.642876Z","shell.execute_reply.started":"2022-10-17T14:27:22.637431Z","shell.execute_reply":"2022-10-17T14:27:22.642000Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tqdm import tqdm\nfrom PIL import Image\nfrom collections import defaultdict\n\nX_train = []\nY_train = []\n\nfor target in os.listdir(train_path):\n    target_path = os.path.join(train_path, target)\n    for file in tqdm(os.listdir(target_path)):\n        file_path = os.path.join(target_path, file)\n        X_train.append(file_path)\n        Y_train.append(target)","metadata":{"execution":{"iopub.status.busy":"2022-10-17T14:27:22.645125Z","iopub.execute_input":"2022-10-17T14:27:22.645753Z","iopub.status.idle":"2022-10-17T14:27:23.242916Z","shell.execute_reply.started":"2022-10-17T14:27:22.645717Z","shell.execute_reply":"2022-10-17T14:27:23.242133Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tqdm import tqdm\nfrom PIL import Image\nfrom collections import defaultdict\n\nX_test = []\nY_test = []\n\nfor target in os.listdir(test_path):\n    target_path = os.path.join(test_path, target)\n    for file in tqdm(os.listdir(target_path)):\n        file_path = os.path.join(target_path, file)\n        X_test.append(file_path)\n        Y_test.append(target)","metadata":{"execution":{"iopub.status.busy":"2022-10-17T14:27:23.248484Z","iopub.execute_input":"2022-10-17T14:27:23.249004Z","iopub.status.idle":"2022-10-17T14:27:23.551750Z","shell.execute_reply.started":"2022-10-17T14:27:23.248961Z","shell.execute_reply":"2022-10-17T14:27:23.550979Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tqdm import tqdm\nfrom PIL import Image\nfrom collections import defaultdict\n\nX_val = []\nY_val = []\n\nfor target in os.listdir(test_path):\n    target_path = os.path.join(test_path, target)\n    for file in tqdm(os.listdir(target_path)):\n        file_path = os.path.join(target_path, file)\n        X_val.append(file_path)\n        Y_val.append(target)","metadata":{"execution":{"iopub.status.busy":"2022-10-17T14:27:23.552815Z","iopub.execute_input":"2022-10-17T14:27:23.553139Z","iopub.status.idle":"2022-10-17T14:27:23.582611Z","shell.execute_reply.started":"2022-10-17T14:27:23.553105Z","shell.execute_reply":"2022-10-17T14:27:23.581873Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sns.countplot(x = Y_train)","metadata":{"execution":{"iopub.status.busy":"2022-10-17T14:27:23.583577Z","iopub.execute_input":"2022-10-17T14:27:23.583861Z","iopub.status.idle":"2022-10-17T14:27:23.803582Z","shell.execute_reply.started":"2022-10-17T14:27:23.583832Z","shell.execute_reply":"2022-10-17T14:27:23.802777Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sns.countplot(x = Y_test)","metadata":{"execution":{"iopub.status.busy":"2022-10-17T14:27:23.804658Z","iopub.execute_input":"2022-10-17T14:27:23.805096Z","iopub.status.idle":"2022-10-17T14:27:23.983686Z","shell.execute_reply.started":"2022-10-17T14:27:23.805062Z","shell.execute_reply":"2022-10-17T14:27:23.982873Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sns.countplot(x = Y_val)","metadata":{"execution":{"iopub.status.busy":"2022-10-17T14:27:23.988492Z","iopub.execute_input":"2022-10-17T14:27:23.990422Z","iopub.status.idle":"2022-10-17T14:27:24.135618Z","shell.execute_reply.started":"2022-10-17T14:27:23.990379Z","shell.execute_reply":"2022-10-17T14:27:24.134785Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train = pd.DataFrame(list(zip(X_train, Y_train)), columns =['image_path', 'label'])\ndf_val = pd.DataFrame(list(zip(X_val, Y_val)), columns =['image_path', 'label'])\ndf_test = pd.DataFrame(list(zip(X_test, Y_test)), columns =['image_path', 'label'])","metadata":{"execution":{"iopub.status.busy":"2022-10-17T14:27:24.137411Z","iopub.execute_input":"2022-10-17T14:27:24.137752Z","iopub.status.idle":"2022-10-17T14:27:24.145780Z","shell.execute_reply.started":"2022-10-17T14:27:24.137716Z","shell.execute_reply":"2022-10-17T14:27:24.144862Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.preprocessing.image import ImageDataGenerator\n\ntrain_aug = ImageDataGenerator(\n    horizontal_flip=True,\n    width_shift_range=0.05,\n    height_shift_range=0.05,\n    zoom_range=0.05,\n    rescale = 1./255,\n    preprocessing_function=tf.keras.applications.vgg16.preprocess_input\n)\n\ntest_aug = ImageDataGenerator(\n    rescale = 1./255,\n    preprocessing_function=tf.keras.applications.vgg16.preprocess_input\n)\n\ntrain_generator= train_aug.flow_from_dataframe(\n    dataframe=df_train,\n    x_col=\"image_path\",\n    y_col=\"label\",\n    batch_size=16,\n    color_mode=\"rgb\",\n    target_size = (224, 224),\n    class_mode=\"categorical\")\n\nval_generator= test_aug.flow_from_dataframe(\n    dataframe=df_val,\n    x_col=\"image_path\",\n    y_col=\"label\",\n    batch_size=16,\n    color_mode=\"rgb\",\n    target_size = (224, 224),\n    class_mode=\"categorical\")\n\ntest_generator= test_aug.flow_from_dataframe(\n    dataframe=df_test,\n    x_col=\"image_path\",\n    y_col=\"label\",\n    color_mode=\"rgb\",\n    batch_size=16,\n    shuffle = False, \n    target_size = (224, 224),\n    class_mode=\"categorical\")","metadata":{"execution":{"iopub.status.busy":"2022-10-17T14:27:24.147556Z","iopub.execute_input":"2022-10-17T14:27:24.147944Z","iopub.status.idle":"2022-10-17T14:27:25.609621Z","shell.execute_reply.started":"2022-10-17T14:27:24.147905Z","shell.execute_reply":"2022-10-17T14:27:25.608750Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.applications.vgg16 import VGG16\nfrom keras.layers import Activation,Dense, Dropout, Flatten, Conv2D, MaxPool2D, MaxPooling2D,AveragePooling2D, BatchNormalization, PReLU, ReLU\nfrom keras.models import Model\nfrom keras.applications.inception_v3 import InceptionV3\nfrom keras.applications import ResNet50, InceptionResNetV2\n\ndef generate_model(pretrained_model = 'vgg16', num_classes=10):\n    if pretrained_model == 'inceptionv3':\n        base_model = InceptionV3(weights = 'imagenet', include_top=False, input_shape=(224, 224, 3))\n    elif pretrained_model == 'inceptionresnet':\n        base_model = InceptionResNetV2(weights = 'imagenet', include_top=False, input_shape=(224, 224, 3))\n    else:\n        base_model = VGG16(weights = 'imagenet', include_top=False, input_shape=(224, 224, 3)) # Topless\n    \n    x = base_model.output\n    x = Flatten()(x)\n    x = Dense(4096)(x)\n    x = ReLU()(x)\n    x = Dropout(0.5)(x)\n    x = Dense(4096)(x)\n    x = ReLU()(x)\n    x = Dropout(0.5)(x)\n    predictions = Dense(num_classes, activation='softmax')(x)\n    model = Model(inputs=base_model.input, outputs=predictions)\n    \n    #Freezing Convolutional Base\n    for layer in base_model.layers[:-3]:\n        layer.trainable = False  \n    return model","metadata":{"execution":{"iopub.status.busy":"2022-10-17T14:27:25.610948Z","iopub.execute_input":"2022-10-17T14:27:25.611298Z","iopub.status.idle":"2022-10-17T14:27:25.621240Z","shell.execute_reply.started":"2022-10-17T14:27:25.611261Z","shell.execute_reply":"2022-10-17T14:27:25.620258Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_model(model, train_generator,val_generator, num_epochs, optimizer, metrics):\n    model.compile(loss='categorical_crossentropy', \n                  optimizer=optimizer, \n                  metrics=metrics)\n    early_stop = tf.keras.callbacks.EarlyStopping(monitor=\"val_accuracy\",patience=40, verbose=1)\n    rlr = tf.keras.callbacks.ReduceLROnPlateau(monitor=\"val_loss\", factor=0.1, patience=5)\n    print(model.summary())\n    \n    history = model.fit(train_generator, epochs=num_epochs, \n                        validation_data=val_generator, verbose=1,\n                        callbacks = [early_stop, rlr])\n    \n    return model, history","metadata":{"execution":{"iopub.status.busy":"2022-10-17T14:27:25.622652Z","iopub.execute_input":"2022-10-17T14:27:25.623006Z","iopub.status.idle":"2022-10-17T14:27:25.634730Z","shell.execute_reply.started":"2022-10-17T14:27:25.622971Z","shell.execute_reply":"2022-10-17T14:27:25.633705Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import itertools\nimport sklearn\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.utils import class_weight\nfrom sklearn.preprocessing import LabelBinarizer\nfrom sklearn.metrics import roc_curve, auc, roc_auc_score, confusion_matrix, classification_report\n\nmetrics = ['accuracy',\n                tf.keras.metrics.AUC(),\n                tfa.metrics.CohenKappa(num_classes = 3),\n                tfa.metrics.F1Score(num_classes = 3),\n                tf.keras.metrics.Precision(), \n                tf.keras.metrics.Recall()]\n\ndef plot_loss(history):\n    plt.plot(history.history['loss'])\n    plt.plot(history.history['val_loss'])\n    plt.title('model loss')\n    plt.ylabel('loss')\n    plt.xlabel('epoch')\n    plt.legend(['train', 'val'], loc='upper left')\n    \ndef plot_acc(history):\n    plt.plot(history.history['accuracy'])\n    plt.plot(history.history['val_accuracy'])\n    plt.title('model accuracy')\n    plt.ylabel('accuracy')\n    plt.xlabel('epoch')\n    plt.legend(['train', 'val'], loc='upper left')\n    \n# It prints & plots the confusion matrix, normalization can be applied by setting normalize=True.\n    \ndef plot_confusion_matrix(cm, classes,normalize=False,title='Confusion matrix',cmap=plt.cm.Blues):\n\n    plt.figure(figsize = (5,5))\n    plt.imshow(cm, interpolation='nearest', cmap=cmap)\n    plt.title(title)\n    plt.colorbar()\n    tick_marks = np.arange(len(classes))\n    plt.xticks(tick_marks, classes, rotation=90)\n    plt.yticks(tick_marks, classes)\n    if normalize:\n        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]\n\n    thresh = cm.max() / 2.\n    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):\n        plt.text(j, i, cm[i, j],\n                 horizontalalignment=\"center\",\n                 color=\"white\" if cm[i, j] > thresh else \"black\")\n    plt.tight_layout()\n    plt.ylabel('True label')\n    plt.xlabel('Predicted label')\n\ndef plot_roc_curves(y_true, y_pred, num_classes, class_labels):\n    \n    lb = LabelBinarizer()\n    lb.fit(y_true)\n    y_test = lb.transform(y_true)\n\n    # Compute ROC curve and ROC area for each class\n    fpr = dict()\n    tpr = dict()\n    roc_auc = dict()\n    for i in range(num_classes):\n        fpr[i], tpr[i], _ = roc_curve(y_test[:, i], y_pred[:, i])\n        roc_auc[i] = auc(fpr[i], tpr[i])\n\n#     # Plot all ROC curves\n#     for i in range(num_classes):\n        #fig, c_ax = plt.subplots(1,1, figsize = (6, 4))\n        plt.plot(fpr[i], tpr[i],\n                 label='ROC curve of class {0} (area = {1:0.2f})'\n                 ''.format(class_labels[i], roc_auc[i]))\n        plt.xlabel('False Positive Rate')\n        plt.ylabel('True Positive Rate')\n        plt.title('ROC curve of class {0}'.format(class_labels[i]))\n        plt.legend(loc=\"lower right\")\n    plt.show()\n    return roc_auc_score(y_test, y_pred)","metadata":{"execution":{"iopub.status.busy":"2022-10-17T14:27:25.636112Z","iopub.execute_input":"2022-10-17T14:27:25.636450Z","iopub.status.idle":"2022-10-17T14:27:28.290788Z","shell.execute_reply.started":"2022-10-17T14:27:25.636416Z","shell.execute_reply":"2022-10-17T14:27:28.289970Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_roc_curves(y_true, y_pred, num_classes, class_labels):\n    \n    lb = LabelBinarizer()\n    lb.fit(y_true)\n    y_test = lb.transform(y_true)\n\n    # Compute ROC curve and ROC area for each class\n    fpr = dict()\n    tpr = dict()\n    roc_auc = dict()\n    for i in range(num_classes):\n        fpr[i], tpr[i], _ = roc_curve(y_test[:, i], y_pred[:, i])\n        roc_auc[i] = auc(fpr[i], tpr[i])\n\n#     # Plot all ROC curves\n#     for i in range(num_classes):\n        #fig, c_ax = plt.subplots(1,1, figsize = (6, 4))\n        plt.plot(fpr[i], tpr[i],\n                 label='ROC curve of class {0} (area = {1:0.2f})'\n                 ''.format(class_labels[i], roc_auc[i]))\n        plt.xlabel('False Positive Rate')\n        plt.ylabel('True Positive Rate')\n        plt.title('ROC curve of class {0}'.format(class_labels[i]))\n        plt.legend(loc=\"lower right\")\n    plt.show()\n    return roc_auc_score(y_test, y_pred)","metadata":{"execution":{"iopub.status.busy":"2022-10-17T14:27:28.292119Z","iopub.execute_input":"2022-10-17T14:27:28.292460Z","iopub.status.idle":"2022-10-17T14:27:28.301366Z","shell.execute_reply.started":"2022-10-17T14:27:28.292424Z","shell.execute_reply":"2022-10-17T14:27:28.300520Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def evaluate_model(model, history, test_generator):\n    # Evaluate model\n    score = model.evaluate(test_generator, verbose=0)\n    print('\\nTest set accuracy:', score[1], '\\n')\n    \n    y_true = np.array(test_generator.labels)\n    y_pred = model.predict(test_generator, verbose = 1)\n    y_pred_classes = np.argmax(y_pred,axis = 1)\n    class_labels = list(test_generator.class_indices.keys())   \n    \n    print('\\n', sklearn.metrics.classification_report(y_true, y_pred_classes, target_names=class_labels), sep='')\n    confusion_mtx = confusion_matrix(y_true, y_pred_classes)\n    plot_acc(history)\n    plt.show()\n    plot_loss(history)\n    plt.show()\n    plot_confusion_matrix(confusion_mtx, classes = class_labels)\n    plt.show()\n    print(\"ROC AUC score:\", plot_roc_curves(y_true, y_pred, 3, class_labels))","metadata":{"execution":{"iopub.status.busy":"2022-10-17T14:27:28.302639Z","iopub.execute_input":"2022-10-17T14:27:28.303058Z","iopub.status.idle":"2022-10-17T14:27:28.312055Z","shell.execute_reply.started":"2022-10-17T14:27:28.303008Z","shell.execute_reply":"2022-10-17T14:27:28.311211Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vgg_model = generate_model('vgg16', 3)","metadata":{"execution":{"iopub.status.busy":"2022-10-17T14:27:28.313329Z","iopub.execute_input":"2022-10-17T14:27:28.313826Z","iopub.status.idle":"2022-10-17T14:27:29.095866Z","shell.execute_reply.started":"2022-10-17T14:27:28.313791Z","shell.execute_reply":"2022-10-17T14:27:29.094915Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vgg_model, vgg_history = train_model(vgg_model, train_generator, val_generator, 20, tf.keras.optimizers.SGD(lr=0.001, momentum=0.9), metrics)","metadata":{"execution":{"iopub.status.busy":"2022-10-17T14:27:29.099262Z","iopub.execute_input":"2022-10-17T14:27:29.099639Z","iopub.status.idle":"2022-10-17T17:44:26.509550Z","shell.execute_reply.started":"2022-10-17T14:27:29.099597Z","shell.execute_reply":"2022-10-17T17:44:26.506350Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"evaluate_model(vgg_model, vgg_history, test_generator)","metadata":{"execution":{"iopub.status.busy":"2022-10-17T17:44:26.515202Z","iopub.execute_input":"2022-10-17T17:44:26.515482Z","iopub.status.idle":"2022-10-17T17:53:24.684803Z","shell.execute_reply.started":"2022-10-17T17:44:26.515451Z","shell.execute_reply":"2022-10-17T17:53:24.683706Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd","metadata":{"execution":{"iopub.status.busy":"2022-10-17T17:53:24.686493Z","iopub.execute_input":"2022-10-17T17:53:24.686853Z","iopub.status.idle":"2022-10-17T17:53:24.691414Z","shell.execute_reply.started":"2022-10-17T17:53:24.686816Z","shell.execute_reply":"2022-10-17T17:53:24.690223Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.preprocessing.image import load_img,img_to_array\nimage_path= df_test['image_path'][80]\nimg = load_img(image_path, target_size=(224,224,3)) # stores image in PIL format\nimage_array=img_to_array(img)\n","metadata":{"execution":{"iopub.status.busy":"2022-10-17T17:53:24.692793Z","iopub.execute_input":"2022-10-17T17:53:24.693164Z","iopub.status.idle":"2022-10-17T17:53:24.806811Z","shell.execute_reply.started":"2022-10-17T17:53:24.693103Z","shell.execute_reply":"2022-10-17T17:53:24.805896Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from PIL import Image\ndisplay(Image.open(image_path))","metadata":{"execution":{"iopub.status.busy":"2022-10-17T17:53:24.808103Z","iopub.execute_input":"2022-10-17T17:53:24.808421Z","iopub.status.idle":"2022-10-17T17:53:27.386591Z","shell.execute_reply.started":"2022-10-17T17:53:24.808385Z","shell.execute_reply":"2022-10-17T17:53:27.385289Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def make_gradcam_heatmap(img_array, model, last_conv_layer_name, pred_index=None):\n    # First, we create a model that maps the input image to the activations\n    # of the last conv layer as well as the output predictions\n\n    grad_model = tf.keras.models.Model([model.inputs], [model.get_layer(last_conv_layer_name).output, model.layers[-2].output])\n\n    # Then, we compute the gradient of the top predicted class for our input image\n    # with respect to the activations of the last conv layer\n    with tf.GradientTape() as tape:\n        last_conv_layer_output, preds = grad_model(img_array)\n        if pred_index is None:\n            pred_index = tf.argmax(preds[0])\n        class_channel = preds[:, pred_index]\n\n    # This is the gradient of the output neuron (top predicted or chosen)\n    # with regard to the output feature map of the last conv layer\n    grads = tape.gradient(class_channel, last_conv_layer_output)\n\n    # This is a vector where each entry is the mean intensity of the gradient\n    # over a specific feature map channel\n    pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))\n\n    # We multiply each channel in the feature map array\n    # by \"how important this channel is\" with regard to the top predicted class\n    # then sum all the channels to obtain the heatmap class activation\n    last_conv_layer_output = last_conv_layer_output[0]\n    heatmap = last_conv_layer_output @ pooled_grads[..., tf.newaxis]\n    heatmap = tf.squeeze(heatmap)\n\n    # For visualization purpose, we will also normalize the heatmap between 0 & 1\n    heatmap = tf.maximum(heatmap, 0) / tf.math.reduce_max(heatmap)\n    return heatmap.numpy()","metadata":{"execution":{"iopub.status.busy":"2022-10-17T17:53:27.387847Z","iopub.execute_input":"2022-10-17T17:53:27.388224Z","iopub.status.idle":"2022-10-17T17:53:27.408869Z","shell.execute_reply.started":"2022-10-17T17:53:27.388184Z","shell.execute_reply":"2022-10-17T17:53:27.407918Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Make model\nmodel = vgg_model\nlast_conv_layer_name =\"block5_conv3\"\n# Remove last layer's softmax\nmodel.layers[-1].activation = None\n\nimg_array=np.expand_dims(image_array, axis=0)\n# Prepare particular image \n\n# Generate class activation heatmap\nheatmap= make_gradcam_heatmap(img_array, model, last_conv_layer_name)\n\n# Display heatmap\nplt.matshow(heatmap)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-10-17T17:53:27.412549Z","iopub.execute_input":"2022-10-17T17:53:27.413272Z","iopub.status.idle":"2022-10-17T17:53:28.500828Z","shell.execute_reply.started":"2022-10-17T17:53:27.413236Z","shell.execute_reply":"2022-10-17T17:53:28.499442Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.cm as cm\ndef save_and_display_gradcam(img_path, heatmap, cam_path, alpha=0.4):\n    # Load the original image\n    img = tf.keras.preprocessing.image.load_img(img_path)\n    img = tf.keras.preprocessing.image.img_to_array(img)\n\n    # Rescale heatmap to a range 0-255\n    heatmap = np.uint8(255 * heatmap)\n\n    # Use jet colormap to colorize heatmap\n    jet = cm.get_cmap(\"jet\")\n\n    # Use RGB values of the colormap\n    jet_colors = jet(np.arange(256))[:, :3]\n    jet_heatmap = jet_colors[heatmap]\n\n    # Create an image with RGB colorized heatmap\n    jet_heatmap = tf.keras.preprocessing.image.array_to_img(jet_heatmap)\n    jet_heatmap = jet_heatmap.resize((img.shape[1], img.shape[0]))\n    jet_heatmap = tf.keras.preprocessing.image.img_to_array(jet_heatmap)\n\n    # Superimpose the heatmap on original image\n    superimposed_img = jet_heatmap * alpha + img\n    superimposed_img = tf.keras.preprocessing.image.array_to_img(superimposed_img)\n\n    # Save the superimposed image\n    superimposed_img.save(cam_path)\n\n    # Display Grad CAM\n    display(Image.open(cam_path))","metadata":{"execution":{"iopub.status.busy":"2022-10-17T17:53:28.502832Z","iopub.execute_input":"2022-10-17T17:53:28.503176Z","iopub.status.idle":"2022-10-17T17:53:28.521339Z","shell.execute_reply.started":"2022-10-17T17:53:28.503140Z","shell.execute_reply":"2022-10-17T17:53:28.520122Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"save_and_display_gradcam(image_path, heatmap,cam_path=\"/kaggle/working/GradCamTest.jpg\")","metadata":{"execution":{"iopub.status.busy":"2022-10-17T17:53:28.526597Z","iopub.execute_input":"2022-10-17T17:53:28.529367Z","iopub.status.idle":"2022-10-17T17:53:30.647878Z","shell.execute_reply.started":"2022-10-17T17:53:28.529311Z","shell.execute_reply":"2022-10-17T17:53:30.643273Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"incres_model = generate_model('inceptionresnet', 3)","metadata":{"execution":{"iopub.status.busy":"2022-10-17T17:53:30.649375Z","iopub.execute_input":"2022-10-17T17:53:30.649863Z","iopub.status.idle":"2022-10-17T17:53:36.532863Z","shell.execute_reply.started":"2022-10-17T17:53:30.649825Z","shell.execute_reply":"2022-10-17T17:53:36.532006Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"incres_model, incres_history = train_model(incres_model, train_generator, val_generator, 20, tf.keras.optimizers.SGD(lr=0.001, momentum=0.9), metrics)","metadata":{"execution":{"iopub.status.busy":"2022-10-17T17:53:36.534904Z","iopub.execute_input":"2022-10-17T17:53:36.535517Z","iopub.status.idle":"2022-10-17T21:15:06.754183Z","shell.execute_reply.started":"2022-10-17T17:53:36.535464Z","shell.execute_reply":"2022-10-17T21:15:06.751108Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"evaluate_model(incres_model, incres_history, test_generator)","metadata":{"execution":{"iopub.status.busy":"2022-10-17T21:15:06.762707Z","iopub.execute_input":"2022-10-17T21:15:06.763015Z","iopub.status.idle":"2022-10-17T21:24:12.599758Z","shell.execute_reply.started":"2022-10-17T21:15:06.762981Z","shell.execute_reply":"2022-10-17T21:24:12.598628Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Make model\nmodel = incres_model\nlast_conv_layer_name =\"conv_7b\"\n# Remove last layer's softmax\nmodel.layers[-1].activation = None\n\nimg_array=np.expand_dims(image_array, axis=0)\n# Prepare particular image \n\n# Generate class activation heatmap\nheatmap= make_gradcam_heatmap(img_array, model, last_conv_layer_name)\n\n# Display heatmap\nplt.matshow(heatmap)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-10-17T21:24:12.601282Z","iopub.execute_input":"2022-10-17T21:24:12.601669Z","iopub.status.idle":"2022-10-17T21:24:13.751658Z","shell.execute_reply.started":"2022-10-17T21:24:12.601629Z","shell.execute_reply":"2022-10-17T21:24:13.750352Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"save_and_display_gradcam(image_path, heatmap,cam_path=\"/kaggle/working/GradCamTest1.jpg\")","metadata":{"execution":{"iopub.status.busy":"2022-10-17T21:24:13.753208Z","iopub.execute_input":"2022-10-17T21:24:13.753540Z","iopub.status.idle":"2022-10-17T21:24:15.779199Z","shell.execute_reply.started":"2022-10-17T21:24:13.753497Z","shell.execute_reply":"2022-10-17T21:24:15.777434Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"inception_model = generate_model('inceptionv3', 3)\n","metadata":{"execution":{"iopub.status.busy":"2022-10-17T21:24:15.780437Z","iopub.execute_input":"2022-10-17T21:24:15.780877Z","iopub.status.idle":"2022-10-17T21:24:18.328522Z","shell.execute_reply.started":"2022-10-17T21:24:15.780841Z","shell.execute_reply":"2022-10-17T21:24:18.327647Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"inception_model, inception_history = train_model(inception_model, train_generator, val_generator, 20, tf.keras.optimizers.SGD(lr=0.001, momentum=0.9), metrics)","metadata":{"execution":{"iopub.status.busy":"2022-10-17T21:24:18.329870Z","iopub.execute_input":"2022-10-17T21:24:18.330224Z","iopub.status.idle":"2022-10-18T00:48:28.733898Z","shell.execute_reply.started":"2022-10-17T21:24:18.330188Z","shell.execute_reply":"2022-10-18T00:48:28.730517Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"evaluate_model(inception_model, inception_history, test_generator)","metadata":{"execution":{"iopub.status.busy":"2022-10-18T00:48:28.742381Z","iopub.execute_input":"2022-10-18T00:48:28.742676Z","iopub.status.idle":"2022-10-18T00:57:22.313786Z","shell.execute_reply.started":"2022-10-18T00:48:28.742644Z","shell.execute_reply":"2022-10-18T00:57:22.312738Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Make model\nmodel = inception_model\nlast_conv_layer_name =\"conv2d_296\"\n# Remove last layer's softmax\nmodel.layers[-1].activation = None\n\nimg_array=np.expand_dims(image_array, axis=0)\n# Prepare particular image \n\n# Generate class activation heatmap\nheatmap= make_gradcam_heatmap(img_array, model, last_conv_layer_name)\n\n# Display heatmap\nplt.matshow(heatmap)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-10-18T00:57:22.315314Z","iopub.execute_input":"2022-10-18T00:57:22.315694Z","iopub.status.idle":"2022-10-18T00:57:23.084449Z","shell.execute_reply.started":"2022-10-18T00:57:22.315654Z","shell.execute_reply":"2022-10-18T00:57:23.083171Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"save_and_display_gradcam(image_path, heatmap,cam_path=\"/kaggle/working/GradCamTest3.jpg\")","metadata":{"execution":{"iopub.status.busy":"2022-10-18T00:57:23.085932Z","iopub.execute_input":"2022-10-18T00:57:23.086612Z","iopub.status.idle":"2022-10-18T00:57:25.046904Z","shell.execute_reply.started":"2022-10-18T00:57:23.086568Z","shell.execute_reply":"2022-10-18T00:57:25.045917Z"},"trusted":true},"execution_count":null,"outputs":[]}]}