{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Cassava Leaf Disease Classification - Exploratory Data Analysis\n\nQuick Exploratory Data Analysis for [Cassava Leaf Disease Classification](https://www.kaggle.com/c/cassava-leaf-disease-classification) challenge    \n\nThis competition will challenge you to distinguish between several diseases that cause material harm to the food supply of many African countries. In some cases the main remedy is to burn the infected plants to prevent further spread, which can make a rapid automated turnaround quite useful to the farmers."},{"metadata":{"trusted":true},"cell_type":"code","source":"%%capture\n!pip install ../input/timm-pip/timm-0.3.1-py3-none-any.whl","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"#import Libraries\n\nimport numpy as np\nimport os\nimport pandas as pd\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nimport json\n\nimport tensorflow as tf\n\nimport tensorflow as tf\nimport torchvision\nfrom fastai.vision.all import *\nimport timm\n\nfrom pathlib import Path\n\nfrom tqdm import tqdm\n\nimport plotly.graph_objects as go\nimport plotly_express as px\nimport plotly.figure_factory as ff\nfrom plotly.subplots import make_subplots\n\nimport cv2\n\nfrom plotly.offline import init_notebook_mode\ninit_notebook_mode()\n\ndataset_path = os.path.normpath(\"../input/cassava-leaf-disease-classification\")\nos.listdir(dataset_path)\n\nBASE_DIR = \"../input/cassava-leaf-disease-classification/\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Checking Tensorflow Version\ntf.__version__","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"#loading dataset\ntrain_df = pd.read_csv(dataset_path + \"/\" + 'train.csv')\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"set_seed(999)\n\ndataset_path = Path('../input/cassava-leaf-disease-classification')\nos.listdir(dataset_path)\n\nBASE_DIR = \"../input/cassava-leaf-disease-classification/\"\n\ntrain_df = pd.read_csv(\"../input/cassava-leaf-disease-classification/train.csv\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Total amount of images\nlen_df = len(train_df)\nprint(f\"There are {len_df} images\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#All Labels in the dataset\nwith open(os.path.join(BASE_DIR, \"label_num_to_disease_map.json\")) as file:\n    map_classes = json.loads(file.read())\n    map_classes = {int(k) : v for k, v in map_classes.items()}\n    \nprint(json.dumps(map_classes, indent=4))\n\ntrain_df = pd.read_csv(os.path.join(BASE_DIR, \"train.csv\"))\n\ntrain_df[\"class_name\"] = train_df[\"label\"].map(map_classes)\n\ntrain_df['path'] = train_df['image_id'].map(lambda x:dataset_path/'train_images'/x)\ntrain_df = train_df.drop(columns=['image_id'])\ntrain_df = train_df.sample(frac=1).reset_index(drop=True) #shuffle dataframe","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#from sklearn.utils import resample\n# Separate majority and minority classes\n#df_cmd_up = train_df[train_df.label==3]\n#df_healthy_up = train_df[train_df.label==4]\n#df_cgm_up = train_df[train_df.label==2]\n#df_cbsd_up = train_df[train_df.label==1]\n#df_cbb_up = train_df[train_df.label==0]\n\n#df_cmd_up = resample(df_cmd_up, \n#                                 replace=True,     # sample with replacement\n#                                 n_samples=3000,    # to match minority class\n#                                 random_state=123) # reproducible results\n    \n    \n# Upsample minority class\n#df_healthy_up = resample(df_healthy_up, \n#                                 replace=True,     # sample with replacement\n#                                 n_samples=13000,    # to match majority class\n#                                 random_state=123) # reproducible results\n\n#df_cgm_up = resample(df_cgm_up, \n#                                 replace=True,     # sample with replacement\n#                                 n_samples=13000,    # to match majority class\n#                                 random_state=123)\n#\n#df_cbsd_up = resample(df_cbsd_up, \n#                                 replace=True,     # sample with replacement\n#                                 n_samples=13000,    # to match majority class\n#                                 random_state=123)\n#\n#df_cbb_up = resample(df_cbb_up, \n#                                 replace=True,     # sample with replacement\n#                                 n_samples=13000,    # to match majority class\n#                                 random_state=123)\n \n# Combine majority class with upsampled minority class\n#df_upsampled = pd.concat([df_cmd_up, df_healthy_up, df_cgm_up, df_cbsd_up, df_cbb_up])\n \n\n#train_df = df_upsampled","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = train_df[[\"label\", \"path\"]]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from PIL import Image\n\nim = Image.open(train_df['path'][1])\nwidth, height = im.size\nprint(width,height) ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"item_tfms = RandomResizedCrop(224, min_scale=0.75, ratio=(1.,1.))\nbatch_tfms = [*aug_transforms(size=224, max_warp=0), Normalize.from_stats(*imagenet_stats)]\nbs=32","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dls = ImageDataLoaders.from_df(train_df, #pass in train DataFrame\n                               valid_pct=0.2, #80-20 train-validation random split\n                               seed=999, #seed\n                               label_col=0, #label is in the first column of the DataFrame\n                               fn_col=1, #filename/path is in the second column of the DataFrame\n                               bs=bs, #pass in batch size\n                               item_tfms=item_tfms, #pass in item_tfms\n                               batch_tfms=batch_tfms) #pass in batch_tfms","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#dls.show_batch()","execution_count":null,"outputs":[]},{"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/timmefficientnet/tf_efficientnet_b0_ns-c0e6a31c.pth' '/root/.cache/torch/hub/checkpoints/tf_efficientnet_b0_ns-c0e6a31c.pth'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from timm import create_model\nfrom fastai.vision.learner import _update_first_layer\n\ndef create_timm_body(arch:str, pretrained=True, cut=None, n_in=3):\n    \"Creates a body from any model in the `timm` library.\"\n    model = create_model(arch, pretrained=pretrained, num_classes=0, global_pool='')\n    _update_first_layer(model, n_in, pretrained)\n    if cut is None:\n        ll = list(enumerate(model.children()))\n        cut = next(i for i,o in reversed(ll) if has_pool_type(o))\n    if isinstance(cut, int): return nn.Sequential(*list(model.children())[:cut])\n    elif callable(cut): return cut(model)\n    else: raise NamedError(\"cut must be either integer or function\")\n        \ndef create_timm_model(arch:str, n_out, cut=None, pretrained=True, n_in=3, init=nn.init.kaiming_normal_, custom_head=None,\n                     concat_pool=True, **kwargs):\n    \"Create custom architecture using `arch`, `n_in` and `n_out` from the `timm` library\"\n    body = create_timm_body(arch, pretrained, None, n_in)\n    if custom_head is None:\n        nf = num_features_model(nn.Sequential(*body.children())) * (2 if concat_pool else 1)\n        head = create_head(nf, n_out, concat_pool=concat_pool, **kwargs)\n    else: head = custom_head\n    model = nn.Sequential(body, head)\n    if init is not None: apply_init(model[1], init)\n    return model\n\ndef timm_learner(dls, arch:str, loss_func=None, pretrained=True, cut=None, splitter=None,\n                y_range=None, config=None, n_out=None, normalize=True, **kwargs):\n    \"Build a convnet style learner from `dls` and `arch` using the `timm` library\"\n    if config is None: config = {}\n    if n_out is None: n_out = get_c(dls)\n    assert n_out, \"`n_out` is not defined, and could not be inferred from data, set `dls.c` or pass `n_out`\"\n    if y_range is None and 'y_range' in config: y_range = config.pop('y_range')\n    model = create_timm_model(arch, n_out, default_split, pretrained, y_range=y_range, **config)\n    learn = Learner(dls, model, loss_func=loss_func, splitter=default_split, **kwargs)\n    if pretrained: learn.freeze()\n    return learn","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn = timm_learner(dls, \n                    'tf_efficientnet_b0_ns', \n                     opt_func = ranger,\n                     loss_func=LabelSmoothingCrossEntropy(),\n                     metrics = [accuracy]).to_native_fp16()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.lr_find()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.freeze()\nlearn.fit_flat_cos(1,1e-1, wd=0.5, cbs=[MixUp()])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.save('stage-1')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn = learn.load('stage-1')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.recorder.plot_loss()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.unfreeze()\nlearn.lr_find()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.unfreeze()\nlearn.fit_flat_cos(20,2e-2,pct_start=0,cbs=[MixUp()])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.recorder.plot_loss()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn = learn.to_native_fp32()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.save('stage-2')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.export()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"interp = ClassificationInterpretation.from_learner(learn)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"interp.plot_confusion_matrix()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_df = pd.read_csv(dataset_path/'sample_submission.csv')\nsample_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"_sample_df = sample_df.copy()\n_sample_df['path'] = _sample_df['image_id'].map(lambda x:dataset_path/'test_images'/x)\n_sample_df = _sample_df.drop(columns=['image_id'])\ntest_dl = dls.test_dl(_sample_df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_dl.show_batch()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"preds, _ = learn.tta(dl=test_dl, n=8, beta=0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_df['label'] = preds.argmax(dim=-1).numpy()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_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}