{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install tez","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\n\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\nfrom torch.nn import functional as F\n\nimport torchvision\n\nfrom sklearn import metrics, model_selection, preprocessing\n\n%matplotlib inline","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dfx = pd.read_csv('../input/cassava-leaf-disease-classification/train.csv')\n\n# and split it into training and validation sets\ndf_train, df_valid = model_selection.train_test_split(\n    dfx, \n    test_size=0.1, \n    random_state=42,\n    stratify=dfx.label.values\n)\n\n# reset index on both dataframes\ndf_train = df_train.reset_index(drop=True)\ndf_valid = df_valid.reset_index(drop=True)\n\n# where are the train/valid images located?\nimage_path = \"../input/cassava-leaf-disease-classification/train_images/\"\n\n# create a list of image paths for training\ntrain_image_paths = [os.path.join(image_path, x) for x in df_train.image_id.values]\n\n# create a list of image paths for validation\nvalid_image_paths = [os.path.join(image_path, x) for x in df_valid.image_id.values]\n\n# targets for training\ntrain_targets = df_train.label.values\n\n# targets for validation\nvalid_targets = df_valid.label.values","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset = ImageDataset(\n    image_paths=train_image_paths,\n    targets=train_targets,\n   \n    augmentations=None,\n)\n\n# and the validation dataset\nvalid_dataset = ImageDataset(\n    image_paths=valid_image_paths,\n    targets=valid_targets,\n    \n    augmentations=None,\n)\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset[0]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_image(img_dict):\n    image_tensor = img_dict[\"image\"]\n    target = img_dict[\"targets\"]\n    print(target)\n    plt.figure(figsize=(10, 10))\n    image = image_tensor.permute(1, 2, 0) / 255\n    plt.imshow(image)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_image(train_dataset[0])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"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        albumentations.ShiftScaleRotate(p=0.5),\n        # albumentations.Normalize(\n        #    mean=[0.485, 0.456, 0.406], \n        #    std=[0.229, 0.224, 0.225], \n        #    max_pixel_value=255.0, \n        #    p=1.0\n        #)\n    ]\n)\n\n\n# now, we set resize to None as we are doing \n# resizing via augmentations\ntrain_dataset = ImageDataset(\n    image_paths=train_image_paths,\n    targets=train_targets,\n    \n    augmentations=train_aug,\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_image(train_dataset[0])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class LeafModel(tez.Model):\n    def __init__(self, num_classes):\n        super().__init__()\n\n        self.convnet = torchvision.models.resnet18(pretrained=True)\n        self.convnet.fc = nn.Linear(512, num_classes)\n        self.step_scheduler_after = \"epoch\"\n        \n    def monitor_metrics(self, outputs, targets):\n        if targets is None:\n            return {}\n        outputs = torch.argmax(outputs, dim=1).cpu().detach().numpy()\n        targets = targets.cpu().detach().numpy()\n        accuracy = metrics.accuracy_score(targets, outputs)\n        return {\"accuracy\": accuracy}\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        batch_size, _, _, _ = image.shape\n\n        outputs = self.convnet(image)\n        \n        if targets is not None:\n            loss = nn.CrossEntropyLoss()(outputs, targets)\n            metrics = self.monitor_metrics(outputs, targets)\n            return outputs, loss, metrics\n        return outputs, None, None","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = LeafModel(num_classes=5)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image = train_dataset[0][\"image\"].unsqueeze(0)\ntarget = train_dataset[0][\"targets\"].unsqueeze(0)\n\n\nmodel(image, target)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_aug = albumentations.Compose([\n            albumentations.RandomResizedCrop(256, 256),\n            albumentations.Transpose(p=0.5),\n            albumentations.HorizontalFlip(p=0.5),\n            albumentations.VerticalFlip(p=0.5),\n            albumentations.ShiftScaleRotate(p=0.5),\n            albumentations.Normalize(\n                mean=[0.485, 0.456, 0.406], \n                std=[0.229, 0.224, 0.225], \n                max_pixel_value=255.0, \n                p=1.0\n            )], p=1.)\n      \nvalid_aug = albumentations.Compose([\n            albumentations.CenterCrop(256, 256, p=1.),\n            albumentations.Resize(256, 256),\n            albumentations.Normalize(\n                mean=[0.485, 0.456, 0.406], \n                std=[0.229, 0.224, 0.225], \n                max_pixel_value=255.0, \n                p=1.0\n            )], p=1.)\n\ntrain_dataset = ImageDataset(\n    image_paths=train_image_paths,\n    targets=train_targets,\n    \n    augmentations=train_aug,\n)\n\nvalid_dataset = ImageDataset(\n    image_paths=valid_image_paths,\n    targets=valid_targets,\n    \n    augmentations=valid_aug,\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"es = EarlyStopping(\n    monitor=\"valid_accuracy\", model_path=\"model.bin\", patience=2, mode=\"max\"\n)\nmodel.fit(\n    train_dataset,\n    valid_dataset=valid_dataset,\n    train_bs=32,\n    valid_bs=64,\n    device=\"cuda\",\n    epochs=5,\n    callbacks=[es],\n    fp16=True,\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_dfx = pd.read_csv(\"../input/cassava-leaf-disease-classification/sample_submission.csv\")\nimage_path = \"../input/cassava-leaf-disease-classification/test_images/\"\ntest_image_paths = [os.path.join(image_path, x) for x in test_dfx.image_id.values]\n# fake targets\ntest_targets = test_dfx.label.values\n\n\ntest_aug = albumentations.Compose([\n            albumentations.CenterCrop(256, 256, p=1.),\n            albumentations.Resize(256, 256),\n            albumentations.Normalize(\n                mean=[0.485, 0.456, 0.406], \n                std=[0.229, 0.224, 0.225], \n                max_pixel_value=255.0, \n                p=1.0\n            )], p=1.)\n\ntest_dataset = ImageDataset(\n    image_paths=test_image_paths,\n    targets=test_targets,\n    \n    augmentations=test_aug,\n)\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds = model.predict(test_dataset, batch_size=32, n_jobs=-1)\nfinal_preds = None\nfor p in preds:\n    if final_preds is None:\n        final_preds = p\n    else:\n        final_preds = np.vstack((final_preds, p))\nfinal_preds = final_preds.argmax(axis=1)\ntest_dfx.label = final_preds\ntest_dfx.to_csv(\"submission.csv\", index=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}