{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport os\nfrom fastai.vision.all import *","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Introduction & Obtaining Pretrained Models\n\nI am following [this notebook](https://www.kaggle.com/tanlikesmath/cassava-classification-eda-fastai-starter) and [this notebook](https://www.kaggle.com/muellerzr/cassava-fastai-starter). The goal is to produce a simple working submission using fastai. This will *not* include EDA or more than a passing attempt at model selection/tuning. This guide differs from the linked notebooks because it includes more detailed instructions for finding and downloading pre-trained PyTorch model weights and using them with the notebook set for offline use.\n\nOne note: for this competition, the notebook cannot have Internet access, so we need to make sure any pre-trained model weights are loaded in advance. To do so, we download the `.pth` files and then add them using the \"add data\" button in the sidebar on the right. We also need to make sure fastai knows where to find these files; this process is detailed below.\n\nYou can find the URLs for the various models [here](https://github.com/pytorch/vision/tree/master/torchvision/models). For example, if you're interested in `resnet50`, open the [resnet.py](https://github.com/pytorch/vision/blob/master/torchvision/models/resnet.py) file. The `model_urls` variable shows the URLs for the various resnet models; the URL for resnet50 is https://download.pytorch.org/models/resnet50-19c8e357.pth."},{"metadata":{},"cell_type":"markdown","source":"# Data Setup"},{"metadata":{"trusted":true},"cell_type":"code","source":"path = Path('../input/cassava-leaf-disease-classification')\ntrain_df = pd.read_csv(path/'train.csv')\ntrain_df['image_id'] = train_df['image_id'].apply(lambda x: f'train_images/{x}')\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Making Labels More Interpretable"},{"metadata":{"trusted":true},"cell_type":"code","source":"idx2lbl = {0:\"Cassava Bacterial Blight (CBB)\",\n          1:\"Cassava Brown Streak Disease (CBSD)\",\n          2:\"Cassava Green Mottle (CGM)\",\n          3:\"Cassava Mosaic Disease (CMD)\",\n          4:\"Healthy\"}\n\ntrain_df['label'].replace(idx2lbl, inplace=True)\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Building the Datablock"},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_x(row): return path/row['image_id']\ndef get_y(row): return row['label']\n\ndb = DataBlock(blocks = (ImageBlock, CategoryBlock),\n                 get_x = get_x,\n                 get_y = get_y,\n                 splitter = RandomSplitter(valid_pct=0.2),\n                 item_tfms = [Resize(128)], # starting with small images for efficient testing\n                 batch_tfms = [RandomResizedCropGPU(224), *aug_transforms(), Normalize.from_stats(*imagenet_stats)])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## DataLoaders"},{"metadata":{"trusted":true},"cell_type":"code","source":"dls = db.dataloaders(train_df, bs=64)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dls.show_batch(figsize=(12,12))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Train the Model\n\nWe're going to start with ResNet 18. We first need to make sure we can find the appropriate model weights. We downloaded the pretrained weights from [here](https://download.pytorch.org/models/resnet18-5c106cde.pth). We now need to make sure fastai can find the weights.\n\nA reminder: You can find the URLs for the various models [here](https://github.com/pytorch/vision/tree/master/torchvision/models). For example, if you're interested in `resnet50`, open the [resnet.py](https://github.com/pytorch/vision/blob/master/torchvision/models/resnet.py) file. The `model_urls` variable shows the URLs for the various resnet models; the URL for resnet50 is https://download.pytorch.org/models/resnet50-19c8e357.pth.\n\nSo if you want to use a pretrained model *other than* `resnet18`, the steps are: (1) locate the URL, as noted above; (2) download the `.pth` file; (3) upload the `.pth` file using \"Add data\" in the sidebar; (4) make fastai aware of the location of the weights, following the procedure in the next cell but copying the desired model; (5) call the desired model in your fastai learner."},{"metadata":{"trusted":true},"cell_type":"code","source":"if not os.path.exists('/root/.cache/torch/hub/checkpoints/'):\n        os.makedirs('/root/.cache/torch/hub/checkpoints/')\n!cp '../input/resnet18/resnet18-5c106cde.pth' '/root/.cache/torch/hub/checkpoints/resnet18-5c106cde.pth'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn = cnn_learner(dls, resnet18, opt_func=ranger, loss_func=LabelSmoothingCrossEntropy(), metrics=accuracy)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.fine_tune(6, freeze_epochs = 3)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Preparing a Submission"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Format submission df in same way as training df\nsample_df = pd.read_csv(path/'sample_submission.csv')\nsample_copy = sample_df.copy()\nsample_copy['image_id'] = sample_copy['image_id'].apply(lambda x: f'test_images/{x}')\n\ntest_dl = learn.dls.test_dl(sample_copy)\npreds, _ = learn.tta(dl=test_dl) # test-time augmentation can improve accuracy somewhat\n\nsample_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}