{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"id":"d5MiaWfC4iix","colab_type":"code","colab":{}},"cell_type":"code","source":"import os\nimport math\n\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\n\n\n# set to false in submission notebook\nTRAINING = False","execution_count":0,"outputs":[]},{"metadata":{"id":"1v8i6AKB4ijY","colab_type":"text"},"cell_type":"markdown","source":"## Load data"},{"metadata":{"id":"2Wl6BZaQ4vrV","colab_type":"code","outputId":"31cb7d8e-ac62-48ff-c566-c43c577f4a29","colab":{"base_uri":"https://localhost:8080/","height":228},"trusted":false},"cell_type":"code","source":"# !pip install kaggle","execution_count":null,"outputs":[]},{"metadata":{"id":"CscU_Onj4syS","colab_type":"code","outputId":"6d39cc66-1377-4737-b7d4-a5de07e93228","colab":{"base_uri":"https://localhost:8080/","height":34},"trusted":false},"cell_type":"code","source":"# download data from Kaggle\n\n# from googleapiclient.discovery import build\n# import io, os\n# from googleapiclient.http import MediaIoBaseDownload\n# from google.colab import auth\n\n# auth.authenticate_user()\n# drive_service = build('drive', 'v3')\n# results = drive_service.files().list(\n#         q=\"name = 'kaggle.json'\", fields=\"files(id)\").execute()\n# kaggle_api_key = results.get('files', [])\n# filename = \"/content/.kaggle/kaggle.json\"\n# os.makedirs(os.path.dirname(filename), exist_ok=True)\n# request = drive_service.files().get_media(fileId=kaggle_api_key[0]['id'])\n# fh = io.FileIO(filename, 'wb')\n# downloader = MediaIoBaseDownload(fh, request)\n# done = False\n# while done is False:\n#     status, done = downloader.next_chunk()\n#     print(\"Download %d%%.\" % int(status.progress() * 100))\n# os.chmod(filename, 600)","execution_count":null,"outputs":[]},{"metadata":{"id":"ymywIB-g94MD","colab_type":"code","colab":{},"trusted":false},"cell_type":"code","source":"# !mkdir ~/.kaggle\n# !cp /content/.kaggle/kaggle.json ~/.kaggle/kaggle.json","execution_count":0,"outputs":[]},{"metadata":{"id":"QsjYAt2_6Vj4","colab_type":"code","outputId":"9265a5d3-07fe-4ad2-ce6d-679cf5a7fbf0","colab":{"base_uri":"https://localhost:8080/","height":278},"trusted":false},"cell_type":"code","source":"# !kaggle competitions download -c aptos2019-blindness-detection","execution_count":null,"outputs":[]},{"metadata":{"id":"skPMjsig8eeD","colab_type":"code","colab":{},"trusted":false},"cell_type":"code","source":"# !unzip -q train_images.zip -d train_images\n# !unzip -q test_images.zip -d test_images","execution_count":0,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!ls ../input/aptos-2019-densenet121-weights","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true,"id":"kS2gjPDw4ijc","colab_type":"code","outputId":"343dc953-22c2-482b-fdf6-caef37153566","colab":{"base_uri":"https://localhost:8080/","height":52}},"cell_type":"code","source":"# load CSV files\n\ntrain = pd.read_csv('../input/aptos2019-blindness-detection/train.csv')\ntest = pd.read_csv('../input/aptos2019-blindness-detection/test.csv')\n\nprint('Number of train samples: ', train.shape[0])\nprint('Number of test samples: ', test.shape[0])","execution_count":null,"outputs":[]},{"metadata":{"id":"ehfkwcrP4ijv","colab_type":"text"},"cell_type":"markdown","source":"## Preprocessing"},{"metadata":{"trusted":true,"id":"v5d56qne4ij1","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":208},"outputId":"170e6cf1-b4fd-4a4f-d174-cb5352dff911"},"cell_type":"code","source":"# set id codes to full image name (add .png)\ntrain['id_code'] = train['id_code'].apply(lambda x: str(x) + \".png\")\ntest['id_code'] = test['id_code'].apply(lambda x: str(x) + \".png\")\ntrain['diagnosis'] = train['diagnosis'].astype(str)\n\n# add label columns\nlabel_cols = ['lbl_0', 'lbl_1', 'lbl_2', 'lbl_3', 'lbl_4']\nlabel_mat = np.zeros((train.shape[0], len(label_cols)), dtype=np.int32)\n\nfor i in range(train.shape[0]):\n    for j in range(int(train['diagnosis'][i]) + 1):\n        label_mat[i, j] = 1\n\ntrain = pd.concat([train, pd.DataFrame(label_mat, columns=label_cols)], axis=1)\n\nprint(train.head(10))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"id":"EbH3YLSs4ikB","colab_type":"code","colab":{}},"cell_type":"code","source":"import cv2\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n\nIMG_SIZE = 224\nNB_CHANNELS = 3\nNB_CLASSES = 5     # 0, 1, 2, 3, 4\nBATCH_SIZE = 32\nTEST_BATCH_SIZE = 1","execution_count":0,"outputs":[]},{"metadata":{"trusted":true,"id":"YV1jy8lq4ikN","colab_type":"code","colab":{}},"cell_type":"code","source":"\"\"\"\ncrops black parts around the image (intensity is <= tol)\n\"\"\"\ndef crop_image(img, tol=10):\n    \n    # for one channel\n    def crop_image_1(img):\n        mask = img > tol\n        return img[np.ix_(mask.any(1), mask.any(0))]\n    \n    if img.ndim == 2:\n        return crop_image_1(img)\n    \n    elif img.ndim == 3:\n        try:\n            img_cpy = img.copy()\n            h, w, _ = img.shape\n            img1 = cv2.resize(crop_image_1(img[:, :, 0]), (w, h))\n            img2 = cv2.resize(crop_image_1(img[:, :, 1]), (w, h))\n            img3 = cv2.resize(crop_image_1(img[:, :, 2]), (w, h))\n\n            img[:,:,0] = img1\n            img[:,:,1] = img2\n            img[:,:,2] = img3\n            \n        except:\n            return img_cpy\n        \n        \n        \"\"\"\n        # add edges to img\n        \n        sobelx = cv2.Sobel(img,cv2.CV_32F,1,0,ksize=5)\n        sobely = cv2.Sobel(img,cv2.CV_32F,0,1,ksize=5)\n        sobelx = cv2.cvtColor(sobelx, cv2.COLOR_RGB2GRAY)\n        sobely = cv2.cvtColor(sobely, cv2.COLOR_RGB2GRAY)\n        \n        img4 = sobelx ** 2 + sobely ** 2\n        \n        img4 -= np.min(img4)\n        img4 = img4 / np.max(img4)\n        \n        img4 *= 255.\n        img4.astype(np.uint8)\n        \"\"\"\n        \n        return img\n\n\n\"\"\"\ncrops black parts and enhances image (Ben Graham's method)\n\"\"\"\ndef preprocess_image(img):\n    \n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    img = crop_image(img)\n    img = cv2.resize(img, (IMG_SIZE, IMG_SIZE))\n    img = cv2.addWeighted(img, 4, cv2.GaussianBlur(img, (0, 0), IMG_SIZE/10), -4, 128)\n    \n    return img","execution_count":0,"outputs":[]},{"metadata":{"trusted":true,"id":"dHTtVL2Q4ika","colab_type":"code","outputId":"c833b330-b3d0-4bc3-f49e-d01692ad70f5","colab":{"base_uri":"https://localhost:8080/","height":899}},"cell_type":"code","source":"# looking at raw/processed image\n\n# GRID_ROWS = 6\n# GRID_COLS = 6\n\n# rand_idx = np.random.randint(0, len(train['id_code']), size=(GRID_ROWS*GRID_COLS//2))\n\n# fig, ax = plt.subplots(GRID_ROWS, GRID_COLS, figsize=(GRID_COLS * 2.5, GRID_ROWS * 2.5))\n\n# for i in range(GRID_ROWS):\n#     for j in range(GRID_COLS // 2):\n#         test_img = cv2.imread(f\"train_images/{train['id_code'][rand_idx[i * GRID_COLS // 2 + j]]}\")\n        \n#         ax[i, j * 2].imshow(test_img)\n#         ax[i, j * 2].axis(\"off\")\n        \n#         test_img = preprocess_image(test_img)\n        \n#         ax[i, j * 2 + 1].set_title(f\"diagnosis: {train['diagnosis'][rand_idx[i * GRID_COLS // 2 + j]]}\")\n#         ax[i, j * 2 + 1].imshow(test_img)\n#         ax[i, j * 2 + 1].axis(\"off\")","execution_count":null,"outputs":[]},{"metadata":{"id":"N9tGiooR4ik0","colab_type":"text"},"cell_type":"markdown","source":"## Data generators"},{"metadata":{"trusted":true,"id":"Cclzzecv4ik7","colab_type":"code","outputId":"37cae160-bf52-4174-c5ef-d1e176f959ab","colab":{"base_uri":"https://localhost:8080/","height":69}},"cell_type":"code","source":"train_datagen = ImageDataGenerator(rescale=1./255,\n                                   validation_split=0.2,\n                                   horizontal_flip=True,\n                                   preprocessing_function=preprocess_image)\n\ntrain_gen = train_datagen.flow_from_dataframe(\n    dataframe=train,\n    directory=\"../input/aptos2019-blindness-detection/train_images/\",\n    x_col='id_code',\n#     y_col='diagnosis',\n    y_col=label_cols,\n    batch_size=BATCH_SIZE,\n#     class_mode=\"categorical\",\n    class_mode=\"other\",\n    target_size=(IMG_SIZE, IMG_SIZE),\n    subset=\"training\",\n    shuffle=True\n)\n\nval_gen = train_datagen.flow_from_dataframe(\n    dataframe=train,\n    directory=\"../input/aptos2019-blindness-detection/train_images/\",\n    x_col='id_code',\n#     y_col='diagnosis',\n    y_col=label_cols,\n    batch_size=BATCH_SIZE,\n#     class_mode=\"categorical\",\n    class_mode=\"other\",\n    target_size=(IMG_SIZE, IMG_SIZE),\n    subset=\"validation\",\n    shuffle=True\n)\n\n\ntest_datagen = ImageDataGenerator(rescale=1./255,\n                                  preprocessing_function=preprocess_image)\n\ntest_gen = test_datagen.flow_from_dataframe(  \n    dataframe=test,\n    directory=\"../input/aptos2019-blindness-detection/test_images/\",\n    x_col='id_code',\n    batch_size=TEST_BATCH_SIZE,\n    class_mode=None,\n    target_size=(IMG_SIZE, IMG_SIZE),\n    shuffle=False,\n)","execution_count":null,"outputs":[]},{"metadata":{"id":"yluYOC194ilQ","colab_type":"text"},"cell_type":"markdown","source":"## Models"},{"metadata":{"trusted":true,"id":"j1_Mosti4ilY","colab_type":"code","colab":{}},"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.layers import (Input,\n                                            GlobalAveragePooling2D,\n                                            Dense,\n                                            Dropout,\n                                            BatchNormalization,\n                                            Conv2D,\n                                            MaxPooling2D)\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.callbacks import (CSVLogger,\n                                        ModelCheckpoint,\n                                        EarlyStopping)\n# from tensorflow.keras.metrics import Metric\nfrom tensorflow.keras.applications.resnet50 import ResNet50\nfrom tensorflow.keras.applications.densenet import DenseNet121\n\nfrom sklearn.metrics import cohen_kappa_score\n\n\nMODEL_NAME = 'densenet121'\n\nNB_WARMUP_EPOCHS = 2\nNB_EPOCHS = 30\nINITIAL_LR = 1e-3\n\n\nweights_path_template = os.path.join(\"../input/aptos-2019-densenet121-weights/\", \"{}_weights.hdf5\")\nlog_path_template     = os.path.join(\"logs/\", \"{}_training_log.csv\")","execution_count":0,"outputs":[]},{"metadata":{"trusted":true,"id":"7Ss3B2Rd4ilk","colab_type":"code","colab":{}},"cell_type":"code","source":"# for creating weights dir\n!mkdir -p weights\n!mkdir -p logs","execution_count":0,"outputs":[]},{"metadata":{"id":"Czgp6FvkreMR","colab_type":"code","colab":{},"trusted":false},"cell_type":"code","source":"# # check tf version\n# print(\"tf version:\", tf.VERSION)\n\n# # check GPU\n# device_name = tf.test.gpu_device_name()\n# if \"GPU\" not in device_name:\n#     print(\"GPU device not found\")\n# else:\n#     print('Found GPU at: {}'.format(device_name))","execution_count":0,"outputs":[]},{"metadata":{"id":"iZ63UUJFI5Wh","colab_type":"text"},"cell_type":"markdown","source":"### ResNet50-based model"},{"metadata":{"trusted":true,"id":"HmjDELPX4ily","colab_type":"code","colab":{}},"cell_type":"code","source":"\"\"\"\nResNet50 based model\n\"\"\"\ndef get_resnet50(input_shape, nb_out):\n    inputs = Input(shape=input_shape)\n\n    base_model = ResNet50(weights='imagenet', include_top=False, input_tensor=inputs)\n\n    x = GlobalAveragePooling2D()(base_model.output)\n    x = Dropout(0.5)(x)\n\n    x = Dense(2048, activation='relu')(x)\n    x = Dropout(0.5)(x)\n\n    x = Dense(1024, activation='relu')(x)\n    x = Dropout(0.5)(x)\n\n    output = Dense(nb_out, activation='softmax', name='final_output')(x)\n\n    model = Model(inputs, output)\n\n    return model","execution_count":0,"outputs":[]},{"metadata":{"id":"MIXjULnvN2id","colab_type":"text"},"cell_type":"markdown","source":"### DenseNet121-based model"},{"metadata":{"id":"R98sR7uxN8JQ","colab_type":"code","colab":{},"trusted":false},"cell_type":"code","source":"def get_densenet121(input_shape, nb_out):\n    inputs = Input(shape=input_shape)\n\n    base_model = DenseNet121(weights=None, include_top=False, input_tensor=inputs)\n\n    x = GlobalAveragePooling2D()(base_model.output)\n    x = Dropout(0.5)(x)\n\n    x = Dense(1024, activation='relu')(x)\n\n    output = Dense(nb_out, activation='sigmoid')(x)\n\n    model = Model(inputs, output)\n\n    return model","execution_count":0,"outputs":[]},{"metadata":{"id":"o7wC87MVI96x","colab_type":"text"},"cell_type":"markdown","source":"### Simple CNN"},{"metadata":{"id":"FqXHel9X9F8m","colab_type":"code","colab":{},"trusted":false},"cell_type":"code","source":"\"\"\"\nsimple CNN (conv1)\n\"\"\"\ndef get_conv1(input_shape, nb_out):\n    inputs = Input(shape=input_shape)\n\n    x = Conv2D(64, (7, 7), activation='relu')(inputs)\n    x = MaxPooling2D((2, 2))(x)\n    x = BatchNormalization()(x)\n    \n    x = Conv2D(64, (7, 7), activation='relu')(x)\n    x = MaxPooling2D((2, 2))(x)\n    x = BatchNormalization()(x)\n    \n    x = Conv2D(128, (5, 5), activation='relu')(x)\n    x = MaxPooling2D((2, 2))(x)\n    x = BatchNormalization()(x)\n    \n    x = Conv2D(256, (3, 3), activation='relu')(x)\n    x = MaxPooling2D((2, 2))(x)\n    x = BatchNormalization()(x)\n    \n    x = Conv2D(512, (3, 3), activation='relu')(x)\n    x = MaxPooling2D((2, 2))(x)\n    x = BatchNormalization()(x)\n    \n    x = GlobalAveragePooling2D()(x)\n    x = Dropout(0.5)(x)\n    \n    x = Dense(2048, activation='relu')(x)\n    x = Dropout(0.5)(x)\n    \n    x = Dense(1024, activation='relu')(x)\n    x = Dropout(0.5)(x)\n\n    output = Dense(nb_out, activation='softmax', name='final_output')(x)\n\n    model = Model(inputs, output)\n\n    return model","execution_count":0,"outputs":[]},{"metadata":{"id":"1lirPi-R3Op-","colab_type":"text"},"cell_type":"markdown","source":"### Simple CNN v2"},{"metadata":{"id":"SG7MT6TR3N10","colab_type":"code","colab":{},"trusted":false},"cell_type":"code","source":"\"\"\"\nsimple CNN v2 (conv2)\n\"\"\"\ndef get_conv2(input_shape, nb_out):\n    inputs = Input(shape=input_shape)\n\n    x = Conv2D(32, (7, 7), activation='relu')(inputs)\n    x = MaxPooling2D((2, 2))(x)\n    x = BatchNormalization()(x)\n    \n    x = Conv2D(64, (5, 5), activation='relu')(x)\n    x = MaxPooling2D((2, 2))(x)\n    x = BatchNormalization()(x)\n    \n    x = Conv2D(128, (3, 3), activation='relu')(x)\n    x = MaxPooling2D((2, 2))(x)\n    x = BatchNormalization()(x)\n    \n    x = GlobalAveragePooling2D()(x)\n    x = Dropout(0.5)(x)\n\n    x = Dense(1024, activation='relu')(x)\n    x = Dropout(0.5)(x)\n\n    output = Dense(nb_out, activation='softmax')(x)\n\n    model = Model(inputs, output)\n\n    return model","execution_count":0,"outputs":[]},{"metadata":{"id":"KO2ypaEsI_6Z","colab_type":"text"},"cell_type":"markdown","source":"### Generic"},{"metadata":{"id":"XrIf7qHd9D0W","colab_type":"code","colab":{},"trusted":false},"cell_type":"code","source":"\"\"\"\nreturns model\n\"\"\"\ndef get_model(name, input_shape, nb_out):\n    \n    models = {\n        'resnet50':    get_resnet50,\n        'conv1':       get_conv1,\n        'conv2':       get_conv2,\n        'densenet121': get_densenet121\n    }\n    \n    if name not in models:\n        print(f\"No model named '{name}'\")\n        return\n    \n    model = models[name](input_shape, nb_out)\n    \n    weights_path = weights_path_template.format(name)\n    if os.path.isfile(weights_path):\n        model.load_weights(weights_path)\n        print(f\"loaded model weights from {weights_path}\")\n        \n    return model","execution_count":0,"outputs":[]},{"metadata":{"id":"2Qu91Ugx4imc","colab_type":"text"},"cell_type":"markdown","source":"## Training\nSet TRAINING to False in submission notebook"},{"metadata":{"id":"ImiwXFEVYcqz","colab_type":"text"},"cell_type":"markdown","source":"### QWK metric"},{"metadata":{"id":"hFJzOj5HYe-S","colab_type":"code","colab":{},"trusted":false},"cell_type":"code","source":"# class qwk_metric(Metric):\n\n#     def __init__(self, name='qwk', **kwargs):\n#         super(qwk_metric, self).__init__(name=name, **kwargs)\n#         self.kappa = None\n\n\n#     def update_state(self, y_true, y_pred, sample_weight=None):\n#         labels = tf.reduce_sum(tf.cast(y_true, tf.int32), axis=1) - 1\n        \n#         self.kappa = tf.contrib.metrics.cohen_kappa(\n            \n#         )\n\n\n#     def result(self):\n#         return self.true_positives\n\n\n#     def reset_states(self):\n#         # The state of the metric will be reset at the start of each epoch.\n#         self.true_positives.assign(0.)","execution_count":0,"outputs":[]},{"metadata":{"id":"nbumUBsgClwz","colab_type":"text"},"cell_type":"markdown","source":"### ResNet50-based model"},{"metadata":{"id":"VuX1jUxmCjUP","colab_type":"code","colab":{},"trusted":false},"cell_type":"code","source":"\"\"\"\ntrains a ResNet50-based model\n\"\"\"\ndef train_resnet50(model, train_generator, val_generator, weights_path, log_path):\n    \n    # ==== train top layers only (warm up) ====\n    \n    for i in range(len(model.layers)):\n        model.layers[i].trainable = False\n\n    for i in range(-5, 0):\n        model.layers[i].trainable = True\n\n    metrics_list = [\"accuracy\"]\n    optimizer = Adam(lr=INITIAL_LR)\n\n    model.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=metrics_list)\n    \n    mc = ModelCheckpoint(weights_path, monitor='val_loss', save_best_only=True, verbose=1)\n    es = EarlyStopping(monitor='val_loss', mode='min', restore_best_weights=True, verbose=1)\n    cl = CSVLogger(log_path)\n\n    STEP_SIZE_TRAIN = train_generator.n // train_generator.batch_size\n    STEP_SIZE_VAL = val_generator.n // val_generator.batch_size\n\n    model.fit_generator(\n        generator=train_generator,\n        steps_per_epoch=STEP_SIZE_TRAIN,\n        validation_data=val_generator,\n        validation_steps=STEP_SIZE_VAL,\n        epochs=NB_WARMUP_EPOCHS,\n        callbacks=[mc, cl],\n        verbose=1\n    )\n    \n    \n    # ==== fine tune all layers ====\n    \n    train_gen.reset()\n    val_gen.reset()\n    \n    for i in range(len(model.layers)):\n        model.layers[i].trainable = True\n    \n    optimizer = Adam(lr=INITIAL_LR)\n\n    model.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=metrics_list)\n    \n    mc = ModelCheckpoint(weights_path, monitor='val_loss', save_best_only=True, verbose=1)\n    es = EarlyStopping(monitor='val_loss', mode='min', restore_best_weights=True, verbose=1)\n    cl = CSVLogger(log_path)\n\n    STEP_SIZE_TRAIN = train_generator.n // train_generator.batch_size\n    STEP_SIZE_VAL = val_generator.n // val_generator.batch_size\n\n    model.fit_generator(\n        generator=train_generator,\n        steps_per_epoch=STEP_SIZE_TRAIN,\n        validation_data=val_generator,\n        validation_steps=STEP_SIZE_VAL,\n        epochs=NB_WARMUP_EPOCHS,\n        callbacks=[mc, cl],\n        verbose=1\n    )","execution_count":0,"outputs":[]},{"metadata":{"id":"rby8nrLOO5lW","colab_type":"text"},"cell_type":"markdown","source":"### DenseNet121-based model"},{"metadata":{"id":"MfwSY0cqO8C5","colab_type":"code","colab":{},"trusted":false},"cell_type":"code","source":"def train_densenet121(model, train_generator, val_generator, weights_path, log_path):\n    \n    metrics_list = [\"accuracy\"]\n    \n    optimizer = Adam(lr=INITIAL_LR)\n\n    model.compile(optimizer=optimizer, loss='binary_crossentropy', metrics=metrics_list)\n    \n    mc = ModelCheckpoint(weights_path, monitor='val_loss', save_best_only=True, verbose=1)\n    es = EarlyStopping(monitor='val_loss', mode='min', restore_best_weights=True, verbose=1)\n    cl = CSVLogger(log_path)\n\n    STEP_SIZE_TRAIN = train_generator.n // train_generator.batch_size\n    STEP_SIZE_VAL = val_generator.n // val_generator.batch_size\n\n    model.fit_generator(\n        generator=train_generator,\n        steps_per_epoch=STEP_SIZE_TRAIN,\n        validation_data=val_generator,\n        validation_steps=STEP_SIZE_VAL,\n        epochs=NB_EPOCHS,\n        callbacks=[mc, cl],\n        verbose=1\n    )","execution_count":0,"outputs":[]},{"metadata":{"id":"PTrYBmLzG9x8","colab_type":"text"},"cell_type":"markdown","source":"### Simple CNN"},{"metadata":{"id":"PxxHJa86DKne","colab_type":"code","colab":{},"trusted":false},"cell_type":"code","source":"\"\"\"\ntrains the simple CNN\n\"\"\"\ndef train_conv1(model, train_generator, val_generator, weights_path, log_path):\n    \n    metrics_list = [\"accuracy\"]\n    optimizer = Adam(lr=INITIAL_LR)\n\n    model.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=metrics_list)\n    \n    mc = ModelCheckpoint(weights_path, monitor='val_loss', save_best_only=True, verbose=1)\n    es = EarlyStopping(monitor='val_loss', mode='min', restore_best_weights=True, verbose=1)\n    cl = CSVLogger(log_path)\n\n    STEP_SIZE_TRAIN = train_generator.n // train_generator.batch_size\n    STEP_SIZE_VAL = val_generator.n // val_generator.batch_size\n\n    model.fit_generator(\n        generator=train_generator,\n        steps_per_epoch=STEP_SIZE_TRAIN,\n        validation_data=val_generator,\n        validation_steps=STEP_SIZE_VAL,\n        epochs=NB_EPOCHS,\n        callbacks=[mc, cl],\n        verbose=1\n    )","execution_count":0,"outputs":[]},{"metadata":{"id":"QPeK_3a73YBY","colab_type":"text"},"cell_type":"markdown","source":"### Simple CNN v2"},{"metadata":{"id":"yyJ6Pu_b3bv4","colab_type":"code","colab":{},"trusted":false},"cell_type":"code","source":"def train_conv2(model, train_generator, val_generator, weights_path, log_path):\n        \n    metrics_list = [\"accuracy\"]\n    optimizer = Adam(lr=INITIAL_LR)\n\n    model.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=metrics_list)\n    \n    mc = ModelCheckpoint(weights_path, monitor='val_loss', save_best_only=True, verbose=1)\n    es = EarlyStopping(monitor='val_loss', mode='min', restore_best_weights=True, verbose=1)\n    cl = CSVLogger(log_path)\n\n    STEP_SIZE_TRAIN = train_generator.n // train_generator.batch_size\n    STEP_SIZE_VAL = val_generator.n // val_generator.batch_size\n\n    model.fit_generator(\n        generator=train_generator,\n        steps_per_epoch=STEP_SIZE_TRAIN,\n        validation_data=val_generator,\n        validation_steps=STEP_SIZE_VAL,\n        epochs=NB_EPOCHS,\n        callbacks=[mc, cl],\n        verbose=1\n    )","execution_count":0,"outputs":[]},{"metadata":{"id":"YnunQ_XFGmmE","colab_type":"text"},"cell_type":"markdown","source":"### Generic"},{"metadata":{"id":"KJdrTadKBNY_","colab_type":"code","colab":{},"trusted":false},"cell_type":"code","source":"def train_model(name, input_shape, nb_out, train_generator, val_generator):\n    model = get_model(name, input_shape, nb_out)\n\n    trainers = {\n        'resnet50':    train_resnet50,\n        'conv1':       train_conv1,\n        'conv2':       train_conv2,\n        'densenet121': train_densenet121\n    }\n\n    if name not in trainers:\n        print(f\"No model named '{name}'\")\n        return\n\n    trainers[name](model, train_generator, val_generator,\n                   weights_path_template.format(name),\n                   log_path_template.format(name))","execution_count":0,"outputs":[]},{"metadata":{"id":"tsonPJmnCMwc","colab_type":"code","outputId":"73359a5a-7274-4656-fdf5-b15012ef7d6d","colab":{"base_uri":"https://localhost:8080/","height":1000},"trusted":false},"cell_type":"code","source":"if TRAINING:\n    train_model(MODEL_NAME, (IMG_SIZE, IMG_SIZE, NB_CHANNELS), NB_CLASSES, train_gen, val_gen)","execution_count":null,"outputs":[]},{"metadata":{"id":"Tvm_-tyj4ims","colab_type":"text"},"cell_type":"markdown","source":"## Predicting on test set"},{"metadata":{"trusted":true,"id":"PJX01MWd4imu","colab_type":"code","outputId":"ddb10f8e-4844-45f3-a8b9-686d39094e9d","colab":{"base_uri":"https://localhost:8080/","height":571}},"cell_type":"code","source":"model = get_model(MODEL_NAME, (IMG_SIZE, IMG_SIZE, NB_CHANNELS), NB_CLASSES)\ntest_gen.reset()\n# STEP_SIZE_TEST = math.ceil(test_gen.n / test_gen.batch_size)\n\npreds = model.predict_generator(test_gen, verbose=1)\n# predictions = np.argmax(preds, axis=1)\npreds = preds > 0.5\npredictions = preds.astype(int).sum(axis=1) - 1\n\nfilenames = test_gen.filenames\nresults = pd.DataFrame({'id_code': filenames, 'diagnosis': predictions})\nresults['id_code'] = results['id_code'].map(lambda x: str(x)[:-4])   # remove .png\nresults.to_csv('submission.csv', index=False)\n# results.head(10)","execution_count":null,"outputs":[]}],"metadata":{"colab":{"name":"aptos_2019_multilabel.ipynb","version":"0.3.2","provenance":[],"collapsed_sections":[],"toc_visible":true},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kernelspec":{"name":"python3","display_name":"Python 3"},"accelerator":"GPU"},"nbformat":4,"nbformat_minor":1}