{"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":"markdown","source":"# Imports","metadata":{}},{"cell_type":"code","source":"import numpy as np \nimport pandas as pd\nimport cv2\nimport os\nimport datetime\nfrom sklearn.model_selection import train_test_split\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.applications import VGG16,DenseNet121,ResNet50,InceptionV3,EfficientNetB3\nimport tensorflow_addons as tfa\nfrom tensorflow.keras import layers\nimport tensorflow as tf\nfrom tqdm import notebook\nimport matplotlib.pyplot as plt\nfrom tensorflow.keras import layers\nfrom sklearn.metrics import confusion_matrix\nimport seaborn as sns\nfrom prettytable import PrettyTable","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMG_SIZE = 256\nBATCH_SIZE = 32","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Preprocessing","metadata":{}},{"cell_type":"markdown","source":"## Reading the data","metadata":{}},{"cell_type":"code","source":"df = pd.read_csv('/kaggle/input/aptos2019-blindness-detection/train.csv')\ndf.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Train Test Split","metadata":{}},{"cell_type":"code","source":"x_train, x_val, y_train, y_val = train_test_split(df['id_code'], df['diagnosis'], test_size=0.15, stratify=df['diagnosis'],random_state=100)\nx_train = x_train.reset_index(drop=True)\nx_val = x_val.reset_index(drop=True)\ny_train = y_train.reset_index(drop=True)\ny_val = y_val.reset_index(drop=True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x_train.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_train","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Adding complete path","metadata":{}},{"cell_type":"code","source":"x_train = x_train.apply(lambda i:'/kaggle/input/aptos2019-blindness-detection/train_images/' + i + \".png\")\nx_val = x_val.apply(lambda i: '/kaggle/input/aptos2019-blindness-detection/train_images/' + i + \".png\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Cropping the image","metadata":{}},{"cell_type":"code","source":"def crop_image_from_gray(img, tol=7):\n    \"\"\"\n    Applies masks to the orignal image and \n    returns the a preprocessed image with \n    3 channels\n    \n    :param img: A NumPy Array that will be cropped\n    :param tol: The tolerance used for masking\n    \n    :return: A NumPy array containing the cropped image\n    \"\"\"\n    # For Grayscale images\n    if img.ndim == 2:\n        mask = img > tol\n        return img[np.ix_(mask.any(axis = 1),mask.any(axis = 0))] # mask.any(axis = 1) makes a boolean array where each element in the array corresponds to each row in the image matrix. For a given row, the corresponding boolean value in the array is true if any value in the row is true.\n                                                                  # mask.any(axis = 0) makes a boolean array where each element in the array corresponds to each col in the image matrix. For a given col, the corresponding boolean value in the array is true if any value in the col is true.\n                                                                  # np.ix_(mask.any(axis = 1),mask.any(axis = 0)) gets those pixels from the image for which both the row and the column value is true.\n    \n    # If we have a normal RGB images\n    elif img.ndim == 3:\n        gray_img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) #RGB image to grayscale\n        mask = gray_img > tol #creates a boolean matrix\n        \n        check_shape = img[:,:,0][np.ix_(mask.any(1),mask.any(0))].shape[0]\n        if (check_shape == 0): # Whole image is cropped as it was too dark,\n            return img # return original image\n        else:\n            img1=img[:,:,0][np.ix_(mask.any(axis = 1),mask.any(axis = 0))] #applies mask to pixel 0\n            img2=img[:,:,1][np.ix_(mask.any(axis = 1),mask.any(axis = 0))]\n            img3=img[:,:,2][np.ix_(mask.any(axis = 1),mask.any(axis = 0))]\n            img = np.stack([img1,img2,img3],axis=-1)\n        return img","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path = \"/kaggle/input/aptos2019-blindness-detection/train_images/001639a390f0.png\"\nimg = cv2.imread(path)\nimg = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n\nplt.subplot(1, 2, 1)\nplt.axis('off')\nplt.imshow(img);\nplt.subplot(1, 2, 2)\nimg_cropped = crop_image_from_gray(img)\nplt.axis('off')\nplt.imshow(img_cropped);","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Preprocessing pipeline","metadata":{}},{"cell_type":"code","source":"def preprocess(image_path):\n    image = cv2.imread(image_path)\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n    image = crop_image_from_gray(image)\n    image = cv2.resize(image, (IMG_SIZE, IMG_SIZE))\n    image = cv2.addWeighted (image, 4, cv2.GaussianBlur(image, (0,0) ,10), -4, 128)\n    return image","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(6,6))\nfor y,x in enumerate(x_train[:9]):\n    plt.subplot(3, 3, y+1)\n    plt.axis('off')\n    i = preprocess(x)\n    plt.imshow(i)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model Training","metadata":{}},{"cell_type":"markdown","source":"## Making an array of train and validation images","metadata":{}},{"cell_type":"code","source":"train_images = np.empty((len(x_train),IMG_SIZE,IMG_SIZE,3), dtype='uint8')\nfor i,path in enumerate(notebook.tqdm(x_train)):\n    train_images[i] = preprocess(path)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_train = pd.get_dummies(y_train).values","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_images = np.empty((len(x_val),IMG_SIZE,IMG_SIZE,3), dtype='uint8')\nfor i,path in enumerate(notebook.tqdm(x_val)):\n    val_images[i] = preprocess(path)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_val = pd.get_dummies(y_val).values","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Cohen Kappa Metric","metadata":{}},{"cell_type":"code","source":"qwk = tfa.metrics.CohenKappa(5,weightage='quadratic')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Callbacks","metadata":{}},{"cell_type":"code","source":"class Save_CB(tf.keras.callbacks.Callback):\n    def __init__(self,name):\n        self.name = name\n    def on_train_begin(self, logs={}):\n        self.max = 0\n    def on_epoch_end(self, epoch, logs={}):\n        if logs['val_cohen_kappa'] > self.max:\n            self.max = logs['val_cohen_kappa']\n            print('Validation kappa improved, saving model')\n            self.model.save(str(round(self.max,2))+'_'+self.name+'_.h5')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 1. Simple CNN","metadata":{}},{"cell_type":"code","source":"cb = Save_CB('CNN')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"input1 = layers.Input((IMG_SIZE,IMG_SIZE,3))\nx = layers.Conv2D(filters=32,kernel_size=3,activation='relu')(input1)\nx = layers.MaxPooling2D(pool_size=2)(x)\nx = layers.Dropout(0.2)(x)\nx = layers.Flatten()(x)\nx = layers.Dense(32,activation='relu')(x)\noutput1 = layers.Dense(5,activation = 'softmax')(x)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model1=tf.keras.Model(inputs=input1, outputs=output1)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model1.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model1.compile(loss='categorical_crossentropy',\n              optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),\n              metrics=[qwk]\n              )","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model1.fit(train_images, y_train, \n                     steps_per_epoch= len(y_train) // BATCH_SIZE, \n                     epochs=10, \n                     validation_data = (val_images,y_val), \n                     validation_steps = len(y_val) // BATCH_SIZE,\n                     callbacks = cb\n                     )","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Results","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=[12,6])\nplt.subplot(2,2,1)\nplt.plot(history.history['loss'],label='loss')\nplt.plot(history.history['val_loss'],label='val_loss')\nplt.xlabel('Epoch')\nplt.ylabel('Cross Entropy Loss')\nplt.legend()\nplt.title('Cross Entropy Loss Per Epoch')\n\nplt.subplot(2,2,2)\nplt.plot(history.history['cohen_kappa'],label='cohen_kappa')\nplt.plot(history.history['val_cohen_kappa'],label='val_cohen_kappa')\nplt.xlabel('Epoch')\nplt.ylabel('Kappa Score')\nplt.title('Kappa Score Per Epoch')\nplt.legend()\n\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_pred = model1.predict(val_images)\ncf_matrix = confusion_matrix([np.argmax(x) for x in y_val], [np.argmax(x) for x in y_pred])\nsns.heatmap(cf_matrix, annot=True, fmt=\"0\")\nplt.ylabel(\"True Labels\")\nplt.xlabel(\"Predicted Labels\")\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2. VGG 16","metadata":{}},{"cell_type":"code","source":"cb = Save_CB('VGG16')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vgg16_model=VGG16(input_shape=(IMG_SIZE,IMG_SIZE,3), weights='imagenet', include_top=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x = vgg16_model.output\nx = layers.Conv2D(filters=32,kernel_size=3,activation='relu')(x)\nx = layers.MaxPooling2D(pool_size=2)(x)\nx = layers.Dropout(0.2)(x)\nx = layers.Flatten()(x)\nx = layers.Dense(32,activation='relu')(x)\nvgg16_output = layers.Dense(units=5, activation='softmax')(x)\n\n#base_model.trainable=False","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_vgg = tf.keras.Model(inputs = vgg16_model.inputs, outputs=vgg16_output)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_vgg.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_vgg.compile(loss='categorical_crossentropy',\n              optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),\n              metrics=[qwk]\n              )","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history_vgg = model_vgg.fit(train_images, y_train, \n                            steps_per_epoch= len(y_train) // BATCH_SIZE, \n                            epochs=10,\n                            validation_data = (val_images,y_val), \n                            validation_steps = len(y_val) // BATCH_SIZE,\n                            callbacks = cb\n                           )","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Results","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=[12,6])\nplt.subplot(2,2,1)\nplt.plot(history_vgg.history['loss'],label='loss')\nplt.plot(history_vgg.history['val_loss'],label='val_loss')\nplt.xlabel('Epoch')\nplt.ylabel('Cross Entropy Loss')\nplt.legend()\nplt.title('Cross Entropy Loss Per Epoch')\n\nplt.subplot(2,2,2)\nplt.plot(history_vgg.history['cohen_kappa'],label='cohen_kappa')\nplt.plot(history_vgg.history['val_cohen_kappa'],label='val_cohen_kappa')\nplt.xlabel('Epoch')\nplt.ylabel('Kappa Score')\nplt.title('Kappa Score Per Epoch')\nplt.legend()\n\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_pred = model_vgg.predict(val_images)\ncf_matrix = confusion_matrix([np.argmax(x) for x in y_val], [np.argmax(x) for x in y_pred])\nsns.heatmap(cf_matrix, annot=True, fmt=\"0\")\nplt.ylabel(\"True Labels\")\nplt.xlabel(\"Predicted Labels\")\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 3. DenseNet121","metadata":{}},{"cell_type":"code","source":"cb = Save_CB('Dense121')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"densenet = DenseNet121(\n    weights='imagenet',\n    include_top=False,\n    input_shape=(IMG_SIZE,IMG_SIZE,3)\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x = densenet.output\nx = layers.GlobalAveragePooling2D()(x)\nx = layers.Dropout(0.5)(x)\ndensenet_op = layers.Dense(5, activation='softmax')(x)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_dn = tf.keras.Model(inputs = densenet.inputs, outputs=densenet_op)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_dn.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_dn.compile(loss='categorical_crossentropy',\n              optimizer=tf.keras.optimizers.Adam(learning_rate=0.00005),\n              metrics=[qwk]\n              )","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history_dn = model_dn.fit(train_images, y_train, \n                            steps_per_epoch= len(y_train) // BATCH_SIZE, \n                            epochs=20,\n                            validation_data = (val_images,y_val), \n                            validation_steps = len(y_val) // BATCH_SIZE,\n                            callbacks = cb\n                           )","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Results","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=[12,6])\nplt.subplot(2,2,1)\nplt.plot(history_dn.history['loss'],label='loss')\nplt.plot(history_dn.history['val_loss'],label='val_loss')\nplt.xlabel('Epoch')\nplt.ylabel('Cross Entropy Loss')\nplt.legend()\nplt.title('Cross Entropy Loss Per Epoch')\n\nplt.subplot(2,2,2)\nplt.plot(history_dn.history['cohen_kappa'],label='cohen_kappa')\nplt.plot(history_dn.history['val_cohen_kappa'],label='val_cohen_kappa')\nplt.xlabel('Epoch')\nplt.ylabel('Kappa Score')\nplt.title('Kappa Score Per Epoch')\nplt.legend()\n\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_pred = model_dn.predict(val_images)\ncf_matrix = confusion_matrix([np.argmax(x) for x in y_val], [np.argmax(x) for x in y_pred])\nsns.heatmap(cf_matrix, annot=True, fmt=\"0\")\nplt.ylabel(\"True Labels\")\nplt.xlabel(\"Predicted Labels\")\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 4. ResNet50","metadata":{}},{"cell_type":"code","source":"cb = Save_CB('Resnet')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"resnet = ResNet50(weights='imagenet', \n                  include_top=False, \n                  input_shape=(IMG_SIZE,IMG_SIZE,3)\n                 )","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x = resnet.output\nx = layers.GlobalAveragePooling2D()(x)\nx = layers.Dropout(0.5)(x)\nresnet_op = layers.Dense(5, activation='softmax')(x)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_rn = tf.keras.Model(inputs = resnet.inputs, outputs=resnet_op)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_rn.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_rn.compile(loss='categorical_crossentropy',\n              optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),\n              metrics=[qwk]\n              )","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history_rn = model_rn.fit(train_images, y_train, \n                            steps_per_epoch= len(y_train) // BATCH_SIZE, \n                            epochs=15,\n                            validation_data = (val_images,y_val), \n                            validation_steps = len(y_val) // BATCH_SIZE,\n                            callbacks = cb\n                           )","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Results","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=[12,6])\nplt.subplot(2,2,1)\nplt.plot(history_rn.history['loss'],label='loss')\nplt.plot(history_rn.history['val_loss'],label='val_loss')\nplt.xlabel('Epoch')\nplt.ylabel('Cross Entropy Loss')\nplt.legend()\nplt.title('Cross Entropy Loss Per Epoch')\n\nplt.subplot(2,2,2)\nplt.plot(history_rn.history['cohen_kappa'],label='cohen_kappa')\nplt.plot(history_rn.history['val_cohen_kappa'],label='val_cohen_kappa')\nplt.xlabel('Epoch')\nplt.ylabel('Kappa Score')\nplt.title('Kappa Score Per Epoch')\nplt.legend()\n\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_pred = model_rn.predict(val_images)\ncf_matrix = confusion_matrix([np.argmax(x) for x in y_val], [np.argmax(x) for x in y_pred])\nsns.heatmap(cf_matrix, annot=True, fmt=\"0\")\nplt.ylabel(\"True Labels\")\nplt.xlabel(\"Predicted Labels\")\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 5. InceptionNetV3","metadata":{}},{"cell_type":"code","source":"cb = Save_CB('Incnet')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"incnet = InceptionV3(weights='imagenet', \n                     include_top=False, \n                     input_shape=(IMG_SIZE,IMG_SIZE,3)\n                    )","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x = incnet.output\nx = layers.GlobalAveragePooling2D()(x)\nx = layers.Dropout(0.5)(x)\nincnet_op = layers.Dense(5, activation='softmax')(x)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_in = tf.keras.Model(inputs = incnet.inputs, outputs=incnet_op)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_in.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_in.compile(loss='categorical_crossentropy',\n              optimizer=tf.keras.optimizers.Adam(learning_rate=0.0002),\n              metrics=[qwk]\n              )","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history_in = model_in.fit(train_images, y_train, \n                            steps_per_epoch= len(y_train) // BATCH_SIZE, \n                            epochs=15,\n                            validation_data = (val_images,y_val), \n                            validation_steps = len(y_val) // BATCH_SIZE,\n                            callbacks = cb\n                           )","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Results","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=[12,6])\nplt.subplot(2,2,1)\nplt.plot(history_in.history['loss'],label='loss')\nplt.plot(history_in.history['val_loss'],label='val_loss')\nplt.xlabel('Epoch')\nplt.ylabel('Cross Entropy Loss')\nplt.legend()\nplt.title('Cross Entropy Loss Per Epoch')\n\nplt.subplot(2,2,2)\nplt.plot(history_in.history['cohen_kappa'],label='cohen_kappa')\nplt.plot(history_in.history['val_cohen_kappa'],label='val_cohen_kappa')\nplt.xlabel('Epoch')\nplt.ylabel('Kappa Score')\nplt.title('Kappa Score Per Epoch')\nplt.legend()\n\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_pred = model_in.predict(val_images)\ncf_matrix = confusion_matrix([np.argmax(x) for x in y_val], [np.argmax(x) for x in y_pred])\nsns.heatmap(cf_matrix, annot=True, fmt=\"0\")\nplt.ylabel(\"True Labels\")\nplt.xlabel(\"Predicted Labels\")\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 6. EfficientNetB3","metadata":{}},{"cell_type":"code","source":"cb = Save_CB('Effcnet')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"effnet = EfficientNetB3(weights='imagenet', \n                     include_top=False, \n                     input_shape=(IMG_SIZE,IMG_SIZE,3)\n                    )","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x = effnet.output\nx = layers.GlobalAveragePooling2D()(x)\nx = layers.Dropout(0.5)(x)\neffnet_op = layers.Dense(5, activation='softmax')(x)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_en = tf.keras.Model(inputs = effnet.inputs, outputs=effnet_op)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_en.compile(loss='categorical_crossentropy',\n              optimizer=tf.keras.optimizers.Adam(learning_rate=0.0001),\n              metrics=[qwk]\n              )","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history_en = model_en.fit(train_images, y_train, \n                            steps_per_epoch= len(y_train) // BATCH_SIZE, \n                            epochs=15,\n                            validation_data = (val_images,y_val), \n                            validation_steps = len(y_val) // BATCH_SIZE,\n                            callbacks = cb\n                           )","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Results","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=[12,6])\nplt.subplot(2,2,1)\nplt.plot(history_en.history['loss'],label='loss')\nplt.plot(history_en.history['val_loss'],label='val_loss')\nplt.xlabel('Epoch')\nplt.ylabel('Cross Entropy Loss')\nplt.legend()\nplt.title('Cross Entropy Loss Per Epoch')\n\nplt.subplot(2,2,2)\nplt.plot(history_en.history['cohen_kappa'],label='cohen_kappa')\nplt.plot(history_en.history['val_cohen_kappa'],label='val_cohen_kappa')\nplt.xlabel('Epoch')\nplt.ylabel('Kappa Score')\nplt.title('Kappa Score Per Epoch')\nplt.legend()\n\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_pred = model_en.predict(val_images)\ncf_matrix = confusion_matrix([np.argmax(x) for x in y_val], [np.argmax(x) for x in y_pred])\nsns.heatmap(cf_matrix, annot=True, fmt=\"0\")\nplt.ylabel(\"True Labels\")\nplt.xlabel(\"Predicted Labels\")\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Summary","metadata":{}},{"cell_type":"code","source":"pt = PrettyTable()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pt.field_names = ['Model','Val Loss','Val Kappa']\npt.add_row([\"Simple CNN\", min(history.history['val_loss']), max(history.history['val_cohen_kappa'])])\npt.add_row([\"VGG16\", min(history_vgg.history['val_loss']), max(history_vgg.history['val_cohen_kappa'])])\npt.add_row([\"DenseNet121\", min(history_dn.history['val_loss']), max(history_dn.history['val_cohen_kappa'])])\npt.add_row([\"ResNet50\", min(history_rn.history['val_loss']), max(history_rn.history['val_cohen_kappa'])])\npt.add_row([\"InceptionV3\", min(history_in.history['val_loss']), max(history_in.history['val_cohen_kappa'])])\npt.add_row([\"EfficientNetB3\", min(history_en.history['val_loss']), max(history_en.history['val_cohen_kappa'])])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(pt)","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}