{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"collapsed":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\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 5GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"\nimport os\nimport sys\nimport cv2\nimport shutil\nimport random\nimport warnings\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\nimport multiprocessing as mp\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\nfrom sklearn.metrics import confusion_matrix, cohen_kappa_score\nfrom keras.models import Model\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.layers import Dense, GlobalAveragePooling2D, Input\n\ndef seed_everything(seed=0):\n    random.seed(seed)\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    np.random.seed(seed)\n    tf.random.set_seed(seed)\n\nseed = 0\nseed_everything(seed)\n%matplotlib inline\nsns.set(style=\"whitegrid\")\nwarnings.filterwarnings(\"ignore\")\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.metrics import roc_curve\nfrom sklearn.metrics import auc\nfrom sklearn.metrics import precision_recall_curve\nfrom sklearn.metrics import precision_score\nfrom sklearn.metrics import recall_score\nfrom sklearn.metrics import f1_score\nfrom sklearn.metrics import average_precision_score\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"!pip install -U git+https://github.com/qubvel/efficientnet"},{"metadata":{"trusted":true,"collapsed":true},"cell_type":"code","source":"!pip install -U git+https://github.com/qubvel/efficientnet","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import efficientnet.keras as efn","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"KAGGLE_DIR = '../input/aptos2019-blindness-detection/'\nTRAIN_DF_PATH = KAGGLE_DIR + \"train.csv\"\nTEST_DF_PATH = KAGGLE_DIR + 'test.csv'\nTRAIN_IMG_PATH = KAGGLE_DIR + \"train_images/\"\n\nprint(\"Image IDs and Labels (TRAIN)\")\ntrain_df = pd.read_csv(TRAIN_DF_PATH)\n# Add extension to id_code\ntrain_df['id_code'] = train_df['id_code'] + \".png\"\nprint(f\"Training images: {train_df.shape[0]}\")\ndisplay(train_df.head())\nprint(\"Image IDs (TEST)\")\ntest_df = pd.read_csv(TEST_DF_PATH)\n# Add extension to id_code\ntest_df['id_code'] = test_df['id_code'] + \".png\"\nprint(f\"Testing Images: {test_df.shape[0]}\")\ndisplay(test_df.head())\n\nfig, ax = plt.subplots(1, 5, figsize=(20, 6))\nfor i in range(5):\n    sample = train_df[train_df['diagnosis'] == i].sample(1)\n    image_name = sample['id_code'].item()\n    X = cv2.imread(f\"{TRAIN_IMG_PATH}{image_name}\")\n    X = cv2.cvtColor(X, cv2.COLOR_BGR2RGB)\n    #ax[i].set_title(f\"{sample['diagnosis'].item()}\", \n                     #fontsize=12)\n    ax[i].axis('off')\n    ax[i].imshow(X);","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from efficientnet import *","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"hold_out_set = pd.read_csv('../input/aptos-data-split/hold-out.csv')\nX_train = hold_out_set[hold_out_set['set'] == 'train']\nX_val = hold_out_set[hold_out_set['set'] == 'validation']\ntest = pd.read_csv('../input/aptos2019-blindness-detection/test.csv')\nprint('Number of train samples: ', X_train.shape[0])\nprint('Number of validation samples: ', X_val.shape[0])\nprint('Number of test samples: ', test.shape[0])\n\n# Preprocecss data\nX_train[\"id_code\"] = X_train[\"id_code\"].apply(lambda x: x + \".png\")\nX_val[\"id_code\"] = X_val[\"id_code\"].apply(lambda x: x + \".png\")\ntest[\"id_code\"] = test[\"id_code\"].apply(lambda x: x + \".png\")\ndisplay(X_train.head())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\n# Model parameters\nHEIGHT = 224\nWIDTH = 224\nCHANNELS = 3\nTTA_STEPS = 10\n\nweights_path_list = ['../input/aptos-5fold-224-oldnew/effNetB5_img224_fold1.h5', '../input/aptos-5fold-224-oldnew/effNetB5_img224_fold2.h5',\n                     '../input/aptos-5fold-224-oldnew/effNetB5_img224_fold3.h5', '../input/aptos-5fold-224-oldnew/effNetB5_img224_fold4.h5',\n                     '../input/aptos-5fold-224-oldnew/effNetB5_img224_fold5.h5']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"labels = ['0 - No DR', '1 - Mild', '2 - Moderate', '3 - Severe', '4 - Proliferative DR']\ndef plot_confusion_matrix(train, validation, labels=labels):\n    train_labels, train_preds = train\n    validation_labels, validation_preds = validation\n    fig, (ax1, ax2) = plt.subplots(1, 2, sharex='col', figsize=(24, 7))\n    train_cnf_matrix = confusion_matrix(train_labels, train_preds)\n    validation_cnf_matrix = confusion_matrix(validation_labels, validation_preds)\n\n    train_cnf_matrix_norm = train_cnf_matrix.astype('float') / train_cnf_matrix.sum(axis=1)[:, np.newaxis]\n    validation_cnf_matrix_norm = validation_cnf_matrix.astype('float') / validation_cnf_matrix.sum(axis=1)[:, np.newaxis]\n\n    train_df_cm = pd.DataFrame(train_cnf_matrix_norm, index=labels, columns=labels)\n    validation_df_cm = pd.DataFrame(validation_cnf_matrix_norm, index=labels, columns=labels)\n\n    sns.heatmap(train_df_cm, annot=True, fmt='.2f', cmap=\"Blues\",ax=ax1).set_title('Train')\n    sns.heatmap(validation_df_cm, annot=True, fmt='.2f', cmap=sns.cubehelix_palette(8),ax=ax2).set_title('Validation')\n    plt.show()\n    \ndef evaluate_model(train, validation):\n    train_labels, train_preds = train\n    validation_labels, validation_preds = validation\n    print(\"Train        Cohen Kappa score: %.3f\" % cohen_kappa_score(train_preds, train_labels, weights='quadratic'))\n    print(\"Validation   Cohen Kappa score: %.3f\" % cohen_kappa_score(validation_preds, validation_labels, weights='quadratic'))\n    print(\"Complete set Cohen Kappa score: %.3f\" % cohen_kappa_score(np.append(train_preds, validation_preds), np.append(train_labels, validation_labels), weights='quadratic'))\n\ndef classify(x):\n    if x < 0.5:\n        return 0\n    elif x < 1.5:\n        return 1\n    elif x < 2.5:\n        return 2\n    elif x < 3.5:\n        return 3\n    return 4\n\ndef ensemble_preds(model_list, generator):\n    preds_ensemble = []\n    for model in model_list:\n        generator.reset()\n        preds = model.predict_generator(generator, steps=generator.n)\n        preds_ensemble.append(preds)\n\n    return np.mean(preds_ensemble, axis=0)\n\ndef apply_tta(model, generator, steps=5):\n    step_size = generator.n//generator.batch_size\n    preds_tta = []\n    for i in range(steps):\n        generator.reset()\n        preds = model.predict_generator(generator, steps=step_size)\n        preds_tta.append(preds)\n\n    return np.mean(preds_tta, axis=0)\n\ndef test_ensemble_preds(model_list, generator, steps=5):\n    preds_ensemble = []\n    for model in model_list:\n        preds = apply_tta(model, generator, steps)\n        preds_ensemble.append(preds)\n\n    return np.mean(preds_ensemble, axis=0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"new_data_base_path = '../input/aptos2019-blindness-detection/train_images/'\ntest_base_path = '../input/aptos2019-blindness-detection/test_images/'\ntrain_dest_path = 'base_dir/train_images/'\nvalidation_dest_path = 'base_dir/validation_images/'\ntest_dest_path =  'base_dir/test_images/'\n\n# Making sure directories don't exist\nif os.path.exists(train_dest_path):\n    shutil.rmtree(train_dest_path)\nif os.path.exists(validation_dest_path):\n    shutil.rmtree(validation_dest_path)\nif os.path.exists(test_dest_path):\n    shutil.rmtree(test_dest_path)\n    \n# Creating train, validation and test directories\nos.makedirs(train_dest_path)\nos.makedirs(validation_dest_path)\nos.makedirs(test_dest_path)\n\ndef crop_image(img, tol=7):\n    if img.ndim ==2:\n        mask = img>tol\n        return img[np.ix_(mask.any(1),mask.any(0))]\n    elif img.ndim==3:\n        gray_img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)\n        mask = gray_img>tol\n        check_shape = img[:,:,0][np.ix_(mask.any(1),mask.any(0))].shape[0]\n        if (check_shape == 0): # image is too dark so that we crop out everything,\n            return img # return original image\n        else:\n            img1=img[:,:,0][np.ix_(mask.any(1),mask.any(0))]\n            img2=img[:,:,1][np.ix_(mask.any(1),mask.any(0))]\n            img3=img[:,:,2][np.ix_(mask.any(1),mask.any(0))]\n            img = np.stack([img1,img2,img3],axis=-1)\n            \n        return img\n\ndef circle_crop(img):\n    img = crop_image(img)\n\n    height, width, depth = img.shape\n    largest_side = np.max((height, width))\n    img = cv2.resize(img, (largest_side, largest_side))\n\n    height, width, depth = img.shape\n\n    x = width//2\n    y = height//2\n    r = np.amin((x, y))\n\n    circle_img = np.zeros((height, width), np.uint8)\n    cv2.circle(circle_img, (x, y), int(r), 1, thickness=-1)\n    img = cv2.bitwise_and(img, img, mask=circle_img)\n    img = crop_image(img)\n\n    return img\n        \ndef preprocess_image(image_id, base_path, save_path, HEIGHT=HEIGHT, WIDTH=WIDTH, sigmaX=10):\n    image = cv2.imread(base_path + image_id)\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n    image = circle_crop(image)\n    image = cv2.resize(image, (HEIGHT, WIDTH))\n#     image = cv2.addWeighted(image, 4, cv2.GaussianBlur(image, (0,0), sigmaX), -4 , 128)\n    cv2.imwrite(save_path + image_id, image)\n        \ndef preprocess_data(df, HEIGHT=HEIGHT, WIDTH=WIDTH, sigmaX=10):\n    df = df.reset_index()\n    for i in range(df.shape[0]):\n        item = df.iloc[i]\n        image_id = item['id_code']\n        item_set = item['set']\n        if item_set == 'train':\n            preprocess_image(image_id, new_data_base_path, train_dest_path)\n        if item_set == 'validation':\n            preprocess_image(image_id, new_data_base_path, validation_dest_path)\n        \ndef preprocess_test(df, base_path=test_base_path, save_path=test_dest_path, HEIGHT=HEIGHT, WIDTH=WIDTH, sigmaX=10):\n    df = df.reset_index()\n    for i in range(df.shape[0]):\n        image_id = df.iloc[i]['id_code']\n        preprocess_image(image_id, base_path, save_path)\n\nn_cpu = mp.cpu_count()\ntrain_n_cnt = X_train.shape[0] // n_cpu\nval_n_cnt = X_val.shape[0] // n_cpu\ntest_n_cnt = test.shape[0] // n_cpu\n\n# Pre-procecss old data train set\npool = mp.Pool(n_cpu)\ndfs = [X_train.iloc[train_n_cnt*i:train_n_cnt*(i+1)] for i in range(n_cpu)]\ndfs[-1] = X_train.iloc[train_n_cnt*(n_cpu-1):]\nres = pool.map(preprocess_data, [x_df for x_df in dfs])\npool.close()\n\n# Pre-procecss validation set\npool = mp.Pool(n_cpu)\ndfs = [X_val.iloc[val_n_cnt*i:val_n_cnt*(i+1)] for i in range(n_cpu)]\ndfs[-1] = X_val.iloc[val_n_cnt*(n_cpu-1):] \nres = pool.map(preprocess_data, [x_df for x_df in dfs])\npool.close()\n\n# Pre-procecss test set\npool = mp.Pool(n_cpu)\ndfs = [test.iloc[test_n_cnt*i:test_n_cnt*(i+1)] for i in range(n_cpu)]\ndfs[-1] = test.iloc[test_n_cnt*(n_cpu-1):] \nres = pool.map(preprocess_test, [x_df for x_df in dfs])\npool.close()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\n    fig, ax = plt.subplots(1, 5, figsize=(30, 12))\n    X = cv2.imread(f\"./base_dir/validation_images/4ccfa0b4e96c.png\")\n    a = cv2.imread(f\"./base_dir/validation_images/fda39982a810.png\")\n    b = cv2.imread(f\"./base_dir/validation_images/66a0bf258013.png\")\n    c = cv2.imread(f\"./base_dir/validation_images/0e0003ddd8df.png\")\n    d = cv2.imread(f\"./base_dir/validation_images/c8a3eb9a5b52.png\")\n    X = cv2.cvtColor(X, cv2.COLOR_BGR2RGB)\n    a = cv2.cvtColor(a, cv2.COLOR_BGR2RGB)\n    b = cv2.cvtColor(b, cv2.COLOR_BGR2RGB)\n    c = cv2.cvtColor(c, cv2.COLOR_BGR2RGB)\n    d = cv2.cvtColor(d, cv2.COLOR_BGR2RGB)\n    ax[0].axis('off')\n    ax[1].axis('off')\n    ax[2].axis('off')\n    ax[3].axis('off')\n    ax[4].axis('off')\n    ax[0].imshow(X)\n    ax[1].imshow(a)\n    ax[2].imshow(b)\n    ax[3].imshow(c)\n    ax[4].imshow(d)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.read_csv('../input/aptos2019-blindness-detection/train.csv')\ntest_df = pd.read_csv('../input/aptos2019-blindness-detection/test.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df['diagnosis'].hist()\ntrain_df['diagnosis'].value_counts()","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.axis('off')\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":"def get_histograms(df,columns=4, rows=3):\n    ax, fig=plt.subplots(columns*rows,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        plt.subplot(columns, rows, i+1)\n        img = cv2.imread(f'../input/aptos2019-blindness-detection/train_images/{image_path}.png')\n        plt.hist(img.flatten(),256,[0,256],color='r')\n#         fig.add_subplot(rows, columns, i+1)\n        plt.title(image_id)\n#         plt.axis('off')\n#         plt.imshow(img)\n    \n    plt.tight_layout() ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"get_histograms(train_df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"datagen=ImageDataGenerator(rescale=1./255, \n                           rotation_range=360,\n                           horizontal_flip=True,\n                           vertical_flip=True)\n\ntrain_generator=datagen.flow_from_dataframe(\n                        dataframe=X_train,\n                        directory=train_dest_path,\n                        x_col=\"id_code\",\n                        y_col=\"diagnosis\",\n                        class_mode=\"raw\",\n                        batch_size=1,\n                        shuffle=False,\n                        target_size=(HEIGHT, WIDTH),\n                        seed=seed)\n\nvalid_generator=datagen.flow_from_dataframe(\n                        dataframe=X_val,\n                        directory=validation_dest_path,\n                        x_col=\"id_code\",\n                        y_col=\"diagnosis\",\n                        class_mode=\"raw\",\n                        batch_size=1,\n                        shuffle=False,\n                        target_size=(HEIGHT, WIDTH),\n                        seed=seed)\n\ntest_generator=datagen.flow_from_dataframe(  \n                       dataframe=test,\n                       directory=test_dest_path,\n                       x_col=\"id_code\",\n                       y_col=\"diagnosis\",\n                       batch_size=1,\n                       class_mode=None,\n                       shuffle=False,\n                       target_size=(HEIGHT, WIDTH),\n                       seed=seed)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def create_model(input_shape, weights_path):\n    input_tensor = Input(shape=input_shape)\n    base_model = efn.EfficientNetB5(weights=None, \n                                include_top=False,\n                                input_tensor=input_tensor)\n\n    x = GlobalAveragePooling2D()(base_model.output)\n    final_output = Dense(1, activation='linear', name='final_output')(x)\n    model = Model(input_tensor, final_output)\n    model.load_weights(weights_path)\n    \n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model_list = []\n\nfor weights_path in weights_path_list:\n    model_list.append(create_model(input_shape=(HEIGHT, WIDTH, CHANNELS), weights_path=weights_path))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Train predictions\npreds_ensemble = ensemble_preds(model_list, train_generator)\npreds_ensemble = [classify(x) for x in preds_ensemble]\ntrain_preds = pd.DataFrame({'label':train_generator.labels, 'pred':preds_ensemble})\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"confusion_matrix(train_preds['label'], train_preds['pred'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Validation predictions\npreds_ensemble2 = ensemble_preds(model_list, valid_generator)\npreds_ensemble2 = [classify(x) for x in preds_ensemble2]\nvalidation_preds = pd.DataFrame({'label':valid_generator.labels, 'pred':preds_ensemble2})","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"confusion_matrix(validation_preds['label'], validation_preds['pred'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_confusion_matrix((train_preds['label'], train_preds['pred']), (validation_preds['label'], validation_preds['pred']))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"evaluate_model((train_preds['label'], train_preds['pred']), (validation_preds['label'], validation_preds['pred']))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"preds = test_ensemble_preds(model_list, test_generator, TTA_STEPS)\npredictions = [classify(x) for x in preds]\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"confusion_matrix(predictions['label'], predictions['pred'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"results = pd.DataFrame({'id_code':test['id_code'], 'diagnosis':predictions})\nresults['id_code'] = results['id_code'].map(lambda x: str(x)[:-4])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Cleaning created directories\nif os.path.exists(train_dest_path):\n    shutil.rmtree(train_dest_path)\nif os.path.exists(validation_dest_path):\n    shutil.rmtree(validation_dest_path)\nif os.path.exists(test_dest_path):\n    shutil.rmtree(test_dest_path)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig = plt.subplots(sharex='col', figsize=(24, 8.7))\nsns.countplot(x=\"diagnosis\", data=results, palette=\"GnBu_d\").set_title('Test')\nsns.despine()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nresults.to_csv('submission.csv', index=False)\ndisplay(results.head())","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}