{"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":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-05-27T17:17:41.226049Z","iopub.execute_input":"2021-05-27T17:17:41.226434Z","iopub.status.idle":"2021-05-27T17:18:25.534673Z","shell.execute_reply.started":"2021-05-27T17:17:41.226336Z","shell.execute_reply":"2021-05-27T17:18:25.533763Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Plant Pathology 2020-FGVC7 challenge competition had a pilot dataset of 3,651 RGB images of foliar disease of apples. For Plant Pathology 2021-FGVC8, we have significantly increased the number of foliar disease images and added additional disease categories. This year’s dataset contains approximately 18,632 (trainset) high-quality RGB images of apple foliar diseases, including a large expert-annotated disease dataset. This dataset reflects real field scenarios by representing non-homogeneous backgrounds of leaf images taken at different maturity stages and at different times of day under different focal camera settings.","metadata":{}},{"cell_type":"code","source":"# to prevent unnecessary warnings\nimport warnings\nwarnings.simplefilter(action='ignore', category=FutureWarning)\n\n# TensorFlow and tf.keras\nimport tensorflow as tf\n\nfrom pathlib import Path\n\n#import useful module for keras library\nfrom tensorflow import keras\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D, BatchNormalization\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.losses import CategoricalCrossentropy\nfrom keras.preprocessing.image import ImageDataGenerator\n\n# get modules from sklearn library\nfrom sklearn.preprocessing import StandardScaler \nfrom sklearn.model_selection import train_test_split \nfrom sklearn.metrics import classification_report \n\n#import libraries\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport random\n\n#computer vision library\nimport cv2","metadata":{"execution":{"iopub.status.busy":"2021-05-27T17:18:25.537538Z","iopub.execute_input":"2021-05-27T17:18:25.537945Z","iopub.status.idle":"2021-05-27T17:18:33.422703Z","shell.execute_reply.started":"2021-05-27T17:18:25.537904Z","shell.execute_reply":"2021-05-27T17:18:33.421618Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Load the image Dataset**","metadata":{}},{"cell_type":"code","source":"#read the data with pandas read csv\nfolia_data = pd.read_csv(\"../input/plant-pathology-2021-fgvc8/train.csv\")\n\n#view the first 4 rows of the dataset in a table\nfolia_data.head()","metadata":{"execution":{"iopub.status.busy":"2021-05-27T17:18:33.425165Z","iopub.execute_input":"2021-05-27T17:18:33.425581Z","iopub.status.idle":"2021-05-27T17:18:33.502941Z","shell.execute_reply.started":"2021-05-27T17:18:33.425550Z","shell.execute_reply":"2021-05-27T17:18:33.501897Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#get shape of dataset\nfolia_data.shape","metadata":{"execution":{"iopub.status.busy":"2021-05-27T17:18:33.505115Z","iopub.execute_input":"2021-05-27T17:18:33.505583Z","iopub.status.idle":"2021-05-27T17:18:33.512338Z","shell.execute_reply.started":"2021-05-27T17:18:33.505539Z","shell.execute_reply":"2021-05-27T17:18:33.511179Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"folia_data.info()","metadata":{"execution":{"iopub.status.busy":"2021-05-27T17:18:33.514283Z","iopub.execute_input":"2021-05-27T17:18:33.515120Z","iopub.status.idle":"2021-05-27T17:18:33.538135Z","shell.execute_reply.started":"2021-05-27T17:18:33.515061Z","shell.execute_reply":"2021-05-27T17:18:33.536627Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Visu","metadata":{}},{"cell_type":"code","source":"folia_data['labels'].unique()","metadata":{"execution":{"iopub.status.busy":"2021-05-27T17:18:33.540275Z","iopub.execute_input":"2021-05-27T17:18:33.540802Z","iopub.status.idle":"2021-05-27T17:18:33.552387Z","shell.execute_reply.started":"2021-05-27T17:18:33.540699Z","shell.execute_reply":"2021-05-27T17:18:33.550951Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#get the counts of the labels\nfolia_data['labels'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2021-05-27T17:18:33.554291Z","iopub.execute_input":"2021-05-27T17:18:33.554882Z","iopub.status.idle":"2021-05-27T17:18:33.569717Z","shell.execute_reply.started":"2021-05-27T17:18:33.554807Z","shell.execute_reply":"2021-05-27T17:18:33.568538Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#visualize\nplt.figure(figsize = (10,5))\n\nplt.xticks(rotation = 90, fontsize = 7)\nsns.countplot(folia_data['labels'])","metadata":{"execution":{"iopub.status.busy":"2021-05-27T17:18:33.574301Z","iopub.execute_input":"2021-05-27T17:18:33.575184Z","iopub.status.idle":"2021-05-27T17:18:33.879377Z","shell.execute_reply.started":"2021-05-27T17:18:33.575139Z","shell.execute_reply":"2021-05-27T17:18:33.877959Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# create a function to visualize the images\ndef visualize_batch(path,image_ids, labels):\n    plt.figure(figsize=(18, 12))\n    \n    for ind, (image_id, label) in enumerate(zip(image_ids, labels)):\n        plt.subplot(5, 3, ind + 1)\n        image = cv2.imread(os.path.join(path, image_id))\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n\n        plt.imshow(image)\n        plt.title(f\"Class: {label}\", fontsize = 8)\n        plt.axis(\"off\")\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2021-05-27T17:18:33.882403Z","iopub.execute_input":"2021-05-27T17:18:33.882911Z","iopub.status.idle":"2021-05-27T17:18:33.890908Z","shell.execute_reply.started":"2021-05-27T17:18:33.882867Z","shell.execute_reply":"2021-05-27T17:18:33.889600Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_path = '../input/plant-pathology-2021-fgvc8/train_images' # the file path for only images\n\ntmp_df = folia_data.sample(15)\nimage_ids = tmp_df[\"image\"].values #the id for the image in the dataframe\nlabels = tmp_df[\"labels\"].values #the labels for the image in the dataframe\n\n# call the function to visualize the 15 images from the dataset\nvisualize_batch(image_path,image_ids,labels)","metadata":{"execution":{"iopub.status.busy":"2021-05-27T17:18:33.892984Z","iopub.execute_input":"2021-05-27T17:18:33.893482Z","iopub.status.idle":"2021-05-27T17:18:48.645056Z","shell.execute_reply.started":"2021-05-27T17:18:33.893439Z","shell.execute_reply":"2021-05-27T17:18:48.644067Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#label = healthy\n\nth_df = folia_data[folia_data[\"labels\"] == 'healthy']\n\n\nth_df = th_df.sample(9)\nimage_ids = th_df[\"image\"].values\nlabels = th_df[\"labels\"].values\n\nvisualize_batch(image_path, image_ids, labels)","metadata":{"execution":{"iopub.status.busy":"2021-05-27T17:18:48.646635Z","iopub.execute_input":"2021-05-27T17:18:48.647285Z","iopub.status.idle":"2021-05-27T17:18:57.810536Z","shell.execute_reply.started":"2021-05-27T17:18:48.647243Z","shell.execute_reply":"2021-05-27T17:18:57.809466Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#label = complex\n\ntmc_df = folia_data[folia_data[\"labels\"] == 'complex']\n\n\ntmc_df = tmc_df.sample(9)\nimage_ids = tmc_df[\"image\"].values\nlabels = tmc_df[\"labels\"].values\n\nvisualize_batch(image_path, image_ids, labels)","metadata":{"execution":{"iopub.status.busy":"2021-05-27T17:18:57.812456Z","iopub.execute_input":"2021-05-27T17:18:57.813144Z","iopub.status.idle":"2021-05-27T17:19:06.512094Z","shell.execute_reply.started":"2021-05-27T17:18:57.813098Z","shell.execute_reply":"2021-05-27T17:19:06.510832Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#label = rust\n\ntmr_df = folia_data[folia_data[\"labels\"] == 'rust']\n\n\ntmr_df = tmr_df.sample(9)\nimage_ids = tmr_df[\"image\"].values\nlabels = tmr_df[\"labels\"].values\n\nvisualize_batch(image_path, image_ids, labels)","metadata":{"execution":{"iopub.status.busy":"2021-05-27T17:19:06.513968Z","iopub.execute_input":"2021-05-27T17:19:06.514374Z","iopub.status.idle":"2021-05-27T17:19:11.857206Z","shell.execute_reply.started":"2021-05-27T17:19:06.514333Z","shell.execute_reply":"2021-05-27T17:19:11.855873Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#label = scab\n\ntms_df = folia_data[folia_data[\"labels\"] == 'scab']\n\n\ntms_df = tms_df.sample(9)\nimage_ids = tms_df[\"image\"].values\nlabels = tms_df[\"labels\"].values\n\nvisualize_batch(image_path, image_ids, labels)","metadata":{"execution":{"iopub.status.busy":"2021-05-27T17:19:11.858988Z","iopub.execute_input":"2021-05-27T17:19:11.859411Z","iopub.status.idle":"2021-05-27T17:19:20.011250Z","shell.execute_reply.started":"2021-05-27T17:19:11.859361Z","shell.execute_reply":"2021-05-27T17:19:20.009922Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#label = powdery_mildew\n\ntpm_df = folia_data[folia_data[\"labels\"] == 'powdery_mildew']\n\n\ntpm_df = tpm_df.sample(9)\nimage_ids = tpm_df[\"image\"].values\nlabels = tpm_df[\"labels\"].values\n\nvisualize_batch(image_path, image_ids, labels)","metadata":{"execution":{"iopub.status.busy":"2021-05-27T17:19:20.013105Z","iopub.execute_input":"2021-05-27T17:19:20.013559Z","iopub.status.idle":"2021-05-27T17:19:28.817231Z","shell.execute_reply.started":"2021-05-27T17:19:20.013513Z","shell.execute_reply":"2021-05-27T17:19:28.815972Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# label = frog_eye_leaf_spot\n\ntfe_df = folia_data[folia_data[\"labels\"] == 'frog_eye_leaf_spot']\n\n\ntfe_df = tfe_df.sample(9)\nimage_ids = tfe_df[\"image\"].values\nlabels = tfe_df[\"labels\"].values\n\nvisualize_batch(image_path, image_ids, labels)","metadata":{"execution":{"iopub.status.busy":"2021-05-27T17:19:28.819041Z","iopub.execute_input":"2021-05-27T17:19:28.819500Z","iopub.status.idle":"2021-05-27T17:19:38.091181Z","shell.execute_reply.started":"2021-05-27T17:19:28.819459Z","shell.execute_reply":"2021-05-27T17:19:38.089845Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### The labels counts shows that there are 12 different classes .\n**In actuality there are 6 labels, 5 diseases and 1 healthy case.**\n\n 1.rust\n \n 2.scab\n \n 3.complex\n \n 4.frog eye leaf spot\n \n 5.powdery mildew\n\nand another label is\n\n6.healthy (healthy leaves)\n\n**But there are cases where an image contains one or more diseases, that means this problem is Multi label classification problem.**\n\n**And then lets find out the actual frequencies of the labels.**\n\nWe divide it based on \" \" or space character , in order to get the labels for each of the image\n\n","metadata":{}},{"cell_type":"code","source":"folia_df = folia_data.copy() # create a copy of the original data set\n\nfolia_df['labels'] = folia_df['labels'].apply(lambda string: string.split(' '))\n# this kind of separates the compound names that we thought were initially unique into the separate diseases classes\nfolia_df","metadata":{"execution":{"iopub.status.busy":"2021-05-27T17:19:38.093137Z","iopub.execute_input":"2021-05-27T17:19:38.093541Z","iopub.status.idle":"2021-05-27T17:19:38.356281Z","shell.execute_reply.started":"2021-05-27T17:19:38.093502Z","shell.execute_reply":"2021-05-27T17:19:38.354918Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### We can check the label for image two and understand what has taken place. If you check the label it has previously, you will see that it was 'scab frog_eye_leaf_spot complex' which made the label think it was another disease.\n#### But applying lamda separated the diseases in the label to [scab, frog_eye_leaf_spot, complex]","metadata":{}},{"cell_type":"code","source":"# using the multilabel binarizer from sklearn\nfrom sklearn.preprocessing import MultiLabelBinarizer\n\nf = list(folia_df['labels'])\nmlb = MultiLabelBinarizer()\ndf = pd.DataFrame(mlb.fit_transform(f), columns = mlb.classes_, index = folia_df.index)\nprint(df.columns)","metadata":{"execution":{"iopub.status.busy":"2021-05-27T17:19:38.358209Z","iopub.execute_input":"2021-05-27T17:19:38.358665Z","iopub.status.idle":"2021-05-27T17:19:38.392479Z","shell.execute_reply.started":"2021-05-27T17:19:38.358605Z","shell.execute_reply":"2021-05-27T17:19:38.390985Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.sum()","metadata":{"execution":{"iopub.status.busy":"2021-05-27T17:19:38.394786Z","iopub.execute_input":"2021-05-27T17:19:38.395338Z","iopub.status.idle":"2021-05-27T17:19:38.406098Z","shell.execute_reply.started":"2021-05-27T17:19:38.395292Z","shell.execute_reply":"2021-05-27T17:19:38.404809Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = list(df.sum().keys())\n#print(labels)\nlabel_counts = df.sum().values.tolist()\n\nfig, ax = plt.subplots(1,1, figsize=(14,6))\n\nsns.barplot(x= labels, y= label_counts, ax=ax)","metadata":{"execution":{"iopub.status.busy":"2021-05-27T17:19:38.408008Z","iopub.execute_input":"2021-05-27T17:19:38.408605Z","iopub.status.idle":"2021-05-27T17:19:38.601675Z","shell.execute_reply.started":"2021-05-27T17:19:38.408545Z","shell.execute_reply":"2021-05-27T17:19:38.600309Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Splitiing the dataset","metadata":{}},{"cell_type":"code","source":"# There is a different dataset for testing,\n#we split the train dataset into train and validation set\n\ntrain_set, val_set = train_test_split(folia_df, test_size = 0.2, random_state = 42)\n\nprint(train_set.shape)\nprint(val_set.shape)","metadata":{"execution":{"iopub.status.busy":"2021-05-27T17:19:38.603696Z","iopub.execute_input":"2021-05-27T17:19:38.604204Z","iopub.status.idle":"2021-05-27T17:19:38.617316Z","shell.execute_reply.started":"2021-05-27T17:19:38.604157Z","shell.execute_reply":"2021-05-27T17:19:38.615847Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Image Generator Preprocessing","metadata":{}},{"cell_type":"code","source":"img_gen = ImageDataGenerator(preprocessing_function = tf.keras.applications.mobilenet_v2.preprocess_input, \n                             rescale=1/255, zoom_range = 0.2,\n                                rotation_range = 20,\n                                width_shift_range = 0.2,\n                                height_shift_range = 0.2,\n                                horizontal_flip = True)\n\n# img_gen cannot take in an array, so ensure the data that is been passed is a dataframe\ntrain = img_gen.flow_from_dataframe(dataframe = train_set,\n    directory = '../input/plant-pathology-2021-fgvc8/train_images' ,  # the path contaning the images                                 \n    x_col = 'image', #name of the column containing the image in the train set\n    y_col ='labels', #name of column containing the target in the train set\n    target_size = (224, 224),\n    color_mode = 'rgb',\n    class_mode = 'categorical',#the class mode here and that for the model_loss(when using sequential model)\n                                    #should be the same\n    batch_size = 32,\n    shuffle = False #not to shuffle the given data\n)\n\nval = img_gen.flow_from_dataframe(dataframe = val_set,\n    directory = '../input/plant-pathology-2021-fgvc8/train_images' ,   # the path conataining the images                          \n    x_col = 'image', #name of the column containing the image in the test set\n    y_col ='labels', #name of column containing the target in the test set\n    target_size =(224, 224),\n    color_mode ='rgb',\n    class_mode ='categorical',\n    batch_size = 32,\n    shuffle = False # not to shuffle the given data\n)","metadata":{"execution":{"iopub.status.busy":"2021-05-27T17:19:38.619180Z","iopub.execute_input":"2021-05-27T17:19:38.619711Z","iopub.status.idle":"2021-05-27T17:19:49.588411Z","shell.execute_reply.started":"2021-05-27T17:19:38.619666Z","shell.execute_reply":"2021-05-27T17:19:49.587299Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Building the Sequential Convolution model ","metadata":{}},{"cell_type":"code","source":"# define sequential model\nmodel = tf.keras.models.Sequential()\n# define conv-pool layers - set 1\nmodel.add(tf.keras.layers.Conv2D(filters = 32, kernel_size=(3, 3), strides=(1, 1), \n                                activation='relu', padding='valid', input_shape = (224, 224, 3)))\nmodel.add(BatchNormalization(axis=3))\nmodel.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))\n\n\n# define conv-pool layers - set 2\nmodel.add(tf.keras.layers.Conv2D(filters = 16, kernel_size=(3, 3), strides=(1, 1), \n                                activation='relu', padding='valid'))\nmodel.add(BatchNormalization(axis=3))\nmodel.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))\n\n# define conv-pool layers - set 3\nmodel.add(tf.keras.layers.Conv2D(filters = 16, kernel_size=(3, 3), strides=(1, 1), \n                                activation='relu', padding='valid'))\nmodel.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))\n\n# add flatten layer\nmodel.add(tf.keras.layers.Flatten())\n\n# add dense layers with some dropout\nmodel.add(tf.keras.layers.Dense(128, activation='relu'))\nmodel.add(tf.keras.layers.Dropout(rate = 0.3))\nmodel.add(tf.keras.layers.Dense(64, activation='relu'))\n\nmodel.add(tf.keras.layers.Dense(16, activation='relu'))\n\n# add output layer\nmodel.add(tf.keras.layers.Dense(6, activation='softmax')) #use softmax as activation in the output layer\n#for multiclass. Sigmoid activation is used for binary and 'relu' shouldnt be use for output layer\n\n\n# view model layers\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2021-05-27T17:19:49.594367Z","iopub.execute_input":"2021-05-27T17:19:49.594700Z","iopub.status.idle":"2021-05-27T17:19:52.135902Z","shell.execute_reply.started":"2021-05-27T17:19:49.594669Z","shell.execute_reply":"2021-05-27T17:19:52.134640Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#import modules that will wnable early stopping for optimization during model training\nfrom tensorflow.keras.callbacks import TensorBoard, EarlyStopping\nfrom datetime import datetime\n\n#tensorboard\nlogdir = \"logs/\" + datetime.now().strftime(\"%Y%m%d-%H%M%S\")\ntensorboard_callback = TensorBoard(log_dir=logdir)\n\n#define the early stopping\nes = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=5)","metadata":{"execution":{"iopub.status.busy":"2021-05-27T17:19:52.138226Z","iopub.execute_input":"2021-05-27T17:19:52.138665Z","iopub.status.idle":"2021-05-27T17:19:52.439658Z","shell.execute_reply.started":"2021-05-27T17:19:52.138620Z","shell.execute_reply":"2021-05-27T17:19:52.438235Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# compile model\nmodel.compile(optimizer='adam', # optimize the model with adam optimizer\n              loss=\"categorical_crossentropy\", \n              metrics=['accuracy']) #to get accuracy of the model in each run","metadata":{"execution":{"iopub.status.busy":"2021-05-27T17:19:52.441569Z","iopub.execute_input":"2021-05-27T17:19:52.442075Z","iopub.status.idle":"2021-05-27T17:19:52.467522Z","shell.execute_reply.started":"2021-05-27T17:19:52.442011Z","shell.execute_reply":"2021-05-27T17:19:52.466278Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#fit the model on train data and add val data fro validation\nhistory = model.fit(train,\n    batch_size = 32,\n    verbose = 1, # Suppress chatty output; use Tensorboard instead\n    epochs = 25,\n    validation_data = val, #add the validation set to evaluate the performance in each run\n    callbacks = [tensorboard_callback, es],\n)\n","metadata":{"execution":{"iopub.status.busy":"2021-05-27T17:19:52.469270Z","iopub.execute_input":"2021-05-27T17:19:52.469935Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# cnn_model.save('model-cnn.folia')\nmodel.save('model.folia')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"acc = history.history['accuracy'] # get history report of the model\n\nval_acc = history.history['val_accuracy'] # get history of the validation set\n\nloss = history.history['loss'] #get the history of the lossses recorded on the train set\nval_loss = history.history['val_loss'] #get the history of the lossses recorded on the validation set\n\nplt.figure(figsize=(8, 8)) # set figure size for the plot generated\nplt.subplot(2, 1, 1) \n\nplt.plot(acc, label='Training Accuracy') #plot accuracy curve for each train run\nplt.plot(val_acc, label='Validation Accuracy') #plot accuracy curve for each validation run\n\nplt.legend(loc='lower right')\nplt.ylabel('Accuracy') #label name for y axis\nplt.ylim([min(plt.ylim()),1]) #set limit for y axis\nplt.title('Training and Validation Accuracy') #set title for the plot","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(8, 8)) # set figure size for the plot generated\nplt.subplot(2, 1, 1) \n\nplt.plot(loss, label='Training Loss') #plot loss curve for each train run\nplt.plot(val_loss, label='Validation Loss') #plot loss curve for each validation run\n\nplt.legend(loc='lower right')\nplt.ylabel('Loss') #label name for y axis\nplt.ylim([min(plt.ylim()),1]) #set limit for y axis\nplt.title('Training and Validation Loss') #set title for the plot","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Prediction","metadata":{}},{"cell_type":"code","source":"#get the testing data\ntest_path = \"../input/plant-pathology-2021-fgvc8/sample_submission.csv\"\ntest_set = pd.read_csv(test_path)\ntest_set","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"imgen = ImageDataGenerator(preprocessing_function = tf.keras.applications.mobilenet_v2.preprocess_input, \n                             rescale=1/255 )\n\n# img_gen cannot take in an array, so ensure the data that is been passed is a dataframe\ntrain = imgen.flow_from_dataframe(dataframe = test_set,\n    directory = '../input/plant-pathology-2021-fgvc8/test_images' ,  # the path contaning the images                                 \n    x_col = 'image', #name of the column containing the image in the train set\n    y_col ='labels', #name of column containing the target in the train set\n    target_size = (224, 224),\n    color_mode = 'rgb',\n    class_mode = 'categorical',#the class mode here and that for the model_loss(when using sequential model)\n                                    #should be the same\n    batch_size = 32,\n    shuffle = False #not to shuffle the given data\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds = model.predict(test)\n\npreds = preds.tolist()\nindices = []\nfor pred in preds:\n    temp = []\n    for category in pred:\n        if category>=0.23:\n            temp.append(pred.index(category))\n    if temp!=[]:\n        indices.append(temp)\n    else:\n        temp.append(np.argmax(pred))\n        indices.append(temp)\n    ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = (train.class_indices)\nlabels = dict((v,k) for k,v in labels.items())\nprint(labels)\n\ntestlabels = []\nfor image in indices:\n    temp = []\n    for i in image:\n        temp.append(str(labels[i]))\n    testlabels.append(' '.join(temp))\nprint(testlabels)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission['labels'] = testlabels\nsubmission.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission.to_csv('submission.csv', index=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}