{"cells":[{"metadata":{},"cell_type":"markdown","source":"## Import packeges"},{"metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","trusted":true},"cell_type":"code","source":"import os\nimport sys\n\nimport numpy as np\nimport pandas as pd\nimport cv2\nimport seaborn as sns\n\nfrom math import ceil\nfrom tqdm import tqdm\n\nfrom PIL import Image\nfrom matplotlib import pyplot as plt\n\nfrom sklearn.model_selection import train_test_split\n\nfrom keras.applications.inception_v3 import InceptionV3, preprocess_input\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.models import Sequential, Model\nfrom keras.layers import Input, Dense, GlobalAveragePooling2D, Dropout\nfrom keras.optimizers import RMSprop, Adam, SGD\nfrom keras.callbacks import ModelCheckpoint, ReduceLROnPlateau, EarlyStopping","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Check dataset"},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"DATA_PATH = '../input/aptos2019-blindness-detection'\n\nTRAIN_IMG_PATH = os.path.join(DATA_PATH, 'train_images')\nTEST_IMG_PATH = os.path.join(DATA_PATH, 'test_images')\nTRAIN_LABEL_PATH = os.path.join(DATA_PATH, 'train.csv')\nTEST_LABEL_PATH = os.path.join(DATA_PATH, 'test.csv')\n\ndf_train = pd.read_csv(TRAIN_LABEL_PATH)\ndf_test = pd.read_csv(TEST_LABEL_PATH)\n\nprint('num of train images ', len(os.listdir(TRAIN_IMG_PATH)))\nprint('num of test images  ', len(os.listdir(TEST_IMG_PATH)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"plt.figure(figsize=(12, 6))\nsns.countplot(df_train[\"diagnosis\"])\nplt.title(\"Number of data per each diagnosis\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Split training set"},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train['diagnosis'] = df_train['diagnosis'].astype('str')\ndf_train = df_train[['id_code', 'diagnosis']]\nif df_train['id_code'][0].split('.')[-1] != 'png':\n    for index in range(len(df_train['id_code'])):\n        df_train['id_code'][index] = df_train['id_code'][index] + '.png'\n        \ndf_test = df_test[['id_code']]\nif df_test['id_code'][0].split('.')[-1] != 'png':\n    for index in range(len(df_test['id_code'])):\n        df_test['id_code'][index] = df_test['id_code'][index] + '.png'\n\ntrain_data = np.arange(df_train.shape[0])\ntrain_idx, val_idx = train_test_split(train_data, train_size=0.8, random_state=2019)\n\nX_train = df_train.iloc[train_idx, :]\nX_val = df_train.iloc[val_idx, :]\nX_test = df_test\n\nprint(X_train.shape)\nprint(X_val.shape)\nprint(X_test.shape)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Image generator"},{"metadata":{"trusted":true},"cell_type":"code","source":"num_classes = 5\nimg_size = (299, 299, 3)\nnb_train_samples = len(X_train)\nnb_validation_samples = len(X_val)\nnb_test_samples = len(X_test)\nepochs = 50\nbatch_size = 32\n\ntrain_datagen = ImageDataGenerator(\n    horizontal_flip=True,\n    vertical_flip=True,\n    width_shift_range=0.1,\n    height_shift_range=0.1,\n    brightness_range=[0.5, 1.5],\n    rescale=1./255\n)\nval_datagen = ImageDataGenerator(\n    rescale=1./255\n)\n# Apply TTA\ntest_datagen = ImageDataGenerator(\n    horizontal_flip=True,\n    vertical_flip=True,\n    width_shift_range=0.1,\n    height_shift_range=0.1,\n    brightness_range=[0.5, 1.5],\n    rescale=1./255\n)\n\ntrain_generator = train_datagen.flow_from_dataframe(\n    dataframe=X_train, \n    directory=TRAIN_IMG_PATH,\n    x_col='id_code',\n    y_col='diagnosis',\n    target_size=img_size[:2],\n    color_mode='rgb',\n    class_mode='categorical',\n    batch_size=batch_size,\n    seed=2019\n)\nvalidation_generator = val_datagen.flow_from_dataframe(\n    dataframe=X_val, \n    directory=TRAIN_IMG_PATH,\n    x_col='id_code',\n    y_col='diagnosis',\n    target_size=img_size[:2],\n    color_mode='rgb',\n    class_mode='categorical',\n    batch_size=batch_size,\n    shuffle=False,\n    seed=2019\n)\ntest_generator = test_datagen.flow_from_dataframe(\n    dataframe=X_test,\n    directory=TEST_IMG_PATH,\n    x_col='id_code',\n    y_col=None,\n    target_size= img_size[:2],\n    color_mode='rgb',\n    class_mode=None,\n    batch_size=batch_size,\n    shuffle=False,\n    seed=2019\n)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Pre-trained model preparation"},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_model(file_path, input_shape, num_classes):\n    input_tensor = Input(shape=input_shape)\n    base_model = InceptionV3(include_top=False,\n                             weights=None,\n                             input_tensor=input_tensor)\n    base_model.load_weights(filepath=file_path)\n    x = base_model.output\n    x = GlobalAveragePooling2D()(x)\n    x = Dense(1024, activation='relu')(x)\n    x = Dropout(0.25)(x)\n    output_tensor = Dense(num_classes, activation='softmax')(x)\n    \n    model = Model(inputs=input_tensor, outputs=output_tensor)\n    \n#     optimizer = Adam(lr=1e-4)\n    optimizer = RMSprop(lr=1e-4)\n    model.compile(\n        loss='categorical_crossentropy',\n        optimizer=optimizer,\n        metrics=['accuracy']\n    )\n    \n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model_path = '../input/inceptionv3/'\nweight_file = 'inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5'\nmodel = get_model(\n    file_path=os.path.join(model_path, weight_file),\n    input_shape=img_size,\n    num_classes=num_classes\n)\n# model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"LOG_DIR = './logs'\nif not os.path.isdir(LOG_DIR):\n    os.mkdir(LOG_DIR)\nelse:\n    pass\nCKPT_PATH = LOG_DIR + '/checkpoint-{epoch:02d}-{val_loss:.4f}.hdf5'\n\ncheckPoint = ModelCheckpoint(\n    filepath=CKPT_PATH,\n    monitor='val_loss',\n    verbose=1,\n    save_best_only=True,\n    mode='min'\n)\nreduceLROnPlateau = ReduceLROnPlateau(\n    monitor='val_loss',\n    factor=0.1,\n    patience=5,\n    min_lr=0.000001,\n    verbose=1,\n    mode='min'\n)\nearlyStopping = EarlyStopping(\n    monitor='val_loss',\n    patience=15,\n    verbose=1,\n    mode='min'\n)\n\nhistory = model.fit_generator(\n    train_generator,\n    steps_per_epoch=ceil(nb_train_samples/batch_size),\n    epochs=epochs,\n    validation_data=validation_generator,\n    validation_steps=ceil(nb_validation_samples/batch_size),\n    callbacks=[checkPoint, reduceLROnPlateau, earlyStopping],\n    verbose=2  # If occur error that 'Timeout waiting for IOPub output', set verbose to 0.\n)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## History visualization"},{"metadata":{},"cell_type":"markdown","source":"- Accuracy"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"acc = history.history['acc']\nval_acc = history.history['val_acc']\n \nplt.plot(acc)\nplt.plot(val_acc)\nplt.ylabel('Accuracy')\nplt.xlabel('Epoch')\nplt.legend(['Train', 'Val'], loc='upper left')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"- Loss"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"loss = history.history['loss']\nval_loss = history.history['val_loss']\n\nplt.plot(loss)\nplt.plot(val_loss)\nplt.ylabel('Loss')\nplt.xlabel('Epoch')\nplt.legend(['Train', 'Val'], loc='upper left')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Prediction"},{"metadata":{"trusted":true},"cell_type":"code","source":"log_dir_list = os.listdir(LOG_DIR)\nckpt_list = []\nfor file in log_dir_list:\n    if file.split('-')[0] == 'checkpoint':\n        ckpt_list.append(file)\n\nloss_list = []\nfor file in ckpt_list:\n    file = file.split('-')[2]\n    file = file[:-3]    # Remove extension name\n    loss_list.append(file)\n    \n# The model with the lowest validation loss\nloss = ckpt_list[loss_list.index(min(loss_list))]\nbest_model = LOG_DIR + '/' + loss\nmodel.load_weights(best_model)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Apply TTA\npreds_tta = []\ntta_steps = 10\nfor i in tqdm(range(tta_steps)):\n    test_generator.reset()\n    preds = model.predict_generator(\n        generator=test_generator,\n        steps =ceil(nb_test_samples/batch_size)\n    )\n    preds_tta.append(preds)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"preds_mean = np.mean(preds_tta, axis=0)\npredicted_class_indices = np.argmax(preds_mean, axis=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"labels = (train_generator.class_indices)\nlabels = dict((v,k) for k,v in labels.items())\npredictions = [labels[k] for k in predicted_class_indices]\n\nsubmission = pd.read_csv(os.path.join(DATA_PATH, 'sample_submission.csv'))\nsubmission['diagnosis'] = predictions\nsubmission.to_csv(\"submission.csv\", index=False)\nsubmission.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Predictions class distribution"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"plt.figure(figsize=(12, 6))\nsns.countplot(submission[\"diagnosis\"])\nplt.title(\"Number of data per each diagnosis\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"diagnosis_0 = 0\ndiagnosis_1 = 1\ndiagnosis_2 = 2\ndiagnosis_3 = 3\ndiagnosis_4 = 4\nfor idx in range(len(submission['diagnosis'])):\n    if submission['diagnosis'][idx] == '0':\n        diagnosis_0 += 1\n    elif submission['diagnosis'][idx] == '1':\n        diagnosis_1 += 1\n    elif submission['diagnosis'][idx] == '2':\n        diagnosis_2 += 1\n    elif submission['diagnosis'][idx] == '3':\n        diagnosis_3 += 1\n    elif submission['diagnosis'][idx] == '4':\n        diagnosis_4 += 1\nprint(\"  0 - No DR              {}\".format(diagnosis_0))\nprint(\"  1 - Mild               {}\".format(diagnosis_1))\nprint(\"  2 - Moderate           {}\".format(diagnosis_2))\nprint(\"  3 - Severe             {}\".format(diagnosis_3))\nprint(\"  4 - Proliferative DR   {}\".format(diagnosis_4))","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.6.6"}},"nbformat":4,"nbformat_minor":1}