{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import os\nimport pandas as pd\nimport numpy as np\nimport json\n\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport plotly.express as px\nimport plotly.graph_objects as go\nimport cv2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import tensorflow as tf","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"base_path = \"../input/cassava-leaf-disease-classification/\"\n\nwith open(os.path.join(base_path, 'label_num_to_disease_map.json'), 'r') as f:\n    class_map = json.load(f)\n    class_map = {int(k):v for k,v in class_map.items()}\nprint(class_map)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"Number of Images in Train Set: {}\".format(len(os.listdir(os.path.join(base_path, 'train_images')))))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.read_csv(os.path.join(base_path, 'train.csv'))\ntrain_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"global_seed = 23\nimport random\nrandom.seed(global_seed)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"disease_names = open(base_path+'label_num_to_disease_map.json')\ndisease_names = json.load(disease_names)\ntrain_df['disease_name'] = train_df['label'].apply(lambda x: disease_names[str(x)])\n# credit: https://www.kaggle.com/ramjib/cassava-leaf-disease-eda-and-outliers\ntrain_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"my_colors = 'kckckc'\nplt.bar(x=train_df['disease_name'].value_counts().index, height=train_df['disease_name'].value_counts().values, color =my_colors)\nplt.xticks(rotation=90)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_batch(data=df):\n    plt.figure(figsize=(16,12))\n    for i in range(9):\n        k = np.random.randint(0, len(data)) #for plotting random images from dataset\n        image = cv2.imread(os.path.join(base_path, 'train_images/', data.image_id[k]))\n        \n        plt.subplot(3,3,i+1)\n        plt.imshow(image)\n        plt.axis(\"off\")\n        plt.title(\"Class Label:{}\\nClass Name:{}\".format(data.label[k], data.disease_name[k]))\n    \n    plt.tight_layout()\n    plt.show()\n# Credit - https://www.kaggle.com/anantgupt/cassava-leaf-doctor-eda-keras/notebook#5:-MODEL-TRAINING-AND-DEFINING-CALLBACKS","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_batch(train_df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for i in range(5):\n    temp_df = train_df.loc[df['label']==i]\n    temp_df.reset_index(inplace=True)\n    print(\"Class label:\", i)\n    plot_batch(temp_df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Baseline model with FastAI\nMost of the following is adapted from kaggle.com/muellerzr/cassava-fastai-starter"},{"metadata":{"trusted":true},"cell_type":"code","source":"from fastai.vision.all import *\nset_seed(23)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"path = Path(\"../input\")\ndata_path = path/'cassava-leaf-disease-classification'\ndata_path.ls()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df = train_df\ndf['image_id'] = df['image_id'].apply(lambda x: f'train_images/{x}')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Building the `DataBlock`\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"blocks = (ImageBlock, CategoryBlock)\nsplitter = RandomSplitter(valid_pct=0.2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_x(row): return data_path/row['image_id']\n\ndef get_y(row): return row['label']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"item_tfms = [Resize(448)]\nbatch_tfms = [RandomResizedCropGPU(224), *aug_transforms(), Normalize.from_stats(*imagenet_stats)]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"block = DataBlock(blocks = blocks,\n                 get_x = get_x,\n                 get_y = get_y,\n                 splitter = splitter,\n                 item_tfms = item_tfms,\n                 batch_tfms = batch_tfms)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dls = block.dataloaders(df, bs=64)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"We're checking a batch of data to make sure everything looks alright:"},{"metadata":{"trusted":true},"cell_type":"code","source":"dls.show_batch(figsize=(12,12))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Looks shipshape!"},{"metadata":{},"cell_type":"markdown","source":"## Training this FastAI model\n\nThe code below is from tanlikesmath's notebook (via kaggle.com/muellerzr/cassava-fastai-starter). We have to add a resnet model to our directory (see https://forums.fast.ai/t/how-can-i-load-a-pretrained-model-on-kaggle-using-fastai/13941/24 for instructions) before running the cell below. The code below moves our pretrained weights to where fastai will expect it:"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Making pretrained weights work without needing to find the default filename\nif not os.path.exists('/root/.cache/torch/hub/checkpoints/'):\n        os.makedirs('/root/.cache/torch/hub/checkpoints/')\n!cp '../input/resnet50/resnet50.pth' '/root/.cache/torch/hub/checkpoints/resnet50-19c8e357.pth'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn = cnn_learner(dls, resnet50, opt_func=ranger, loss_func=LabelSmoothingCrossEntropy(), metrics=accuracy)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def fine_tune(self:Learner, epochs, base_lr=2e-3, freeze_epochs=1, lr_mult=100,\n              pct_start=0.3, div=5.0, **kwargs):\n    \"Fine tune with `freeze` for `freeze_epochs` then with `unfreeze` from `epochs` using discriminative LR\"\n    self.freeze()\n    self.fit_one_cycle(freeze_epochs, slice(base_lr), pct_start=0.99, **kwargs)\n    base_lr /= 2\n    self.unfreeze()\n    self.fit_one_cycle(epochs, slice(base_lr/lr_mult, base_lr), pct_start=pct_start, div=div, **kwargs)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"@patch\ndef fine_tune_flat(self:Learner, epochs, base_lr=4e-3, freeze_epochs=1, lr_mult=100, pct_start=0.75, \n                   first_callbacks = [], second_callbacks = [], **kwargs):\n    \"Fine-tune applied to `fit_flat_cos`\"\n    self.freeze()\n    self.fit_flat_cos(freeze_epochs, slice(base_lr), pct_start=0.99, cbs=first_callbacks, **kwargs)\n    base_lr /= 2\n    self.unfreeze()\n    self.fit_flat_cos(epochs, slice(base_lr/lr_mult, base_lr), pct_start=pct_start, cbs=second_callbacks)","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"learn.lr_find()\n# Interrupted b/c taking too long; see Mueller's notebook for output\n# His SuggestedLRs were: (lr_min=0.017378008365631102, lr_steep=0.14454397559165955)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"We'll choose a learning rate of roughly 4e-3 to start."},{"metadata":{"trusted":true},"cell_type":"code","source":"cbs1 = [MixUp(alpha = 0.7)]\ncbs2 = [MixUp(alpha = 0.3)]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"We're training for 1 epoch frozen and 2 unfrozen, with a `pct_start` of 0.72:"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Note that the original had `start_pct`, but it should have been `pct_start`\nlearn.fine_tune_flat(2, base_lr=1e-3, pct_start=0.72, first_callbacks=cbs1, second_callbacks=cbs2)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Submitting some results"},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_df = pd.read_csv(data_path/'sample_submission.csv')\nsample_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_copy = sample_df.copy()\nsample_copy['image_id'] = sample_copy['image_id'].apply(lambda x: f'test_images/{x}')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_dl = learn.dls.test_dl(sample_copy)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"We'll look at a batch of data to make sure it all looks okay:"},{"metadata":{"trusted":true},"cell_type":"code","source":"test_dl.show_batch()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Next we'll get some predictions. We will use the `.tta` method to run test-time-augmentation which can help boost our accuracy some:"},{"metadata":{"trusted":true},"cell_type":"code","source":"preds, _ = learn.tta(dl=test_dl)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Then we submit them."},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_df['label'] = preds.argmax(dim=-1).numpy()\nsample_df.to_csv('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}