{"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":"# Implementation of EfficientNetB5 for the APTOS 2019 dataset with Keras","metadata":{}},{"cell_type":"code","source":"import os\nimport cv2\nimport random\nimport warnings\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nfrom sklearn.metrics import confusion_matrix, cohen_kappa_score\nfrom keras.models import Model\nfrom sklearn.utils import class_weight\nfrom sklearn.model_selection import train_test_split\nfrom keras import backend as K\nfrom keras.utils import to_categorical\n\nfrom keras import optimizers, applications\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.callbacks import EarlyStopping, ReduceLROnPlateau, Callback, LearningRateScheduler\nfrom keras.layers import Dense, Dropout, GlobalAveragePooling2D, Input\n\n# Set seeds to make the experiment more reproducible.\nfrom tensorflow import set_random_seed\ndef seed_everything(seed=0):\n    random.seed(seed)\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    np.random.seed(seed)\n    set_random_seed(0)\nseed = 0\nseed_everything(seed)\n\n%matplotlib inline\nsns.set(style=\"whitegrid\")\nwarnings.filterwarnings(\"ignore\")","metadata":{"execution":{"iopub.status.busy":"2023-05-04T16:40:22.883436Z","iopub.execute_input":"2023-05-04T16:40:22.883760Z","iopub.status.idle":"2023-05-04T16:40:25.169342Z","shell.execute_reply.started":"2023-05-04T16:40:22.883702Z","shell.execute_reply":"2023-05-04T16:40:25.168501Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = pd.read_csv('../input/aptos2019-blindness-detection/train.csv')\ntest = pd.read_csv('../input/aptos2019-blindness-detection/test.csv')","metadata":{"execution":{"iopub.status.busy":"2023-05-04T16:40:27.032384Z","iopub.execute_input":"2023-05-04T16:40:27.032718Z","iopub.status.idle":"2023-05-04T16:40:27.048793Z","shell.execute_reply.started":"2023-05-04T16:40:27.032654Z","shell.execute_reply":"2023-05-04T16:40:27.047946Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('Number of train samples: ', train.shape[0])\nprint('Number of test samples: ', test.shape[0])\ndisplay(train.head())","metadata":{"execution":{"iopub.status.busy":"2023-05-04T16:40:28.822500Z","iopub.execute_input":"2023-05-04T16:40:28.822847Z","iopub.status.idle":"2023-05-04T16:40:28.841927Z","shell.execute_reply.started":"2023-05-04T16:40:28.822787Z","shell.execute_reply":"2023-05-04T16:40:28.841110Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"f, ax = plt.subplots(figsize=(14, 8.7))\nax = sns.countplot(x=\"diagnosis\", data=train, palette=\"GnBu_d\")\nsns.despine()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-05-04T16:40:30.862316Z","iopub.execute_input":"2023-05-04T16:40:30.862638Z","iopub.status.idle":"2023-05-04T16:40:31.145681Z","shell.execute_reply.started":"2023-05-04T16:40:30.862571Z","shell.execute_reply":"2023-05-04T16:40:31.144811Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sns.set_style(\"white\")\ncount = 1\nplt.figure(figsize=[20, 20])\nfor img_name in train['id_code'][:15]:\n    img = cv2.imread(\"../input/aptos2019-blindness-detection/train_images/%s.png\" % img_name)[...,[2, 1, 0]]\n    plt.subplot(5, 5, count)\n    plt.imshow(img)\n    plt.title(\"Image %s\" % count)\n    count += 1\n    \nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-05-04T16:40:33.052441Z","iopub.execute_input":"2023-05-04T16:40:33.052780Z","iopub.status.idle":"2023-05-04T16:40:39.194028Z","shell.execute_reply.started":"2023-05-04T16:40:33.052719Z","shell.execute_reply":"2023-05-04T16:40:39.191755Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Model parameters\nBATCH_SIZE = 16\nEPOCHS = 40\nWARMUP_EPOCHS = 5\nLEARNING_RATE = 1e-4\nWARMUP_LEARNING_RATE = 1e-3\nHEIGHT = 320\nWIDTH = 320\nCANAL = 3\nN_CLASSES = train['diagnosis'].nunique()\nES_PATIENCE = 5\nRLROP_PATIENCE = 3\nDECAY_DROP = 0.5","metadata":{"execution":{"iopub.status.busy":"2023-05-04T16:40:45.202479Z","iopub.execute_input":"2023-05-04T16:40:45.202807Z","iopub.status.idle":"2023-05-04T16:40:45.208696Z","shell.execute_reply.started":"2023-05-04T16:40:45.202751Z","shell.execute_reply":"2023-05-04T16:40:45.207924Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Preprocecss data\ntrain[\"id_code\"] = train[\"id_code\"].apply(lambda x: x + \".png\")\ntest[\"id_code\"] = test[\"id_code\"].apply(lambda x: x + \".png\")\ntrain['diagnosis'] = train['diagnosis'].astype('str')\ntrain.head()","metadata":{"execution":{"iopub.status.busy":"2023-05-04T16:40:48.332470Z","iopub.execute_input":"2023-05-04T16:40:48.332981Z","iopub.status.idle":"2023-05-04T16:40:48.350938Z","shell.execute_reply.started":"2023-05-04T16:40:48.332907Z","shell.execute_reply":"2023-05-04T16:40:48.350045Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def crop_image_from_gray(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        \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    #         print(img1.shape,img2.shape,img3.shape)\n            img = np.stack([img1,img2,img3],axis=-1)\n    #         print(img.shape)\n        return img\n\ndef circle_crop(img):\n    img = crop_image_from_gray(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_from_gray(img)\n\n    return img    \n    \ndef preprocess_image(image, sigmaX=10):\n#     image = cv2.imread(path)\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        \n    return image","metadata":{"execution":{"iopub.status.busy":"2023-05-04T16:40:50.802568Z","iopub.execute_input":"2023-05-04T16:40:50.802911Z","iopub.status.idle":"2023-05-04T16:40:50.813527Z","shell.execute_reply.started":"2023-05-04T16:40:50.802855Z","shell.execute_reply":"2023-05-04T16:40:50.812754Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(1, 5, figsize=(15, 6))\nfor i in range(5):\n    sample = train[train['diagnosis'] == str(i)].sample(1)\n    image_name = sample['id_code'].item()\n    X = preprocess_image(cv2.imread(f\"/kaggle/input/aptos2019-blindness-detection/train_images/{ image_name }\"))\n    ax[i].set_title(f\"Image: { image_name }\\n Label = { sample['diagnosis'].item() }\", \n                    weight = 'bold', fontsize = 10)\n    ax[i].axis('off')\n    ax[i].imshow(X);","metadata":{"execution":{"iopub.status.busy":"2023-05-04T16:40:54.892568Z","iopub.execute_input":"2023-05-04T16:40:54.892924Z","iopub.status.idle":"2023-05-04T16:40:56.858483Z","shell.execute_reply.started":"2023-05-04T16:40:54.892868Z","shell.execute_reply":"2023-05-04T16:40:56.857599Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_datagen=ImageDataGenerator(rescale=1./255, \n                                 rotation_range=360,\n                                 vertical_flip=True,\n                                 preprocessing_function=preprocess_image,\n                                 validation_split=0.2,\n                                 horizontal_flip=True)\n\ntrain_generator=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    batch_size=BATCH_SIZE,\n    class_mode=\"categorical\",\n    seed=seed,\n    target_size=(HEIGHT, WIDTH),\n    subset='training')\n\nvalid_generator=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    seed=seed,\n    batch_size=BATCH_SIZE,\n    class_mode=\"categorical\",    \n    target_size=(HEIGHT, WIDTH),\n    subset='validation')\n\ntest_datagen = ImageDataGenerator(rescale=1./255,\n                                 rotation_range=360,\n                                 vertical_flip=True,\n                                 validation_split=0.2,\n                                  preprocessing_function=preprocess_image,\n                                 horizontal_flip=True)\n\ntest_generator = test_datagen.flow_from_dataframe(  \n        dataframe=test,\n        directory = \"../input/aptos2019-blindness-detection/test_images/\",\n        x_col=\"id_code\",\n        target_size=(HEIGHT, WIDTH),\n        batch_size=1,\n        shuffle=False,\n        class_mode=None)","metadata":{"execution":{"iopub.status.busy":"2023-05-04T16:41:17.963602Z","iopub.execute_input":"2023-05-04T16:41:17.963952Z","iopub.status.idle":"2023-05-04T16:41:37.166703Z","shell.execute_reply.started":"2023-05-04T16:41:17.963896Z","shell.execute_reply":"2023-05-04T16:41:37.165773Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install ../input/efficientnet100","metadata":{"execution":{"iopub.status.busy":"2023-05-04T16:48:51.806509Z","iopub.execute_input":"2023-05-04T16:48:51.806841Z","iopub.status.idle":"2023-05-04T16:48:59.815344Z","shell.execute_reply.started":"2023-05-04T16:48:51.806783Z","shell.execute_reply":"2023-05-04T16:48:59.814305Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from efficientnet.keras import EfficientNetB7 as EfficientNet\ndef create_model(input_shape, n_out):\n    input_tensor = Input(shape=input_shape)\n    base_model = EfficientNet(weights=None, \n                              include_top=False,\n                              input_tensor=input_tensor)\n    base_model.load_weights('/kaggle/input/efficientnet-keras-weights-b0b5/efficientnet-b5_imagenet_1000_notop.h5')\n\n    x = GlobalAveragePooling2D()(base_model.output)\n    x = Dropout(0.5)(x)\n    x = Dense(2048, activation='relu')(x)\n    x = Dropout(0.5)(x)\n    final_output = Dense(n_out, activation='softmax', name='final_output')(x)\n    model = Model(input_tensor, final_output)\n    \n    return model","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = create_model(input_shape=(HEIGHT, WIDTH, CANAL), n_out=N_CLASSES)\n\nfor layer in model.layers:\n    layer.trainable = False\n\nfor i in range(-5, 0):\n    model.layers[i].trainable = True\n    \nclass_weights = class_weight.compute_class_weight('balanced', \n                                                  np.unique(X_train['diagnosis'].astype('int').values), \n                                                  X_train['diagnosis'].astype('int').values)\n\n\nmetric_list = [\"accuracy\"]\noptimizer = optimizers.Adam(lr=WARMUP_LEARNING_RATE)\nmodel.compile(optimizer=optimizer, loss=\"categorical_crossentropy\",  metrics=metric_list)\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2023-05-04T17:24:24.446561Z","iopub.execute_input":"2023-05-04T17:24:24.446952Z","iopub.status.idle":"2023-05-04T17:24:58.475874Z","shell.execute_reply.started":"2023-05-04T17:24:24.446893Z","shell.execute_reply":"2023-05-04T17:24:58.474952Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"STEP_SIZE_TRAIN = train_generator.n//train_generator.batch_size\nSTEP_SIZE_VALID = valid_generator.n//valid_generator.batch_size\n\nhistory_warmup = model.fit_generator(generator=train_generator,\n                                     steps_per_epoch=STEP_SIZE_TRAIN,\n                                     validation_data=valid_generator,\n                                     validation_steps=STEP_SIZE_VALID,\n                                     epochs=WARMUP_EPOCHS,\n                                     class_weight=class_weights,\n                                     verbose=1).history","metadata":{"execution":{"iopub.status.busy":"2023-05-04T17:25:22.186699Z","iopub.execute_input":"2023-05-04T17:25:22.187035Z","iopub.status.idle":"2023-05-04T17:41:22.195698Z","shell.execute_reply.started":"2023-05-04T17:25:22.186980Z","shell.execute_reply":"2023-05-04T17:41:22.194742Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for layer in model.layers:\n    layer.trainable = True\n\nes = EarlyStopping(monitor='val_loss', mode='min', patience=ES_PATIENCE, restore_best_weights=True, verbose=1)\nrlrop = ReduceLROnPlateau(monitor='val_loss', mode='min', patience=RLROP_PATIENCE, factor=DECAY_DROP, min_lr=1e-6, verbose=1)\n\ncallback_list = [es, rlrop]\noptimizer = optimizers.Adam(lr=LEARNING_RATE)\nmodel.compile(optimizer=optimizer, loss=\"categorical_crossentropy\",  metrics=metric_list)\nmodel.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history_finetunning = model.fit_generator(generator=train_generator,\n                                          steps_per_epoch=STEP_SIZE_TRAIN,\n                                          validation_data=valid_generator,\n                                          validation_steps=STEP_SIZE_VALID,\n                                          epochs=int(EPOCHS*0.8),\n                                          callbacks=callback_list,\n                                          class_weight=class_weights,\n                                          verbose=1).history","metadata":{"execution":{"iopub.status.busy":"2023-05-04T17:44:36.035238Z","iopub.execute_input":"2023-05-04T17:44:36.035553Z","iopub.status.idle":"2023-05-04T18:23:35.346005Z","shell.execute_reply.started":"2023-05-04T17:44:36.035500Z","shell.execute_reply":"2023-05-04T18:23:35.339684Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"optimizer = optimizers.SGD(lr=LEARNING_RATE, momentum=0.9, nesterov=True)\nmodel.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=metric_list)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history_finetunning_2 = model.fit_generator(generator=train_generator,\n                                          steps_per_epoch=STEP_SIZE_TRAIN,\n                                          validation_data=valid_generator,\n                                          validation_steps=STEP_SIZE_VALID,\n                                          epochs=int(EPOCHS*0.2),\n                                          callbacks=callback_list,\n                                          class_weight=class_weights,\n                                          verbose=1).history","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = {'loss': history_finetunning['loss'] + history_finetunning_2['loss'], \n           'val_loss': history_finetunning['val_loss'] + history_finetunning_2['val_loss'], \n           'acc': history_finetunning['acc'] + history_finetunning_2['acc'], \n           'val_acc': history_finetunning['val_acc'] + history_finetunning_2['val_acc']}\n\nsns.set_style(\"whitegrid\")\nfig, (ax1, ax2) = plt.subplots(2, 1, sharex='col', figsize=(20, 14))\n\nax1.plot(history['loss'], label='Train loss')\nax1.plot(history['val_loss'], label='Validation loss')\nax1.legend(loc='best')\nax1.set_title('Loss')\n\nax2.plot(history['acc'], label='Train Accuracy')\nax2.plot(history['val_acc'], label='Validation accuracy')\nax2.legend(loc='best')\nax2.set_title('Accuracy')\n\nplt.xlabel('Epochs')\nsns.despine()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-05-04T18:24:07.606093Z","iopub.execute_input":"2023-05-04T18:24:07.606424Z","iopub.status.idle":"2023-05-04T18:24:07.631444Z","shell.execute_reply.started":"2023-05-04T18:24:07.606364Z","shell.execute_reply":"2023-05-04T18:24:07.630296Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create empty arays to keep the predictions and labels\nlastFullTrainPred = np.empty((0, N_CLASSES))\nlastFullTrainLabels = np.empty((0, N_CLASSES))\nlastFullValPred = np.empty((0, N_CLASSES))\nlastFullValLabels = np.empty((0, N_CLASSES))\n\n# Add train predictions and labels\nfor i in range(STEP_SIZE_TRAIN+1):\n    im, lbl = next(train_generator)\n    scores = model.predict(im, batch_size=train_generator.batch_size)\n    lastFullTrainPred = np.append(lastFullTrainPred, scores, axis=0)\n    lastFullTrainLabels = np.append(lastFullTrainLabels, lbl, axis=0)\n\n# Add validation predictions and labels\nfor i in range(STEP_SIZE_VALID+1):\n    im, lbl = next(valid_generator)\n    scores = model.predict(im, batch_size=valid_generator.batch_size)\n    lastFullValPred = np.append(lastFullValPred, scores, axis=0)\n    lastFullValLabels = np.append(lastFullValLabels, lbl, axis=0)\n\nlastFullComPred = np.concatenate((lastFullTrainPred, lastFullValPred))\nlastFullComLabels = np.concatenate((lastFullTrainLabels, lastFullValLabels))\n\ntrain_preds = [np.argmax(pred) for pred in lastFullTrainPred]\ntrain_labels = [np.argmax(label) for label in lastFullTrainLabels]\nvalidation_preds = [np.argmax(pred) for pred in lastFullValPred]\nvalidation_labels = [np.argmax(label) for label in lastFullValLabels]\ncomplete_labels = [np.argmax(label) for label in lastFullComLabels]","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# complete_datagen = ImageDataGenerator(rescale=1./255)\n# complete_generator = complete_datagen.flow_from_dataframe(  \n#         dataframe=train,\n#         directory = \"../input/aptos2019-blindness-detection/train_images/\",\n#         x_col=\"id_code\",\n#         target_size=(HEIGHT, WIDTH),\n#         batch_size=1,\n#         shuffle=False,\n#         class_mode=None)\n\n# STEP_SIZE_COMPLETE = complete_generator.n//complete_generator.batch_size\n# train_preds = model.predict_generator(complete_generator, steps=STEP_SIZE_COMPLETE)\n# train_preds = [np.argmax(pred) for pred in train_preds]","metadata":{},"execution_count":null,"outputs":[]},{"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\nplot_confusion_matrix((train_labels, train_preds), (validation_labels, validation_preds))","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def 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(train_preds+validation_preds, train_labels+validation_labels, weights='quadratic'))\n    \nprint(\"   Original thresholds\")\nevaluate_model((train_preds, train_labels), (validation_preds, validation_labels))","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.metrics import classification_report\n\ncr = classification_report(train_preds, train_labels)\nprint(cr)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Train Cohen Kappa score: %.3f\" % cohen_kappa_score(train_preds, train['diagnosis'].astype('int'), weights='quadratic'))","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_generator.reset()\nSTEP_SIZE_TEST = test_generator.n//test_generator.batch_size\npreds = model.predict_generator(test_generator, steps=STEP_SIZE_TEST)\npredictions = [np.argmax(pred) for pred in preds]","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"filenames = test_generator.filenames\nresults = pd.DataFrame({'id_code':filenames, 'diagnosis':predictions})\nresults['id_code'] = results['id_code'].map(lambda x: str(x)[:-4])\nresults.to_csv('submission.csv',index=False)\nresults.head(10)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"f, ax = plt.subplots(figsize=(14, 8.7))\nax = sns.countplot(x=\"diagnosis\", data=results, palette=\"GnBu_d\")\nsns.despine()\nplt.show()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## ## End of Code ## ##","metadata":{}}]}