{"cells":[{"metadata":{},"cell_type":"markdown","source":"# **Final Research Project: Ammar Chalifah**\n**Baseline Comparison to Shidqie's Project**\n\nURL: https://www.kaggle.com/shidqiet/diabetic-retinopathy-mobilenetv2-svm/data\n\nComparing MobileNetV2 performance to EfficientNet family"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# Import Library\n\nimport numpy as np\nimport pandas as pd\n\nimport seaborn as sns\nimport matplotlib.pyplot as plt\n%matplotlib inline\n\nimport cv2\nfrom PIL import Image\n\nimport tensorflow as tf\nfrom keras import layers\nfrom tensorflow.keras import applications \nfrom keras.applications import MobileNetV2\nfrom keras.callbacks import Callback, ModelCheckpoint\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.models import Sequential, load_model\nfrom keras.optimizers import Adam\nfrom keras import models\n\n\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import cohen_kappa_score, accuracy_score, confusion_matrix\n\nfrom tqdm import tqdm","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.read_csv('../input/valid-and-test-ta/x_train_8.csv')\nvalid_df = pd.read_csv('../input/valid-and-test-ta/x_valid_8.csv')\nprint(train_df.shape)\nprint(valid_df.shape)\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df['diagnosis'].value_counts()\ntrain_df['diagnosis'].hist()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def display_samples(df, columns=4, rows=3):\n    fig=plt.figure(figsize=(5*columns, 4*rows))\n\n    for i in range(columns*rows):\n        image_path = df.loc[i,'id_code']\n        image_id = df.loc[i,'diagnosis']\n        img = cv2.imread(f'../input/aptos2019-blindness-detection/train_images/{image_path}.png')\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n        \n        fig.add_subplot(rows, columns, i+1)\n        plt.title(image_id)\n        plt.imshow(img)\n    \n    plt.tight_layout()\n\ndisplay_samples(train_df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#resample\nfrom sklearn.utils import resample\nX=train_df\nnormal=X[X.diagnosis==0]\nmild=X[X.diagnosis==1]\nmoderate=X[X.diagnosis==2]\nsevere=X[X.diagnosis==3]\npdr=X[X.diagnosis==4]\n\n#downsampled\nmild = resample(mild,\n                replace=True, # sample with replacement\n                n_samples=700, # match number in majority class\n                random_state=2020) # reproducible results\nmoderate = resample(moderate,\n                    replace=False, # sample with replacement\n                    n_samples=700, # match number in majority class\n                    random_state=2020) # reproducible results\nsevere = resample(severe,\n                  replace=True, # sample with replacement\n                  n_samples=700, # match number in majority class\n                  random_state=2020) # reproducible results\nnormal = resample(normal,\n                  replace=False, # sample with replacement\n                  n_samples=700, # match number in majority class\n                  random_state=2020) # reproducible results\npdr = resample(pdr,\n               replace=True, # sample with replacement\n               n_samples=700, # match number in majority class\n               random_state=2020) # reproducible results    \n\n# combine minority and downsampled majority\nsampled = pd.concat([normal, mild, moderate, severe, pdr])\n\n# checking counts\nsampled.diagnosis.value_counts()\n\ntrain_df = sampled\ntrain_df = train_df.sample(frac=1).reset_index(drop=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def preprocess_image(image_path, desired_size=224):\n    im = Image.open(image_path)\n    im = im.resize((desired_size, )*2, resample=Image.BILINEAR)\n    \n    return im","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"N = train_df.shape[0]\nx_train = np.empty((N, 224, 224, 3), dtype=np.float32)\n\nfor i, image_id in enumerate(tqdm(train_df['id_code'])):\n    x_train[i, :, :, :] = preprocess_image(\n        f'../input/aptos2019-blindness-detection/train_images/{image_id}.png'\n    )\n    \nN = valid_df.shape[0]\nx_val = np.empty((N, 224, 224, 3), dtype=np.float32)\n\nfor i, image_id in enumerate(tqdm(valid_df['id_code'])):\n    x_val[i, :, :, :] = preprocess_image(\n        f'../input/aptos2019-blindness-detection/train_images/{image_id}.png'\n    )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y_train = train_df['diagnosis']\ny_val = valid_df['diagnosis']\nprint(x_train.shape)\nprint(y_train.shape)\nprint(x_val.shape)\nprint(y_val.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"BATCH_SIZE = 32\n\ndef create_datagen():\n    return ImageDataGenerator(\n        zoom_range=0.1,  # set range for random zoom\n        rotation_range = 360,\n        fill_mode='constant',\n        cval=0.,\n        horizontal_flip=True,  # randomly flip images\n        vertical_flip=True,  # randomly flip images\n    )\n\n# Using generator\ndata_generator = create_datagen().flow(x_train, y_train, batch_size=BATCH_SIZE, seed=2019)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class Metrics(Callback):\n    def __init__(self, xval, yval):\n        super().__init__()\n        self.xval = xval\n        self.yval = yval\n        \n    def on_train_begin(self, logs={}):\n        self.val_kappas = []\n\n    def on_epoch_end(self, epoch, logs={}):\n        X_val = self.xval\n        y_val = self.yval\n        \n        y_pred = self.model.predict(X_val)\n        y_pred = np.clip(y_pred,0,4)\n        y_pred = y_pred.astype(int)\n\n        _val_kappa = cohen_kappa_score(\n            y_val,\n            y_pred, \n            weights='quadratic'\n        )\n\n        self.val_kappas.append(_val_kappa)\n\n        print(f\"val_kappa: {_val_kappa:.4f}\")\n        \n        if _val_kappa == max(self.val_kappas):\n            print(\"Validation Kappa has improved. Saving model.\")\n            self.model.save('model.h5')\n\n        return\n    \nkappa_metrics = Metrics(x_val, y_val)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"efficientnet = applications.EfficientNetB0(include_top=False, weights='imagenet', input_shape=(224,224,3))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def build_model():\n    model = Sequential()\n    model.add(efficientnet)\n    model.add(layers.GlobalAveragePooling2D())\n    model.add(layers.Dense(256))\n    model.add(layers.Dense(256))\n    model.add(layers.Dense(1))\n    \n    model.compile(\n        loss='mse',\n        optimizer=Adam(lr=0.0001),\n        metrics=['accuracy']\n    )\n    \n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = build_model()\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history = model.fit_generator(\n    data_generator,\n    steps_per_epoch=x_train.shape[0] / BATCH_SIZE,\n    epochs=100,\n    validation_data = (x_val, y_val),\n    callbacks=[kappa_metrics]\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#plotting accuracies and loss\nhistory_df = pd.DataFrame(history.history)\nhistory_df[['loss', 'val_loss']].plot()\nhistory_df[['accuracy', 'val_accuracy']].plot()\nhistory_df.to_csv('history.csv', index = False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#plotting the QWK score\nplt.plot(kappa_metrics.val_kappas)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.load_weights('model.h5')\ny_val_pred = model.predict(x_val)\n#clipping the value to range of 0-4, and round it to the nearest integer\ny_val_pred = np.clip(y_val_pred,0,4).astype(int)","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(valid_df['diagnosis'].astype('int'), y_val_pred)\ndf_cm = pd.DataFrame(cnf_matrix, index=labels, columns=labels)\nplt.figure(figsize=(16, 7))\nsns.heatmap(df_cm, annot=True, cmap=\"Blues\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"kappa_val = cohen_kappa_score(\n            valid_df['diagnosis'].astype('int'),\n            y_val_pred, \n            weights='quadratic'\n        )\nprint(kappa_val)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df = pd.read_csv('../input/aptos2019-blindness-detection/test.csv')\nN = test_df.shape[0]\nx_test = np.empty((N, 224, 224, 3), dtype=np.float32)\n\nfor i, image_id in enumerate(tqdm(test_df['id_code'])):\n    x_test[i, :, :, :] = preprocess_image(\n        f'../input/aptos2019-blindness-detection/test_images/{image_id}.png'\n    )\n\ny_test_pred = model.predict(x_test)\n#clipping the value to range of 0-4, and round it to the nearest integer\ny_test_pred = np.clip(y_test_pred,0,4).astype(int)\n\ntest_df['diagnosis'] = y_test_pred\ntest_df.to_csv('submission.csv')","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}