{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Cassava leaf disease classification [pre-trained model]"},{"metadata":{},"cell_type":"markdown","source":"The objective of this notebook is to generate a pre-trained model for the Cassava Leaf Disease Classification dataset. This pre-trained model will serve as an initialization to another model (final model) in order to propose a performing model without internet. "},{"metadata":{},"cell_type":"markdown","source":"This is my first notebook in computer vision and I would like to thank the authors of the following notebooks from which I have learned a lot and from which I have been greatly inspired:\n* [Step-by-Step Guide to Denoising Your Labels](https://www.kaggle.com/junyingsg/step-by-step-guide-to-denoising-your-labels)\n* [Cassava Leaf Disease: Best Keras CNN](https://www.kaggle.com/maksymshkliarevskyi/cassava-leaf-disease-best-keras-cnn)\n* [Xception - Cassava Leaf Disease Classification](https://www.kaggle.com/eceifter/xception-cassava-leaf-disease-classification)"},{"metadata":{},"cell_type":"markdown","source":"Here are the steps of this notebook :\n* Split the training data set into 5 folds of equal distribution for cross validation\n* Train one EfficientNetB0 keras model with transfer learning for each fold\n* Estimate with the Test Time method Increase the predictions of each fold\n* Detecting Mislabeling bias\n* Training an EfficientNetB0 model without bias and with transfer learning"},{"metadata":{},"cell_type":"markdown","source":"### Import python packages"},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true,"scrolled":true},"cell_type":"code","source":"import keras\nfrom keras.models import Model, Sequential\nfrom keras.layers import Dense, GlobalAveragePooling2D, experimental\nfrom keras import optimizers\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.preprocessing import image\nfrom keras.applications.vgg16 import VGG16\nfrom tensorflow.keras.applications import EfficientNetB4, EfficientNetB0\nfrom tensorflow.keras.experimental import CosineDecay\nfrom tensorflow import expand_dims\nfrom keras.callbacks import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau\nfrom keras.models import load_model\n\nimport pandas as pd\nimport cv2\nimport os\nimport random\nimport gc\nimport matplotlib.pyplot as plt\nimport numpy as np\n%matplotlib inline\nimport seaborn as sns\nfrom sklearn.model_selection import StratifiedKFold \nfrom PIL import Image\nfrom tqdm import tqdm","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Define input and output paths"},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"INPUT_PATH = '../input/cassava-leaf-disease-classification'\nOUTPUT_PATH = './'","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Visualisation of the input data"},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"train_list = pd.read_csv(os.path.join(INPUT_PATH, 'train.csv'))\ntrain_list.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"label_num_to_disease_map = pd.read_json('/kaggle/input/cassava-leaf-disease-classification/label_num_to_disease_map.json', typ='series')\nlabel_num_to_disease_map","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Repartition of the labels"},{"metadata":{},"cell_type":"markdown","source":"#### Histogram"},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"label_repartition = train_list.groupby(['label']).count()\nlabel_repartition.columns = ['count']\nlabel_repartition.index.tolist()\nplt.ylabel('count')\nplt.title(\"histogram of labels\")\nplt.xlabel('labels')\nsns.barplot(x=label_repartition.index.tolist(), y=label_repartition['count'], palette=\"rocket\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Pie"},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"import plotly.express as px\npie_df = train_list['label'].value_counts().reset_index()\npie_df.columns = ['label', 'count']\npie_df['text_label'] = pie_df['label'].apply(lambda x:label_num_to_disease_map.tolist()[x])\nfig = px.pie(pie_df, values = 'count', names = 'text_label', hole=.27)\nfig.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"The labels are not fairly distributed. The Cassava label is particularly in the majority (more than 60%). When applying a cross validation, it is relevant to ensure that the proportion of each class is the same in each group. "},{"metadata":{},"cell_type":"markdown","source":"### Visualization of each class"},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"train_list['image_path'] = train_list.apply(lambda x: os.path.join(INPUT_PATH,'train_images/{}'.format(x['image_id'])), axis=1).tolist()\ntrain_list","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"def plot_label_images(dataset, label):\n    print('Images with label {} for : {}'.format(label, label_num_to_disease_map.tolist()[int(label)]))\n    filtered_dataset_head = dataset[dataset.label == label].sample(6)\n    plt.figure(figsize=(20, 12))\n    columns = 6\n    for i in range(columns):\n        plt.subplot(2, 3, i+1)\n        image = cv2.imread(os.path.join(INPUT_PATH,'train_images/{}'.format(filtered_dataset_head['image_id'].iloc[i])))\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        plt.imshow(image)\n    plt.show()\n    return","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Label 0 : Cassava Bacterial Blight (CBB)"},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"plot_label_images(train_list, 0)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Label 1 : Cassava Brown Streak Disease (CBSD)"},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"plot_label_images(train_list, 1)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Label 2 : Cassava Green Mottle (CGM) "},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"plot_label_images(train_list, 2)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Label 3 : Cassava Mosaic Disease (CMD)"},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"plot_label_images(train_list, 3)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Label 4 : Healthy"},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"plot_label_images(train_list, 4)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Correction of mislabeling biases"},{"metadata":{},"cell_type":"markdown","source":"A neural network can be very affected by label errors on training data. This part aims at identifying cases of mislabeling bias. A cross validation distribution with 20% validation and 80% training will be applied. In order to respect the distribution of classes in each split, StratifiedKFold from sklearn will be used. This will allow us to have 5 distinct training groups with their equivalent validation groups."},{"metadata":{},"cell_type":"markdown","source":"### Definition of hyperparameters"},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"train_list.label = train_list.label.astype('str')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"BATCH_SIZE = 32 #Mini-Batch Gradient Descent \nSTEPS_PER_EPOCH = len(train_list)*0.8 / BATCH_SIZE\nVALIDATION_STEPS = len(train_list)*0.2 / BATCH_SIZE\nEPOCHS = 3\nTARGET_SIZE = 350\nn_splits = 5\nseed_value = 2019","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Definition of the training and validation data pipeline as well as image enhancement, using ImageDataGenerator"},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"def generate_input_data(train_set, val_set):\n    train_datagen = ImageDataGenerator()\n    \n    train_generator = train_datagen.flow_from_dataframe(train_set,\n                         directory = os.path.join(INPUT_PATH,'train_images'),\n                         x_col = \"image_id\",\n                         y_col = \"label\",\n                         target_size = (TARGET_SIZE, TARGET_SIZE),\n                         batch_size = BATCH_SIZE,\n                         class_mode = \"sparse\",\n                         shuffle= True,\n                         seed=seed_value)\n    \n        \n    validation_generator = ImageDataGenerator().flow_from_dataframe(\n                         dataframe = val_set,\n                         directory = os.path.join(INPUT_PATH,'train_images'),\n                         x_col = \"image_id\",\n                         y_col = \"label\",\n                         target_size = (TARGET_SIZE, TARGET_SIZE),\n                         shuffle=False,\n                         batch_size = BATCH_SIZE,\n                         class_mode = \"sparse\",\n                         seed=seed_value)\n\n\n    return train_generator, validation_generator","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### A function to create a basic CNN model with transfert learning"},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"def create_basic_model(model_name, lr=0.001):\n    if model_name == 'EfficientNetB0':\n         conv_base = EfficientNetB0(include_top = False, weights = 'imagenet',\n                               input_shape = (TARGET_SIZE, TARGET_SIZE, 3))\n    elif model_name == 'EfficientNetB4':\n         conv_base = EfficientNetB4(include_top = False, weights = 'imagenet',\n                               input_shape = (TARGET_SIZE, TARGET_SIZE, 3))\n    elif model_name == 'VGG16':\n         conv_base = VGG16(include_top = False, weights = 'imagenet',\n                               input_shape = (TARGET_SIZE, TARGET_SIZE, 3))\n    else:\n        print(\"the model {} is not recognize\".format(model_name))\n        return\n    model = conv_base.output\n    model = GlobalAveragePooling2D()(model)\n    model = Dense(5, activation = \"softmax\", dtype='float32')(model)\n    model = Model(conv_base.input, model)\n\n    model.compile(optimizer = optimizers.Adam(learning_rate=lr),\n                  loss = \"sparse_categorical_crossentropy\",\n                  metrics = [\"acc\"])\n    return model","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"***Clear the backend of keras on this session and create the 5 folds for cross validation***"},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"keras.backend.clear_session()\nskf = StratifiedKFold(n_splits=n_splits, random_state=seed_value, shuffle=True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Training of the model for each group of the cross validation "},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"fold_number = 0\noof_acc = []\nall_steps = int(STEPS_PER_EPOCH+1)*EPOCHS\nlr = CosineDecay(initial_learning_rate=1e-3, decay_steps=all_steps)\nmodel_name = 'effnetb0'\nfor train_index, val_index in skf.split(train_list['image_id'], train_list['label']):\n    train_set = train_list.loc[train_index]\n    val_set = train_list.loc[val_index]\n    train_generator, validation_generator = generate_input_data(train_set, val_set)\n    basic_model = create_basic_model('EfficientNetB0', lr)\n    print('Taining the fold : {}'.format(fold_number))\n    file_path = '{}_{}_fold.h5'.format(model_name, fold_number+1)\n    callbacks = [ModelCheckpoint(filepath=file_path, monitor='val_acc', save_best_only=True)]\n    history = basic_model.fit(train_generator, epochs=EPOCHS, validation_data=validation_generator, callbacks=callbacks)\n    oof_acc.append(max(history.history[\"val_acc\"]))\n    fold_number += 1\n    if fold_number == n_splits:\n        print(\"Training finished!\")\n    \n    ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"At this stage, there are 5 models each trained for a fold, it would be interesting to know for each associated validation group, the predictive class as well as the probability of prediction. Moreover, to improve the prediction, the time test increase (increase of the images on the validation data) will be used."},{"metadata":{},"cell_type":"markdown","source":"### Time Test Augmentation"},{"metadata":{},"cell_type":"markdown","source":"***function tta to increase validation images***"},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"tta = Sequential(\n    [\n        experimental.preprocessing.RandomFlip(\"horizontal_and_vertical\"),\n        experimental.preprocessing.RandomRotation(0.25),\n        experimental.preprocessing.RandomContrast(0.2)\n    ]\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"def duplicate_image(img_path, image_size=TARGET_SIZE, tta_runs=2):\n\n    img = Image.open(img_path)\n    img = img.resize((image_size, image_size))\n    img_height, img_width = img.size\n    img = np.array(img)\n    \n    img_list = []\n    for i in range(tta_runs):\n        img_list.append(img)\n  \n    return np.array(img_list)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"def predict_with_tta(image_filename, folder, model, tta_runs=2):\n    \n    #apply TTA to each of the 3 images and sum all predictions for each local image\n    localised_predictions = []\n    local_image_list = duplicate_image(folder+image_filename)\n    for local_image in local_image_list:\n        local_image = expand_dims(local_image,0)\n        augmented_images = [tta(local_image) for i in range(tta_runs)]\n        predictions = model.predict(np.array(augmented_images[0]))\n        localised_predictions.append(np.sum(predictions, axis=0))\n    \n    #sum all predictions from all 3 images and retrieve the index of the highest value\n    global_predictions = np.sum(np.array(localised_predictions),axis=0)/tta_runs\n    max_value = max(global_predictions)\n    final_prediction = np.argmax(global_predictions)\n    \n    return [final_prediction, max_value, global_predictions]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"def predict_image_list(image_list, folder, model):\n    predictions = []\n    values = []\n    with tqdm(total=len(image_list)) as pbar:\n        for image_filename in image_list:\n            pbar.update(1)\n            tta_predictions = predict_with_tta(image_filename, folder, model)\n            predictions.append(tta_predictions[0])\n            values.append(tta_predictions[1])\n    return [predictions, values]\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"# First we load our models\nmodels = [] \nfor i in range(5):\n    effnet = load_model(\"./effnetb0_\" + str(i+1) + \"_fold.h5\")\n    models.append(effnet)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"# Then we get our validation data\ndf = pd.read_csv(os.path.join(INPUT_PATH,'train.csv'))\nval_list = []\n\nskf = StratifiedKFold(n_splits=5, random_state=seed_value)\nfor train_index, val_index in skf.split(df[\"image_id\"], df[\"label\"]):\n    val_list.append(val_index)\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### TTA test on an image"},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"train_folder = os.path.join(INPUT_PATH, 'train_images/')\ntrain_image = \"1000015157.jpg\"\npredictions = predict_with_tta(train_image, train_folder, models[0])\n\nprint(\"Predicted Label: \", predictions[0])\nprint(\"Predicted Label Value: \", predictions[1])\nprint(\"Predicted One-Hot Label: \", predictions[2])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Apply TTA on an image list"},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"def predict_image_list(image_list, folder, model):\n    predictions = []\n    values = []\n    with tqdm(total=len(image_list)) as pbar:\n        for image_filename in image_list:\n            pbar.update(1)\n            tta_pred = predict_with_tta(image_filename, folder, model)\n            predictions.append(tta_pred[0])\n            values.append(tta_pred[1])\n    return [predictions, values]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### TTA on validation image of each fold"},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"predictions_by_fold_list = []\nfor i in range(5):\n    fold_prediction = df.loc[val_list[i]]\n    placeholder = predict_image_list(fold_prediction['image_id'], train_folder, models[i])\n    fold_prediction['pred'] = placeholder[0]\n    fold_prediction['value'] = placeholder[1]\n    print(fold_prediction.head())\n    predictions_by_fold_list.append(fold_prediction)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Estimation of poorly labeled images"},{"metadata":{},"cell_type":"markdown","source":"For all predictions made if a data has the right label, it is kept. If it has a badly predicted label with a high degree of certainty then the image will be removed. To do this, we must define a threshold beyond which if a badly labeled image exceeds it it will be seen as a bias."},{"metadata":{},"cell_type":"markdown","source":"***I choise the threshold at 80 %***"},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"threshold = 0.8\nmislabelled_list = []\nfor i in range(5):\n    mask = (predictions_by_fold_list[i]['label'] != predictions_by_fold_list[i]['pred']) & (predictions_by_fold_list[i]['value'] >= threshold)\n    mislabelled_list = mislabelled_list + predictions_by_fold_list[i][mask].index.to_list()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"temp = df.iloc[mislabelled_list]\ntemp[\"label\"].value_counts()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"new list of images without mislabeling noise"},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"df = df.drop(mislabelled_list, axis=\"index\")\ndf.reset_index(drop=True, inplace=True)\ndf.to_csv(\"train_denoised.csv\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Apply a basic CNN Model"},{"metadata":{},"cell_type":"markdown","source":"Now that label errors have been eliminated, the pre-training of the model can begin. This part is used to train a basic CNN with transfer learning and the input layers already trained. This will provide weights for the initialization of the next CNN."},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"BATCH_SIZE = 8 #Mini-Batch Gradient Descent \nSTEPS_PER_EPOCH = len(df)*0.8 / BATCH_SIZE\nVALIDATION_STEPS = len(df)*0.2 / BATCH_SIZE\nEPOCHS = 12\nTARGET_SIZE = 350","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"def build_random_split_data_generator(image_set):\n    train_datagen = ImageDataGenerator(validation_split = 0.2,\n                                     preprocessing_function = None,\n                                     rotation_range = 45,\n                                     zoom_range = 0.2,\n                                     horizontal_flip = True,\n                                     vertical_flip = True,\n                                     fill_mode = 'nearest',\n                                     shear_range = 0.1,\n                                     height_shift_range = 0.1,\n                                     width_shift_range = 0.1)\n\n    train_generator = train_datagen.flow_from_dataframe(image_set,\n                         directory = os.path.join(INPUT_PATH,'train_images'),\n                         subset = \"training\",\n                         x_col = \"image_id\",\n                         y_col = \"label\",\n                         target_size = (TARGET_SIZE, TARGET_SIZE),\n                         batch_size = BATCH_SIZE,\n                         class_mode = \"sparse\")\n\n\n    validation_datagen = ImageDataGenerator(validation_split = 0.2)\n\n    validation_generator = validation_datagen.flow_from_dataframe(image_set,\n                         directory = os.path.join(INPUT_PATH,'train_images'),\n                         subset = \"validation\",\n                         x_col = \"image_id\",\n                         y_col = \"label\",\n                         target_size = (TARGET_SIZE, TARGET_SIZE),\n                         batch_size = BATCH_SIZE,\n                         class_mode = \"sparse\")\n    return train_generator, validation_generator","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"keras.backend.clear_session()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Model training (with reduceLROnPlateau)"},{"metadata":{},"cell_type":"markdown","source":"Using :\n* ModelCheckPoint to save the best weights\n* EarlyStopping to stop the model training if it doesn't learn any more\n* ReduceLROnPlateau to refine the learning rate during training\n* Finally we train the model by keeping loss, accuracy, validation loss and validation accuracy in the variable history."},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"model_name = 'denoised_effnet0'\ndf.label = df.label.astype('str')\n\ntrain_generator, validation_generator = build_random_split_data_generator(df)\nbasic_model = create_basic_model('EfficientNetB0')\nfile_path = '{}_best_weight.h5'.format(model_name)\n             \nmodel_save = ModelCheckpoint(filepath = file_path, \n                             save_best_only = True,\n                             monitor = 'val_loss', \n                             mode = 'min', verbose = 1)\nearly_stop = EarlyStopping(monitor = 'val_loss', min_delta = 0.001, \n                           patience = 5, mode = 'min', verbose = 1,\n                           restore_best_weights = True)\nreduce_lr = ReduceLROnPlateau(monitor = 'val_loss', factor = 0.3, \n                              patience = 2, min_delta = 0.001, \n                              mode = 'min', verbose = 1)\n\n\nhistory = basic_model.fit(\n    train_generator,\n    steps_per_epoch = STEPS_PER_EPOCH,\n    epochs = EPOCHS,\n    validation_data = validation_generator,\n    validation_steps = VALIDATION_STEPS,\n    callbacks = [model_save, early_stop, reduce_lr]\n)\n\naccuracy_best_model = max(history.history[\"val_acc\"])\n    ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Model training statistics"},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"acc = history.history['acc']\nval_acc = history.history['val_acc']\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nepochs = range(1, len(acc) + 1)\n\nfig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 5))\nsns.set_style(\"white\")\nplt.suptitle('Train history', size = 15)\n\nax1.plot(epochs, acc, \"bo\", label = \"Training acc\")\nax1.plot(epochs, val_acc, \"b\", label = \"Validation acc\")\nax1.set_title(\"Training and validation acc\")\nax1.legend()\n\nax2.plot(epochs, loss, \"bo\", label = \"Training loss\", color = 'red')\nax2.plot(epochs, val_loss, \"b\", label = \"Validation loss\", color = 'red')\nax2.set_title(\"Training and validation loss\")\nax2.legend()\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Model training (with CosineDecay)"},{"metadata":{"trusted":true},"cell_type":"code","source":"keras.backend.clear_session()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"all_steps = int(STEPS_PER_EPOCH+1)*EPOCHS\nlr = CosineDecay(initial_learning_rate=1e-3, decay_steps=all_steps)\nmodel_name = 'denoised_effnetb0_cosine_decay'\ntrain_generator, validation_generator = build_random_split_data_generator(df)\nbasic_model = create_basic_model('EfficientNetB0', lr)\nfile_path = '{}_.h5'.format(model_name)\ncallbacks = [ModelCheckpoint(filepath=file_path, monitor='val_acc', save_best_only=True)]\nhistory = basic_model.fit(train_generator, epochs=EPOCHS, validation_data=validation_generator, callbacks=callbacks)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"acc = history.history['acc']\nval_acc = history.history['val_acc']\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nepochs = range(1, len(acc) + 1)\n\nfig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 5))\nsns.set_style(\"white\")\nplt.suptitle('Train history', size = 15)\n\nax1.plot(epochs, acc, \"bo\", label = \"Training acc\")\nax1.plot(epochs, val_acc, \"b\", label = \"Validation acc\")\nax1.set_title(\"Training and validation acc\")\nax1.legend()\n\nax2.plot(epochs, loss, \"bo\", label = \"Training loss\", color = 'red')\nax2.plot(epochs, val_loss, \"b\", label = \"Validation loss\", color = 'red')\nax2.set_title(\"Training and validation loss\")\nax2.legend()\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Prediction"},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"submission_file = pd.read_csv(os.path.join(INPUT_PATH, 'sample_submission.csv'))\nsubmission_file.label = submission_file.label.astype('str')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"\nsaved_model = load_model(file_path)\ntest_folder = os.path.join(INPUT_PATH, 'test_images/')\n\nfor image_name in submission_file['image_id']:\n    img = image.load_img(os.path.join(INPUT_PATH,'test_images/',image_name))\n    img = img.resize((TARGET_SIZE, TARGET_SIZE))\n    img = np.asarray(img)\n    plt.imshow(img)\n    predictions = predict_with_tta(image_name, test_folder, saved_model)\n    print(\"Predicted Label: \", predictions[0])\n    print(\"Predicted Label Value: \", predictions[1])\n    print(\"Predicted One-Hot Label: \", predictions[2])\n    \n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Submission"},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"predictions_list = predict_image_list(submission_file['image_id'], test_folder, saved_model)\nsample_submission = submission_file\nsample_submission['label'] = predictions_list[0]\nsample_submission.to_csv('submission.csv')","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}