{"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":"## Import packeges","metadata":{}},{"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","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","execution":{"iopub.status.busy":"2023-11-07T05:53:28.203043Z","iopub.execute_input":"2023-11-07T05:53:28.203324Z","iopub.status.idle":"2023-11-07T05:53:30.650710Z","shell.execute_reply.started":"2023-11-07T05:53:28.203281Z","shell.execute_reply":"2023-11-07T05:53:30.649802Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Check dataset","metadata":{}},{"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, '/kaggle/input/dataset/1000 รูป 2 NidexAFC210')\nTRAIN_LABEL_PATH = os.path.join(DATA_PATH, 'train.csv')\nTEST_LABEL_PATH = os.path.join(DATA_PATH, '/kaggle/input/testdataset/test_dataset.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)))\n\nplt.figure(figsize=(12, 6))\nsns.countplot(df_train[\"diagnosis\"])\nplt.title(\"Number of data per each diagnosis\")\nplt.show()","metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","execution":{"iopub.status.busy":"2023-11-07T05:53:30.654286Z","iopub.execute_input":"2023-11-07T05:53:30.654801Z","iopub.status.idle":"2023-11-07T05:53:31.462962Z","shell.execute_reply.started":"2023-11-07T05:53:30.654564Z","shell.execute_reply":"2023-11-07T05:53:31.462172Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Split training set","metadata":{}},{"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] != 'jpg':\n    for index in range(len(df_test['id_code'])):\n        df_test['id_code'][index] = df_test['id_code'][index] + '.jpg'\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)","metadata":{"execution":{"iopub.status.busy":"2023-11-07T05:53:31.464435Z","iopub.execute_input":"2023-11-07T05:53:31.464977Z","iopub.status.idle":"2023-11-07T05:53:31.997818Z","shell.execute_reply.started":"2023-11-07T05:53:31.464922Z","shell.execute_reply":"2023-11-07T05:53:31.997099Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Image generator","metadata":{}},{"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)","metadata":{"execution":{"iopub.status.busy":"2023-11-07T05:53:31.998940Z","iopub.execute_input":"2023-11-07T05:53:31.999168Z","iopub.status.idle":"2023-11-07T05:53:40.090127Z","shell.execute_reply.started":"2023-11-07T05:53:31.999129Z","shell.execute_reply":"2023-11-07T05:53:40.089220Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Pre-trained model preparation","metadata":{}},{"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","metadata":{"execution":{"iopub.status.busy":"2023-11-07T05:53:40.093012Z","iopub.execute_input":"2023-11-07T05:53:40.093252Z","iopub.status.idle":"2023-11-07T05:53:40.101525Z","shell.execute_reply.started":"2023-11-07T05:53:40.093211Z","shell.execute_reply":"2023-11-07T05:53:40.100655Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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)\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2023-11-07T05:53:40.103165Z","iopub.execute_input":"2023-11-07T05:53:40.103469Z","iopub.status.idle":"2023-11-07T05:53:58.176984Z","shell.execute_reply.started":"2023-11-07T05:53:40.103413Z","shell.execute_reply":"2023-11-07T05:53:58.174281Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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)","metadata":{"execution":{"iopub.status.busy":"2023-11-07T05:53:58.178436Z","iopub.execute_input":"2023-11-07T05:53:58.178677Z","iopub.status.idle":"2023-11-07T08:24:47.229936Z","shell.execute_reply.started":"2023-11-07T05:53:58.178635Z","shell.execute_reply":"2023-11-07T08:24:47.227905Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## History visualization","metadata":{}},{"cell_type":"markdown","source":"- Accuracy","metadata":{}},{"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()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2023-11-07T08:24:47.231359Z","iopub.execute_input":"2023-11-07T08:24:47.231657Z","iopub.status.idle":"2023-11-07T08:24:47.528933Z","shell.execute_reply.started":"2023-11-07T08:24:47.231600Z","shell.execute_reply":"2023-11-07T08:24:47.527707Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"- Loss","metadata":{}},{"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()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2023-11-07T08:24:47.531041Z","iopub.execute_input":"2023-11-07T08:24:47.531461Z","iopub.status.idle":"2023-11-07T08:24:47.840812Z","shell.execute_reply.started":"2023-11-07T08:24:47.531396Z","shell.execute_reply":"2023-11-07T08:24:47.839616Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Prediction","metadata":{}},{"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)","metadata":{"execution":{"iopub.status.busy":"2023-11-07T08:24:47.842252Z","iopub.execute_input":"2023-11-07T08:24:47.842705Z","iopub.status.idle":"2023-11-07T08:24:49.698950Z","shell.execute_reply.started":"2023-11-07T08:24:47.842512Z","shell.execute_reply":"2023-11-07T08:24:49.698230Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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)","metadata":{"execution":{"iopub.status.busy":"2023-11-07T08:24:49.702052Z","iopub.execute_input":"2023-11-07T08:24:49.702441Z","iopub.status.idle":"2023-11-07T08:32:44.147915Z","shell.execute_reply.started":"2023-11-07T08:24:49.702368Z","shell.execute_reply":"2023-11-07T08:32:44.146882Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds_mean = np.mean(preds_tta, axis=0)\npredicted_class_indices = np.argmax(preds_mean, axis=1)","metadata":{"execution":{"iopub.status.busy":"2023-11-07T08:32:44.149533Z","iopub.execute_input":"2023-11-07T08:32:44.149850Z","iopub.status.idle":"2023-11-07T08:32:44.158858Z","shell.execute_reply.started":"2023-11-07T08:32:44.149786Z","shell.execute_reply":"2023-11-07T08:32:44.156252Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\n\n# อ่านไฟล์ test_dataset.csv ที่มีข้อมูลตัวอย่าง\ntest_data = pd.read_csv('/kaggle/input/testdataset/test_dataset.csv')\n\ntest_data['diagnosis'] = 0\n\n# บันทึก DataFrame ใหม่เป็นไฟล์ CSV\ntest_data.to_csv('new_submission.csv', index=False)\n","metadata":{"execution":{"iopub.status.busy":"2023-11-07T08:49:25.745726Z","iopub.execute_input":"2023-11-07T08:49:25.746076Z","iopub.status.idle":"2023-11-07T08:49:25.794321Z","shell.execute_reply.started":"2023-11-07T08:49:25.746027Z","shell.execute_reply":"2023-11-07T08:49:25.793631Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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('/kaggle/working/new_submission.csv'))\nsubmission['diagnosis'] = predictions\nsubmission.to_csv(\"submission.csv\", index=False)\nsubmission.head()","metadata":{"execution":{"iopub.status.busy":"2023-11-07T08:50:50.857159Z","iopub.execute_input":"2023-11-07T08:50:50.857465Z","iopub.status.idle":"2023-11-07T08:50:50.885407Z","shell.execute_reply.started":"2023-11-07T08:50:50.857421Z","shell.execute_reply":"2023-11-07T08:50:50.884433Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Predictions class distribution","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(12, 6))\nsns.countplot(submission[\"diagnosis\"])\nplt.title(\"Number of data per each diagnosis\")\nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2023-11-07T08:51:04.639443Z","iopub.execute_input":"2023-11-07T08:51:04.639943Z","iopub.status.idle":"2023-11-07T08:51:04.928008Z","shell.execute_reply.started":"2023-11-07T08:51:04.639734Z","shell.execute_reply":"2023-11-07T08:51:04.926939Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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))","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2023-11-07T08:51:14.256749Z","iopub.execute_input":"2023-11-07T08:51:14.257065Z","iopub.status.idle":"2023-11-07T08:51:14.279372Z","shell.execute_reply.started":"2023-11-07T08:51:14.257020Z","shell.execute_reply":"2023-11-07T08:51:14.278394Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}