{"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":"## Plant Pathology 2021 - FGVC8\n#### Identify the category of foliar diseases in apple trees","metadata":{}},{"cell_type":"markdown","source":"Apples are one of the most important temperate fruit crops in the world. Foliar (leaf) diseases pose a major threat to the overall productivity and quality of apple orchards. The current process for disease diagnosis in apple orchards is based on manual scouting by humans, which is time-consuming and expensive.\n\nAlthough computer vision-based models have shown promise for plant disease identification, there are some limitations that need to be addressed. Large variations in visual symptoms of a single disease across different apple cultivars, or new varieties that originated under cultivation, are major challenges for computer vision-based disease identification. These variations arise from differences in natural and image capturing environments, for example, leaf color and leaf morphology, the age of infected tissues, non-uniform image background, and different light illumination during imaging etc.","metadata":{}},{"cell_type":"markdown","source":"#### Importing libraries","metadata":{}},{"cell_type":"code","source":"import numpy as np \nimport pandas as pd\nfrom pathlib import Path\nimport os.path\nimport matplotlib.pyplot as plt\n%matplotlib inline\nimport seaborn as sns\nimport os\nimport cv2","metadata":{"execution":{"iopub.status.busy":"2021-05-30T22:38:19.712562Z","iopub.execute_input":"2021-05-30T22:38:19.712924Z","iopub.status.idle":"2021-05-30T22:38:19.721712Z","shell.execute_reply.started":"2021-05-30T22:38:19.712886Z","shell.execute_reply":"2021-05-30T22:38:19.72051Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from cycler import cycler\nimport matplotlib as mpl\n\nraw_light_palette = [\n    (0, 122, 255), # Blue\n    (255, 149, 0), # Orange\n    (52, 199, 89), # Green\n    (255, 59, 48), # Red\n    (175, 82, 222),# Purple\n    (255, 45, 85), # Pink\n    (88, 86, 214), # Indigo\n    (90, 200, 250),# Teal\n    (255, 204, 0)  # Yellow\n]\nraw_dark_palette = [\n    (10, 132, 255), # Blue\n    (255, 159, 10), # Orange\n    (48, 209, 88),  # Green\n    (255, 69, 58),  # Red\n    (191, 90, 242), # Purple\n    (94, 92, 230),  # Indigo\n    (255, 55, 95),  # Pink\n    (100, 210, 255),# Teal\n    (255, 214, 10)  # Yellow\n]\nraw_gray_light_palette = [\n    (142, 142, 147),# Gray\n    (174, 174, 178),# Gray (2)\n    (199, 199, 204),# Gray (3)\n    (209, 209, 214),# Gray (4)\n    (229, 229, 234),# Gray (5)\n    (242, 242, 247),# Gray (6)\n]\nraw_gray_dark_palette = [\n    (142, 142, 147),# Gray\n    (99, 99, 102),  # Gray (2)\n    (72, 72, 74),   # Gray (3)\n    (58, 58, 60),   # Gray (4)\n    (44, 44, 46),   # Gray (5)\n    (28, 28, 39),   # Gray (6)\n]\n\nlight_palette = np.array(raw_light_palette)/255\ndark_palette = np.array(raw_dark_palette)/255\ngray_light_palette = np.array(raw_gray_light_palette)/255\ngray_dark_palette = np.array(raw_gray_dark_palette)/255\n\nmpl.rcParams['axes.prop_cycle'] = cycler('color',dark_palette)\nmpl.rcParams['figure.facecolor']  = gray_dark_palette[-2]\nmpl.rcParams['figure.edgecolor']  = gray_dark_palette[-2]\nmpl.rcParams['axes.facecolor'] =  gray_dark_palette[-2]\n\nwhite_color = gray_light_palette[-2]\nmpl.rcParams['text.color'] = white_color\nmpl.rcParams['axes.labelcolor'] = white_color\nmpl.rcParams['axes.edgecolor'] = white_color\nmpl.rcParams['xtick.color'] = white_color\nmpl.rcParams['ytick.color'] = white_color\n\nmpl.rcParams['figure.dpi'] = 200\nmpl.rcParams['axes.spines.top'] = False\nmpl.rcParams['axes.spines.right'] = False","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-05-30T22:38:19.811779Z","iopub.execute_input":"2021-05-30T22:38:19.812083Z","iopub.status.idle":"2021-05-30T22:38:19.826743Z","shell.execute_reply.started":"2021-05-30T22:38:19.812055Z","shell.execute_reply":"2021-05-30T22:38:19.825663Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create a list with the filepaths for training and testing\ntrain_img_Path = '../input/plant-pathology-2021-fgvc8/train_images'\n\ntest_img_Path = '../input/plant-pathology-2021-fgvc8/test_images'\n\nimg_Path = '../input/resized-plant2021/img_sz_256'\n\ntrain = pd.read_csv(r'../input/plant-pathology-2021-fgvc8/train.csv')\n\nsample_submission = pd.read_csv(r'../input/plant-pathology-2021-fgvc8/sample_submission.csv')","metadata":{"execution":{"iopub.status.busy":"2021-05-30T22:38:19.847234Z","iopub.execute_input":"2021-05-30T22:38:19.847556Z","iopub.status.idle":"2021-05-30T22:38:19.87482Z","shell.execute_reply.started":"2021-05-30T22:38:19.847528Z","shell.execute_reply":"2021-05-30T22:38:19.8741Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.head()","metadata":{"execution":{"iopub.status.busy":"2021-05-30T22:38:19.897882Z","iopub.execute_input":"2021-05-30T22:38:19.898121Z","iopub.status.idle":"2021-05-30T22:38:19.910258Z","shell.execute_reply.started":"2021-05-30T22:38:19.898098Z","shell.execute_reply":"2021-05-30T22:38:19.909512Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f'Number of pictures in the training dataset: {train.shape[0]}\\n')\nprint(f'Number of different labels: {len(train.labels.unique())}\\n')\nprint(f'Labels: {train.labels.unique()}')","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-05-30T22:38:20.010353Z","iopub.execute_input":"2021-05-30T22:38:20.010588Z","iopub.status.idle":"2021-05-30T22:38:20.018971Z","shell.execute_reply.started":"2021-05-30T22:38:20.010565Z","shell.execute_reply":"2021-05-30T22:38:20.01796Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train['labels'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2021-05-30T22:38:20.057535Z","iopub.execute_input":"2021-05-30T22:38:20.05778Z","iopub.status.idle":"2021-05-30T22:38:20.06826Z","shell.execute_reply.started":"2021-05-30T22:38:20.057756Z","shell.execute_reply":"2021-05-30T22:38:20.067253Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(14,7))\nb = sns.countplot(x='labels', data=train, order=sorted(train['labels'].unique()))\nfor item in b.get_xticklabels():\n    item.set_rotation(90)\nplt.title('Label Distribution', weight='bold')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-05-30T22:38:20.102559Z","iopub.execute_input":"2021-05-30T22:38:20.102793Z","iopub.status.idle":"2021-05-30T22:38:20.507955Z","shell.execute_reply.started":"2021-05-30T22:38:20.10277Z","shell.execute_reply":"2021-05-30T22:38:20.507026Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(20,40))\ni=1\nfor idx,s in train.head(9).iterrows():\n    img_path = os.path.join(img_Path,s['image'])\n    img=cv2.imread(img_path)\n    img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)\n    fig=plt.subplot(9,3,i)\n    fig.imshow(img)\n    fig.set_title(s['labels'])\n    i+=1","metadata":{"execution":{"iopub.status.busy":"2021-05-30T22:38:20.509549Z","iopub.execute_input":"2021-05-30T22:38:20.50991Z","iopub.status.idle":"2021-05-30T22:38:22.815285Z","shell.execute_reply.started":"2021-05-30T22:38:20.509874Z","shell.execute_reply":"2021-05-30T22:38:22.81451Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"CLASSES = train['labels'].unique().tolist()","metadata":{"execution":{"iopub.status.busy":"2021-05-30T22:38:22.817074Z","iopub.execute_input":"2021-05-30T22:38:22.817661Z","iopub.status.idle":"2021-05-30T22:38:22.824626Z","shell.execute_reply.started":"2021-05-30T22:38:22.817621Z","shell.execute_reply":"2021-05-30T22:38:22.823748Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n\n\n# Preprocessing the Training set\ntrain_datagen = ImageDataGenerator(#rescale=1./255,\n                                   shear_range = 0.1,\n                                   zoom_range = 0.1,\n                                   horizontal_flip = True,\n                                   validation_split=0.35)\n\ntrain_data = train_datagen.flow_from_dataframe(train,\n                                              directory=img_Path,\n                                              classes=CLASSES,\n                                              x_col=\"image\",\n                                              y_col=\"labels\",\n                                              target_size=(150, 150),\n                                              subset='training')\n\nval_data = train_datagen.flow_from_dataframe(train,\n                                            directory=img_Path,\n                                            classes=CLASSES,\n                                            x_col=\"image\",\n                                            y_col=\"labels\",\n                                            target_size=(150, 150),\n                                            subset='validation')","metadata":{"execution":{"iopub.status.busy":"2021-05-30T22:38:22.826473Z","iopub.execute_input":"2021-05-30T22:38:22.826992Z","iopub.status.idle":"2021-05-30T22:38:29.94053Z","shell.execute_reply.started":"2021-05-30T22:38:22.826956Z","shell.execute_reply":"2021-05-30T22:38:29.939503Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dict_classes = train_data.class_indices\ndict_classes","metadata":{"execution":{"iopub.status.busy":"2021-05-30T22:38:29.941783Z","iopub.execute_input":"2021-05-30T22:38:29.942205Z","iopub.status.idle":"2021-05-30T22:38:29.949122Z","shell.execute_reply.started":"2021-05-30T22:38:29.942166Z","shell.execute_reply":"2021-05-30T22:38:29.947924Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow import keras\nfrom keras import Sequential\nfrom keras.applications import InceptionResNetV2, DenseNet169, ResNet152V2\nfrom tensorflow.keras.applications.vgg16 import VGG16\nfrom tensorflow.keras.layers import Dense","metadata":{"execution":{"iopub.status.busy":"2021-05-30T22:38:29.950745Z","iopub.execute_input":"2021-05-30T22:38:29.951259Z","iopub.status.idle":"2021-05-30T22:38:29.960269Z","shell.execute_reply.started":"2021-05-30T22:38:29.951219Z","shell.execute_reply":"2021-05-30T22:38:29.959327Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base_VGG = VGG16(include_top = False, \n                         weights = 'imagenet', \n                         input_shape = train_data.image_shape, \n                         pooling='avg',\n                         classes = CLASSES)\n\n#Adding the final layers to the above base models where the actual classification is done in the dense layers\nmodel_VGG = Sequential()\nmodel_VGG.add(base_VGG)\nmodel_VGG.add(Dense(12, activation=('softmax')))\nmodel_VGG.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy'])\nmodel_VGG.summary()\n\n# Training the CNN on the Train data and evaluating it on the val data\nb = model_VGG.fit(train_data, validation_data = val_data, epochs = 10, batch_size=264)\n","metadata":{"execution":{"iopub.status.busy":"2021-05-30T22:38:29.961471Z","iopub.execute_input":"2021-05-30T22:38:29.961862Z","iopub.status.idle":"2021-05-30T22:45:29.089977Z","shell.execute_reply.started":"2021-05-30T22:38:29.961816Z","shell.execute_reply":"2021-05-30T22:45:29.087383Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"* I am using the ResNet152V2, InceptionResNetV2, DenseNet169.","metadata":{}},{"cell_type":"markdown","source":"#### Defining the ResNet152V2 Convolutional Neural Net:","metadata":{}},{"cell_type":"code","source":"base_Net = ResNet152V2(include_top = False, \n                         weights = 'imagenet', \n                         input_shape = train_data.image_shape, \n                         pooling='avg',\n                         classes = CLASSES)\n","metadata":{"execution":{"iopub.status.busy":"2021-05-30T22:45:29.090753Z","iopub.status.idle":"2021-05-30T22:45:29.091138Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Adding the final layers to the above base models where the actual classification is done in the dense layers\nfrom keras.layers import Dropout\nmodel_Net = Sequential()\nmodel_Net.add(base_Net)\nmodel_Net.add(Dense(12, activation=('softmax')))\n#model_Net.add(Dropout(0.02))\nmodel_Net.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy'])\nmodel_Net.summary()\n\n# Training the CNN on the Train data and evaluating it on the val data\nb = model_Net.fit(train_data, validation_data = val_data, epochs = 40, batch_size=264)","metadata":{"_kg_hide-output":false,"execution":{"iopub.status.busy":"2021-05-30T22:45:29.092161Z","iopub.status.idle":"2021-05-30T22:45:29.092625Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Defining the InceptionResNetV2 Convolutional Neural Net:","metadata":{}},{"cell_type":"code","source":"base_InceptionResNetV2 = InceptionResNetV2(include_top = False, \n                         weights = '../input/keras-pretrained-models/InceptionResNetV2_NoTop_ImageNet.h5', \n                         input_shape = train_data.image_shape, \n                         pooling='avg',\n                         classes = CLASSES)","metadata":{"execution":{"iopub.status.busy":"2021-05-30T22:45:29.093518Z","iopub.status.idle":"2021-05-30T22:45:29.094053Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Adding the final layers to the above base models where the actual classification is done in the dense layers\nmodel_IResNet2 = Sequential()\nmodel_IResNet2.add(base_InceptionResNetV2)\nmodel_IResNet2.add(Dense(12, activation=('softmax')))\nmodel_IResNet2.add(Dropout(0.5))\nmodel_IResNet2.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy'])\nmodel_IResNet2.summary()\n\n# Training the CNN on the Train data and evaluating it on the val data\nc = model_IResNet2.fit(train_data, validation_data = val_data, epochs = 20, batch_size=400)","metadata":{"execution":{"iopub.status.busy":"2021-05-30T22:45:29.095091Z","iopub.status.idle":"2021-05-30T22:45:29.095692Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Defining the DenseNet169 Convolutional Neural Net:","metadata":{}},{"cell_type":"code","source":"base_DenseNet169 = DenseNet169(include_top = False, \n                         weights = '../input/keras-pretrained-models/DenseNet169_NoTop_ImageNet.h5', \n                         input_shape = train_data.image_shape, \n                         pooling='avg',\n                         classes = CLASSES)","metadata":{"execution":{"iopub.status.busy":"2021-05-30T22:45:29.09693Z","iopub.status.idle":"2021-05-30T22:45:29.097531Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Adding the final layers to the above base models where the actual classification is done in the dense layers\nmodel_dense = Sequential()\nmodel_dense.add(base_DenseNet169)\nmodel_dense.add(Dense(12, activation=('softmax')))\nmodel_dense.add(Dropout(0.5))\nmodel_dense.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy'])\nmodel_dense.summary()\n\n# Training the CNN on the Train data and evaluating it on the val data\nd = model_dense.fit(train_data, validation_data = val_data, epochs = 20, batch_size=400)","metadata":{"execution":{"iopub.status.busy":"2021-05-30T22:45:29.098605Z","iopub.status.idle":"2021-05-30T22:45:29.0992Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_dir = '/kaggle/input/plant-pathology-2021-fgvc8/test_images/'\ntest_df = pd.DataFrame()\ntest_df['image'] = os.listdir(test_dir)\n\ntest_data = train_datagen.flow_from_dataframe(dataframe=test_df,\n                                    directory=test_dir,\n                                    x_col=\"image\",\n                                    y_col=None,\n                                    batch_size=32,\n                                    seed=42,\n                                    shuffle=False,\n                                    class_mode=None,\n                                    target_size=(150, 150))","metadata":{"execution":{"iopub.status.busy":"2021-05-30T22:45:29.100278Z","iopub.status.idle":"2021-05-30T22:45:29.100912Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Making predictions on test data:","metadata":{}},{"cell_type":"code","source":"pred_net = model_Net.predict(test_data)\npred_iresnet2 = model_IResNet2.predict(test_data)\npred_dense = model_dense.predict(test_data)","metadata":{"execution":{"iopub.status.busy":"2021-05-30T22:45:29.102053Z","iopub.status.idle":"2021-05-30T22:45:29.102661Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred = (pred_net+pred_iresnet2+pred_dense).tolist()","metadata":{"execution":{"iopub.status.busy":"2021-05-30T22:45:29.103704Z","iopub.status.idle":"2021-05-30T22:45:29.104301Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in range(len(pred)):\n    pred[i] = np.argmax(pred[i])\n\n    \ndef get_key(val):\n    for key, value in dict_classes.items():\n        if val == value:\n            return key\n        \n\nfor i in range(len(pred)):\n    pred[i] = get_key(pred[i])","metadata":{"execution":{"iopub.status.busy":"2021-05-30T22:45:29.10542Z","iopub.status.idle":"2021-05-30T22:45:29.106034Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred","metadata":{"execution":{"iopub.status.busy":"2021-05-30T22:45:29.107102Z","iopub.status.idle":"2021-05-30T22:45:29.107679Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df['labels'] = pred\ntest_df","metadata":{"execution":{"iopub.status.busy":"2021-05-30T22:45:29.108806Z","iopub.status.idle":"2021-05-30T22:45:29.109404Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df.to_csv('submission.csv',index=False)","metadata":{"execution":{"iopub.status.busy":"2021-05-30T22:45:29.110472Z","iopub.status.idle":"2021-05-30T22:45:29.111071Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### If you liked the Notebook Please Upvote It !\n#### Thank You","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}