{"cells":[{"metadata":{},"cell_type":"markdown","source":"## This entire work is hands-on session by Abhishek Thakur\n## Planning to expand the same for all existing pretrained networks for better accuracies\n## Trying different augmentation techniques too\n"},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"!pip install tez","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\nimport albumentations\nimport matplotlib.pyplot as plt\nimport pandas as pd\n\nimport tez\nfrom tez.datasets import ImageDataset\nfrom tez.callbacks import EarlyStopping\n\nimport torch\nimport torch.nn as nn\nimport torchvision\n\nfrom sklearn import metrics, model_selection\n\n%matplotlib inline","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df = pd.read_csv(\"../input/cassava-leaf-disease-classification/train.csv\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df[\"label\"].value_counts()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df[\"label\"].value_counts().plot.bar()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train , df_valid = model_selection.train_test_split(\n    df, \n    test_size=0.1, \n    random_state=45, \n    stratify=df[\"label\"].values \n)\n\ndf_train = df_train.reset_index(drop=True)\ndf_valid = df_valid.reset_index(drop=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train[\"label\"].value_counts()\n#df_train[\"label\"].value_counts().plot.bar()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_valid.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_valid[\"label\"].value_counts()\ndf_valid[\"label\"].value_counts().plot.bar()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image_path = \"../input/cassava-leaf-disease-classification/train_images/\"\n\ntrain_image_paths = [\n    os.path.join(image_path, x) for x in df_train[\"image_id\"].values\n]\n\nvalid_image_paths = [\n    os.path.join(image_path, x) for x in df_valid[\"image_id\"].values\n]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_image_paths[:5]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"valid_image_paths[:5]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_targets = df_train.label.values\nvalid_targets = df_valid.label.values","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''\ntrain_dataset = ImageDataset(\n    image_paths =train_image_paths,\n    targets = train_targets,\n    resize=(256,256),\n    augmentations=None\n)\n'''","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_img(img_dict):\n    img_tensor = img_dict[\"image\"]\n    target = img_dict[\"targets\"]\n    plt.figure(figsize=(10,10))\n    image = img_tensor.permute(1,2,0)/255\n    plt.imshow(image)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_aug = albumentations.Compose(\n    [\n        albumentations.RandomResizedCrop(256,256),\n        albumentations.Transpose(p=0.5),\n        albumentations.HorizontalFlip(p=0.5),\n        albumentations.VerticalFlip(p=0.5)\n    ]\n\n)\n\nvalid_aug = albumentations.Compose(\n    [\n        albumentations.CenterCrop(256,256, p=1.0),\n        albumentations.Resize(256,256),\n        albumentations.RandomResizedCrop(256,256),\n        albumentations.Transpose(p=0.5),\n        albumentations.HorizontalFlip(p=0.5),\n        albumentations.VerticalFlip(p=0.5)\n    ]\n\n)\n\ntrain_dataset = ImageDataset(\n    image_paths =train_image_paths,\n    targets = train_targets,\n    resize=None,\n    augmentations=train_aug\n)\n\nvalid_dataset = ImageDataset(\n    image_paths =valid_image_paths,\n    targets = valid_targets,\n    resize=None,\n    augmentations=valid_aug\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class LeafModel(tez.Model):\n    def __init__(self, num_classes, pretrained=True):\n        super().__init__()\n        self.convnet = torchvision.models.resnet18(pretrained=pretrained)\n        self.convnet.fc = nn.Linear(512, num_classes)\n        self.step_scheduler_after = \"epoch\"\n        \n        \n    def loss(self, outputs, targets):\n        if targets is None:\n            return None\n        return nn.CrossEntropyLoss()(outputs, targets)\n    \n    def monitor_metrics(self, outputs, targets):\n        outputs = torch.argmax(outputs, dim=1).cpu().detach().numpy()\n        targets = targets.cpu().detach().numpy()\n        acc = metrics.accuracy_score(targets, outputs)\n        \n        return {\n            \"accuracy\":acc\n        }\n    \n    def fetch_optimizer(self):\n        opt = torch.optim.Adam(self.parameters(), lr=1e-3)\n        return opt\n    \n    def fetch_scheduler(self):\n        sch = torch.optim.lr_scheduler.StepLR(self.optimizer, step_size=0.7)\n        return sch\n    \n    def forward(self, image, targets=None):\n        outputs = self.convnet(image)\n        if targets is not None:\n            loss = self.loss(outputs, targets)\n            mon_metrics = self.monitor_metrics(outputs,targets)\n            return outputs, loss, mon_metrics\n        return outputs, loss, mon_metrics\n        ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"torchvision.models.resnet18(pretrained=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = LeafModel(num_classes=df.label.nunique(), pretrained=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img = train_dataset[0][\"image\"]\ny = train_dataset[0][\"targets\"]\n\nmodel(img.unsqueeze(0), y.unsqueeze(0))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"es = EarlyStopping(\n    monitor=\"valid_accuracy\",\n    model_path=\"model.bin\",\n    patience=2,\n    mode=\"max\"\n)\n\nmodel.fit(\n    train_dataset,\n    valid_dataset=valid_dataset,\n    train_bs=32,\n    valid_bs=64,\n    device=\"cuda\",\n    callbacks=[es],\n    fp16=True, \n    epochs=10,\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.save(\"model.bin\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.load(\"model.bin\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df = pd.read_csv(\"../input/cassava-leaf-disease-classification/sample_submission.csv\")\nimage_path = \"../input/cassava-leaf-disease-classification/test_images/\"\n\ntest_targets = test_df.label.values\n\ntest_image_paths = [\n    os.path.join(image_path,x) for x in test_df.image_id.values\n]\n\ntest_aug = albumentations.Compose(\n    [\n        albumentations.CenterCrop(256,256, p=1.0),\n        albumentations.Resize(256,256),\n        albumentations.RandomResizedCrop(256,256),\n        albumentations.Transpose(p=0.5),\n        albumentations.HorizontalFlip(p=0.5),\n        albumentations.VerticalFlip(p=0.5)\n    ]\n)\n\ntest_dataset = ImageDataset(\n    image_paths=test_image_paths,\n    targets=test_targets,\n    resize=None,\n    augmentations=test_aug\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"preds = model.predict(test_dataset, batch_size=64, n_jobs=-1, device=\"cuda\", sampler=None)\nprint(preds)\nfinal_preds = None\n\nfor p in preds:\n    if final_preds is None:\n        final_preds = p\n    else:\n        final_preds = np.vstack((final_preds,p))\n        \nfinal_preds = final_preds.argmax(axis=1)\ntest_df.label = final_preds\ntest_df.to_csv(\"submission.csv\", index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df.head()","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}