{"cells":[{"metadata":{},"cell_type":"markdown","source":"**Importing the required libraries**"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \nimport os\nimport gc\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport glob\nimport psutil\nimport matplotlib.pyplot as plt\nfrom tqdm import tqdm\nfrom math import ceil\nfrom sklearn.model_selection import train_test_split\nfrom tensorflow import set_random_seed\nimport tensorflow as tf\nimport keras\nfrom keras.applications.inception_v3 import InceptionV3\nfrom keras.preprocessing import image\nfrom keras.layers import Conv2D, MaxPooling2D, GlobalAveragePooling2D\nfrom keras.layers import Flatten, Dense\nfrom keras.models import Model\nfrom keras.layers import BatchNormalization\nfrom keras.optimizers import SGD\nfrom keras.callbacks import EarlyStopping, ReduceLROnPlateau\nfrom keras.layers import Input\nfrom keras import backend as K\n\nprint(os.listdir('/kaggle/input'))\nprint(os.listdir('/kaggle/input/inceptionv3/'))\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Declaring the constansts**"},{"metadata":{"trusted":true},"cell_type":"code","source":"SEED = 7\nnp.random.seed(SEED)\nset_random_seed(SEED)\ndir_path = \"/kaggle/input/\"\nIMG_DIM = 299  # 224\nBATCH_SIZE = 8\nCHANNEL_SIZE = 3\nNUM_EPOCHS = 60\nTRAIN_DIR = 'train_images'\nTEST_DIR = 'test_images'\nFREEZE_LAYERS = 2  # freeze the first this many layers for training\nCLASSS = {0: \"No DR\", 1: \"Mild\", 2: \"Moderate\", 3: \"Severe\", 4: \"Proliferative DR\"}\nNUM_CLASSS = 5","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ROOT_PATH = '/kaggle/input/aptos2019-blindness-detection'\nTRAIN_PATH = '/kaggle/input/aptos2019-blindness-detection/' + TRAIN_DIR \nTEST_PATH = '/kaggle/input/aptos2019-blindness-detection/' + TEST_DIR \ndir_path = ROOT_PATH + '/'","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Loading the dataframes**"},{"metadata":{"trusted":true},"cell_type":"code","source":"# print names of train images\ntrain_img_names = glob.glob(TRAIN_PATH + '/*.png')\n#print(train_img_names)\n\ndf_train = pd.read_csv(ROOT_PATH + '/train.csv')\n#print(df_train)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# print names of test images\ntest_img_names = glob.glob(TEST_PATH + '/*.png')\n#print(test_img_names)\ndf_test = pd.read_csv(ROOT_PATH + '/test.csv')\n#print(df_test)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Function to show one image\n\ndef draw_img(imgs, target_dir, class_label='0'):\n    for row in enumerate(imgs.iterrows()):\n        name = row[1][1]['id_code'] + '.png'\n        print(name)\n        plt.figure(figsize=(15,10))\n        img = plt.imread(dir_path + target_dir + '/' + name)\n        plt.imshow(img)\n        plt.title(class_label)\n        plt.show()\n        del img\n        gc.collect","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Showing randomly chosen No-DR image one at a time** "},{"metadata":{"trusted":true},"cell_type":"code","source":"# Showing the class 0 image randomly\nCLASS_ID = 0\ndraw_img(df_train[df_train.diagnosis == CLASS_ID].sample(n=1), 'train_images', CLASSS[CLASS_ID])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Showing randomly chosen Mild DR image one at a time** "},{"metadata":{"trusted":true},"cell_type":"code","source":"# Showing the class 1 image randomly\nCLASS_ID = 1\ndraw_img(df_train[df_train.diagnosis == CLASS_ID].sample(n=1), 'train_images', CLASSS[CLASS_ID])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Showing randomly chosen Moderate DR image one at a time** "},{"metadata":{"trusted":true},"cell_type":"code","source":"# Showing the class 2 image randomly\nCLASS_ID = 2\ndraw_img(df_train[df_train.diagnosis == CLASS_ID].sample(n=1), 'train_images', CLASSS[CLASS_ID])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Showing randomly chosen Severe DR image one at a time** "},{"metadata":{"trusted":true},"cell_type":"code","source":"# Showing the class 3 image randomly\nCLASS_ID = 3\ndraw_img(df_train[df_train.diagnosis == CLASS_ID].sample(n=1), 'train_images', CLASSS[CLASS_ID])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Showing randomly chosen Proliferative DR image one at a time** "},{"metadata":{"trusted":true},"cell_type":"code","source":"# Showing the class 4 image randomly\nCLASS_ID = 4\ndraw_img(df_train[df_train.diagnosis == CLASS_ID].sample(n=1), 'train_images', CLASSS[CLASS_ID])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"gc.collect()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Split the train data into train and test(validation) set**"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Split Dataset\n\nx_train, x_test, y_train, y_test = train_test_split(df_train.id_code, df_train.diagnosis, test_size=0.2,\n                                                    random_state=SEED, stratify=df_train.diagnosis)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Obervations:**\nThe differences between the classes are very minute and intricate in *some cases*, which is difficult to detect by human eyes. So to capture the intricacies we can consider using Inception Network as it combines the information from different scales of the image and the 1x1 convolution helps to detect the complex functions as well as it helps to reduce dimension. Let's see how it goes.... I have taken help from the following link for the inception module architecture:\nhttps://becominghuman.ai/understanding-and-coding-inception-module-in-keras-eb56e9056b4b"},{"metadata":{},"cell_type":"markdown","source":"**Defining the inception network**"},{"metadata":{"trusted":true},"cell_type":"code","source":"input_tensor = Input(shape = (299, 299, 3))\n\n# create the base pre-trained model\nbase_model = InceptionV3(weights=None, include_top=False, input_tensor=input_tensor)\nbase_model.load_weights('/kaggle/input/inceptionv3/inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5')\n\n# add a global spatial average pooling layer\nx = base_model.output\noutput = BatchNormalization()(x)\nx = GlobalAveragePooling2D()(x)\n\n# let's add a fully-connected layer\nx = Dense(1024, activation='relu')(x)\n\n# and a logistic layer -- let's say we have 200 classes\npredictions = Dense(NUM_CLASSS, activation='softmax')(x)\n\n# this is the model we will train\nmodel = Model(inputs=base_model.input, outputs=predictions)\n\n# first: train only the top layers (which were randomly initialized)\n# i.e. freeze all convolutional InceptionV3 layers\nfor layer in base_model.layers:\n    layer.trainable = False\n\nfor layer in model.layers:\n    layer.trainable = True\n    \nprint(model.summary())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"epochs = 25\nlrate = 0.01\ndecay = lrate/epochs\nsgd = SGD(lr=lrate, momentum=0.9, decay=decay, nesterov=False)\nmodel.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Image Data Generator**: with Image Data Generator we can use Model.fit_generator() instead of Model.fit(). The 1st one exploits multiprocessing in python, while the 2nd one does not."},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"available RAM:\", psutil.virtual_memory())\ngc.collect()\nprint(\"available RAM:\", psutil.virtual_memory())\n\ndf_train.id_code = df_train.id_code.apply(lambda x: x + \".png\")\ndf_test.id_code = df_test.id_code.apply(lambda x: x + \".png\")\ndf_train['diagnosis'] = df_train['diagnosis'].astype('str')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Data Generator\ntrain_datagen = image.ImageDataGenerator(rescale=1. / 255, validation_split=0.15, horizontal_flip=True,\n                                         vertical_flip=True, rotation_range=360, zoom_range=0.2, shear_range=0.1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_generator = train_datagen.flow_from_dataframe(dataframe=df_train,\n                                                    directory= TRAIN_PATH + '/',\n                                                    x_col='id_code',\n                                                    y_col='diagnosis',\n                                                    batch_size=BATCH_SIZE,\n                                                    class_mode='categorical',\n                                                    target_size=(IMG_DIM, IMG_DIM),\n                                                    subset='training',\n                                                    shaffle=True,\n                                                    seed=SEED\n                                                    )\nvalid_generator = train_datagen.flow_from_dataframe(dataframe=df_train,\n                                                    directory= TRAIN_PATH + '/',\n                                                    x_col='id_code',\n                                                    y_col='diagnosis',\n                                                    batch_size=BATCH_SIZE,\n                                                    class_mode='categorical',\n                                                    target_size=(IMG_DIM, IMG_DIM),\n                                                    subset='validation',\n                                                    shaffle=True,\n                                                    seed=SEED\n                                                    )\n#del x_train\n# # del x_test\n#del y_train\n# del y_test\ngc.collect()\n#  color_mode= \"grayscale\",","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"NUB_TRAIN_STEPS = train_generator.n // train_generator.batch_size\nNUB_VALID_STEPS = valid_generator.n // valid_generator.batch_size\n\nNUB_TRAIN_STEPS, NUB_VALID_STEPS","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**keras Callbacks:**\nDefining callback for EarlyStopping of training if the result is not significantly improving through some mentioned number of epochs. Defining callback for Reducnig learning rate on Platau regions of the underlying cost function."},{"metadata":{"trusted":true},"cell_type":"code","source":"eraly_stop = EarlyStopping(monitor='val_loss', min_delta=0.0001, patience=3, verbose=1, mode='auto')\n# Reducing the Learning Rate if result is not improving. \nreduce_lr = ReduceLROnPlateau(monitor='val_loss', min_delta=0.0004, patience=2, factor=0.1, min_lr=1e-6, mode='auto',\n                              verbose=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%capture\n!pip install wandb","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import wandb","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import wandb\nfrom wandb.keras import WandbCallback\nwandb.login()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"wandb.init(project='test3')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history = model.fit_generator(generator=train_generator,\n                                     steps_per_epoch=NUB_TRAIN_STEPS,\n                                     validation_data=valid_generator,\n                                     validation_steps=NUB_VALID_STEPS,\n                                     epochs=NUM_EPOCHS,\n                                     #shuffle=True,  \n                                     callbacks=[eraly_stop, reduce_lr],\n                                     verbose=1)\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Confusion Matrix "},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\nimport cv2\nimport random\nimport warnings\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nfrom sklearn.metrics import confusion_matrix, cohen_kappa_score\nfrom keras.models import Model\nfrom keras import optimizers, applications\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.callbacks import EarlyStopping, ReduceLROnPlateau\nfrom keras.layers import Dense, Dropout, GlobalAveragePooling2D, Input\n\n# Set seeds to make the experiment more reproducible.\nfrom tensorflow import set_random_seed\ndef seed_everything(seed=0):\n    random.seed(seed)\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    np.random.seed(seed)\n    set_random_seed(0)\nseed_everything()\n\n%matplotlib inline\nsns.set(style=\"whitegrid\")\nwarnings.filterwarnings(\"ignore\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train = pd.read_csv('../input/aptos2019-blindness-detection/train.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"STEP_SIZE_COMPLETE = complete_generator.n//complete_generator.batch_size\ntrain_preds = model.predict_generator(complete_generator, steps=STEP_SIZE_COMPLETE)\ntrain_preds = [np.argmax(pred) for pred in train_preds]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"labels = ['0 - No DR', '1 - Mild', '2 - Moderate', '3 - Severe', '4 - Proliferative DR']\ncnf_matrix = confusion_matrix(train['diagnosis'].astype('int') \ncnf_matrix_norm = cnf_matrix.astype('float') / cnf_matrix.sum(axis=1)[:, np.newaxis]\ndf_cm = pd.DataFrame(cnf_matrix_norm, index=labels, columns=labels)\nplt.figure(figsize=(16, 7))\nsns.heatmap(df_cm, annot=True, fmt='.2f', cmap=\"Blues\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# STEP_SIZE_TEST=test_generator.n//test_generator.batch_size\n(eval_loss, eval_accuracy) = tqdm(\n    model.evaluate_generator(generator=valid_generator, steps=NUB_VALID_STEPS, pickle_safe=False))\nprint(\"[INFO] accuracy: {:.2f}%\".format(eval_accuracy * 100))\nprint(\"[INFO] Loss: {}\".format(eval_loss))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''scores = model.evaluate(x_test, y_test, verbose=1)\nprint(\"Accuracy: %.2f%%\" % (scores[1]*100))'''","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.metrics import confusion_matrix\nfrom sklearn.metrics import ConfusionMatrixDisplay\n\ny_pred = clf.predict(X_test)\ncm = confusion_matrix(y_test, y_pred)\n\ncm_display = ConfusionMatrixDisplay(cm).plot()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"accu = history.history['acc']\nval_acc = history.history['val_acc']\n\nplt.plot(accu, label=\"Accuracy\")\nplt.plot(val_acc)\nplt.xlabel(\"Epoch\")\nplt.ylabel(\"Accuracy\")\nplt.legend(['Acc', 'val_acc'])\nplt.plot(np.argmax(history.history[\"val_acc\"]), np.max(history.history[\"val_acc\"]), marker=\"x\", color=\"r\",\n         label=\"best model\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(8, 8))\nplt.title(\"Learning curve\")\nplt.plot(history.history[\"loss\"], label=\"loss\")\nplt.plot(history.history[\"val_loss\"], label=\"val_loss\")\nplt.plot(np.argmin(history.history[\"val_loss\"]), np.min(history.history[\"val_loss\"]), marker=\"x\", color=\"r\",\n         label=\"best model\")\nplt.xlabel(\"Epochs\")\nplt.ylabel(\"log_loss\")\nplt.legend();","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_datagen = image.ImageDataGenerator(rescale=1. / 255, validation_split=0.2, horizontal_flip=True)\n\ntest_generator = test_datagen.flow_from_dataframe(dataframe=df_test,\n                                                  directory= TEST_PATH  + '/',\n                                                  x_col=\"id_code\",\n                                                  target_size=(IMG_DIM, IMG_DIM),\n                                                  batch_size=1,\n                                                  shuffle=False,\n                                                  class_mode=None,\n                                                  seed=SEED)\n# del df_test\nprint(df_test.shape[0])\n# del train_datagen\n# del traabsin_generator\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# evaluating the model on test data\n\ntta_steps = 5\npreds_tta = []\nfor i in tqdm(range(tta_steps)):\n    test_generator.reset()\n    preds = model.predict_generator(generator=test_generator, steps=ceil(df_test.shape[0]))\n    #     print('Before ', preds.shape)\n    preds_tta.append(preds)\n#     print(i,  len(preds_tta))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"final_pred = np.mean(preds_tta, axis=0)\npredicted_class_indices = np.argmax(final_pred, axis=1)\nlen(predicted_class_indices)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"results = pd.DataFrame({\"id_code\": test_generator.filenames, \"diagnosis\": predicted_class_indices})\nresults.id_code = results.id_code.apply(lambda x: x[:-4])  # results.head()\nresults.to_csv(\"submission.csv\", index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(results)","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}