{"cells":[{"metadata":{},"cell_type":"markdown","source":"## Problem Statement\nThe goal of this competition is to identify diseased cassava leaves from images which were crowdsourced from farmers taking photos of their gardens, and annotated by experts at the National Crops Resources Research Institute (NaCRRI) in collaboration with the AI lab at Makerere University, Kampala. This is in a format that most realistically represents what farmers would need to diagnose in real life.  \nThere are 4 different types of diseases that generally affect the Cassava Plant:\n* Cassava Bacterial Blight (CBB)\n* Cassava Brown Streak Disease (CBSD)\n* Cassava Green Mottle (CGM)\n* Cassava Mosaic Disease (CMD) \n\nAlong with the diseased leaves there is also a 5th category of healthy leaves. The photos are taken from relatively inexpensive Mobile cameras generally kept by the farmers and correctly identifying the diseased leaves would result in quciker automated turn arounds enabling early action"},{"metadata":{},"cell_type":"markdown","source":"![](https://storage.googleapis.com/kaggle-competitions/kaggle/13836/logos/header.png)"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Install the fastai library \n# !pip install fastai2","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# Import libraries \nimport os\nimport random\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport cv2\nfrom fastai.vision.all import *\n# Auto code completion\n%config Completer.use_jedi = False\n# Configs\npd.options.display.max_colwidth = 100","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Verify that the pretrained resnet 50 model is available so it's not downloaded\nos.listdir('/kaggle/input/pretrained-pytorch')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"markdown","source":"### EDA- Looking at general aspects of the data, visualizing Images from each category of leaves etc"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Train and Test dataset sizes\nnum_train_images = len(os.listdir('/kaggle/input/cassava-leaf-disease-classification/train_images'))\nnum_test_images = len(os.listdir('/kaggle/input/cassava-leaf-disease-classification/test_images'))\nprint('There are: ', num_train_images, \"images in train and\", num_test_images, 'images in test')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"To prevent cheating and manual labelling the full set of Test Images are only available when the notebook is submitted for scoring. This is why the number of test images is being shown as 1"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Let's see the distribution of classes in the training data\ntrain_mappings_data = pd.read_csv('/kaggle/input/cassava-leaf-disease-classification/train.csv')\nmapping_dict = pd.read_json('/kaggle/input/cassava-leaf-disease-classification/label_num_to_disease_map.json',\n                           typ='series')\nmapping_dict = mapping_dict.to_dict()\ntrain_mappings_data['Label_expanded'] = train_mappings_data['label'].map(mapping_dict)\ntrain_mappings_data.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Class distribution\nprint(train_mappings_data['Label_expanded'].value_counts() / train_mappings_data.shape[0] * 100)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"As can be seen there is a fairly large imbalance in class distribution with ~62% Images belonging to the Cassava Mosaic Disease class. In this kind of a problem selecting a proper evaluation metric like macro f1_score or auc during training is paramount."},{"metadata":{},"cell_type":"markdown","source":"### Visualization- Let's visualize a few Images from each of the 5 categories"},{"metadata":{},"cell_type":"markdown","source":"<h2 style='background:limegreen; border:0; color:black'><center> 3 Cassava Mosaic Disease </center></h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_images(img_list, img_label):\n    os.chdir('/kaggle/input/cassava-leaf-disease-classification/train_images')\n    plt.figure(figsize=(16, 12))\n    for i, img in enumerate(img_list):\n        plt.subplot(3,2,i+1)\n        temp_img = cv2.imread(img)\n        temp_img = cv2.cvtColor(temp_img, cv2.COLOR_BGR2RGB)\n        plt.imshow(temp_img)\n        plt.title(img_label, fontsize=12)\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"CMD_IDs = list(train_mappings_data['image_id'][train_mappings_data['label'] == 3])\nCMD_IDs_to_display = random.sample(CMD_IDs, 6)\nplot_images(CMD_IDs_to_display, mapping_dict[3])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h3>Let's see some symptoms of the Cassava Mosaic Disease<h3>"},{"metadata":{},"cell_type":"markdown","source":"<img style=\"height:480\" src=\"https://www.easybiologyclass.com/wp-content/uploads/2018/09/Leaf-Mosaic-of-Tapioca.jpg\" alt=\"Cassava Mosaic Disease\"> <cite> <a href=\"https://www.easybiologyclass.com/mosaic-disease-of-tapioca-symptoms-and-control-measures/\"> Easy Biology Class </a> </cite>"},{"metadata":{},"cell_type":"markdown","source":"<h2 style='background:limegreen; border:0; color:black'><center> 4 Healthy Leaves </center></h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"Healthy_IDs = list(train_mappings_data['image_id'][train_mappings_data['label'] == 4])\nHealthy_IDs_to_display = random.sample(Healthy_IDs, 6)\nplot_images(Healthy_IDs_to_display, mapping_dict[4])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"As can be Healthy leaves seem to have more shine and clearer veins but to the naked eyes of a non expert it can be indeed difficult to distinguish"},{"metadata":{},"cell_type":"markdown","source":"<h2 style='background:limegreen; border:0; color:black'> <center>2 Casava Green Mottle</center></h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"CGM_IDs = list(train_mappings_data['image_id'][train_mappings_data['label'] == 2])\nCGM_IDs_to_display = random.sample(Healthy_IDs, 6)\nplot_images(CGM_IDs_to_display, mapping_dict[2])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h3>Let's see some symptoms of the Cassava Green Mottle Disease<h3>"},{"metadata":{},"cell_type":"markdown","source":"<div class=\"img-with-text\">\n    <img style=\"height:300px\" src=\"https://www.pestnet.org/fact_sheets/assets/image/cassava_green_mottle_068/cgmv2.jpg\" alt=\"Image 1\"/>\n    <p><center>Yellow Spots throughout the leaf caused by infection from Cassava Green Mottle Virus</p>\n</div>\n<div class=\"img-with-text2\">\n    <img style=\"height:300px\" src=\"https://www.pestnet.org/fact_sheets/assets/image/cassava_green_mottle_068/cgmv.jpg\" alt=\"Image 1\"/>\n    <p><center><b>Larger Irregular spots and patches on distorted leaves</b></p>\n</div>\n<cite>Link to Images: <a href=\"https://www.pestnet.org/fact_sheets/cassava_green_mottle_068.htm\">Cassava Green Mottle Virus</a></cite>"},{"metadata":{},"cell_type":"markdown","source":"<h2 style='background:limegreen; border:0; color:black'><center> 1 Cassava Brown Streak Disease </center></h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"CBB_IDs = list(train_mappings_data['image_id'][train_mappings_data['label'] == 1])\nCBB_IDs_to_display = random.sample(CBB_IDs, 6)\nplot_images(CBB_IDs_to_display, mapping_dict[1])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h3>Zoom in to see a more detailed Image</h3>"},{"metadata":{},"cell_type":"markdown","source":"<img style=\"height:300;width:300\" src=\"https://newscenter.lbl.gov/wp-content/uploads/sites/2/Characteristic-yellowing-of-casssava-leaves-symptom-of-CBSD-infection.jpg\" alt=\"Cassava Brown Streak Disease\"> <cite> <a href=\"https://newscenter.lbl.gov/2013/03/18/cassava-brief-genomics/\"> Newscenter </a> </cite>"},{"metadata":{},"cell_type":"markdown","source":"<h2 style='background:limegreen; border:0; color:black'><center> 0 Cassava Bacterial Blight </center></h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"CBBlight_IDs = list(train_mappings_data['image_id'][train_mappings_data['label'] == 0])\nCBBlight_IDs_to_display = random.sample(CBBlight_IDs, 6)\nplot_images(CBBlight_IDs_to_display, mapping_dict[0])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"markdown","source":"<h3> Zoom in to see a more detailed image </h3>"},{"metadata":{},"cell_type":"markdown","source":"<img style=\"height:300px\" src=\"http://www.pestnet.org/fact_sheets/assets/image/cassava_bacterial_blight_173/thumbs/cassavabb_sml.jpg\" alt=\"Cassava Bacterial Blight\"> <cite> <a href=\"http://www.pestnet.org/fact_sheets/cassava_bacterial_blight_173.htm\"> Easy Biology Class </a> </cite>"},{"metadata":{},"cell_type":"markdown","source":"This category seems to be a bit more easily identifiable as the whole leaf seems more yellowish rather than some spots and also brown splotches and wilting is prevalent"},{"metadata":{},"cell_type":"markdown","source":"## Getting some baseline results with the Fast AI library for reference"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Create a DataFrame containing the Image labels and paths for easy use with Image Data Loaders from FastAI\ntrain_df = train_mappings_data.loc[:, ['image_id', 'label']]\ntrain_df['Img_path'] = 'train_images/' + train_df['image_id']\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_img_data = ImageDataLoaders.from_df(train_df,path='/kaggle/input/cassava-leaf-disease-classification/',\n                                          valid_pct=0.2, seed=123, fn_col=2, \n                                          item_tfms = RandomResizedCrop(224, min_scale=0.5),\n                                          batch_tfms=aug_transforms())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Move the pre trained model weights to proper location so the resnet model can use it without downloading\n# from internet\nif not os.path.exists('/root/.cache/torch/hub/checkpoints/'):\n        os.makedirs('/root/.cache/torch/hub/checkpoints/')\n!cp '/kaggle/input/pretrained-pytorch/resnet50-19c8e357.pth' '/root/.cache/torch/hub/checkpoints/resnet50-19c8e357.pth'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Create lerner\nlearner_50 = cnn_learner(train_img_data, resnet50, metrics=accuracy)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Train one cycle\nlearner_50.fine_tune(4)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Have a look at the mistakes the model made for future improvements\nmodel_interpreter = ClassificationInterpretation.from_learner(learner_50)\nmodel_interpreter.plot_confusion_matrix()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"It is the Healthy leaves which seem to be misclassified the most consistently. Also categories 2 and 3 are misclassified as each other frequently. "},{"metadata":{"trusted":true},"cell_type":"code","source":"# Let's see top losses\nmodel_interpreter.plot_top_losses(5, nrows=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Generate Predictions for the Test set and establish a baseline\n# Ingest the test image names\ntest_df = pd.read_csv('/kaggle/input/cassava-leaf-disease-classification/sample_submission.csv')\ntest_df['Img_path'] = \"test_images/\" + test_df['image_id']\ntest_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Add the test data to the Data Loader\ntest_img_data = train_img_data.test_dl(test_df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# See if image was successfully added\ntest_img_data.show_batch()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Generate predictions for the test data with TTA\npreds, _ = learner_50.tta(dl=test_img_data, n=15, beta=0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Submit preds using the same format as the sample submissions file\nsubmission_1 = test_df.drop(columns=['Img_path'])\nsubmission_1['label'] = preds.argmax(dim=-1).numpy()\nsubmission_1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Make submission\nsubmission_1.to_csv('/kaggle/working/submission.csv',index=False)","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}