{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# Tez is currently not available on kaggle but you can install it using pip \n# or just add tez-lib dataset to the python path.\n# If internet is enabled (and allowed), you can just install using pip\n!pip install tez","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"# If internet is disabled, you can add it to path after \n# including https://www.kaggle.com/abhishek/tez-lib\n# dataset to your kernel\n#\n# Add the following lines of the code to top of your kernel, \n# if you cannot install using pip\n#\n# tez_path = '../input/tez-lib/'\n# import sys\n# sys.path.append(tez_path)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Everything becomes easy and intuitive from here. \n# Also, Tez keeps your code clean and readable!\n# Let's import a few things.\n\nimport 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","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Let's read the CSV file\ndfx = 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","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Now, lets add some augmentations using one of the best\n# augmentations library: albumentations\n# Tez supports albumentations exclusively\n\ntrain_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    augmentations=train_aug,\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"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)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_image(train_dataset[0])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Let's define a model now\n# We inherit from tez.Model instead of nn.Module\n# we have monitor_metrics if we want to monitor any metrics\n# except the loss\n# and we return 3 values in forward function.\n\nclass 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","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = LeafModel(num_classes=5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image = train_dataset[0][\"image\"].unsqueeze(0)\ntarget = train_dataset[0][\"targets\"].unsqueeze(0)\n\n\nmodel(image, target)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"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    augmentations=train_aug,\n)\n\nvalid_dataset = ImageDataset(\n    image_paths=valid_image_paths,\n    targets=valid_targets,\n    augmentations=valid_aug,\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"es = EarlyStopping(\n    monitor=\"valid_accuracy\", model_path=\"model.bin\", patience=3, mode=\"max\"\n)\nmodel.fit(\n    train_dataset,\n    valid_dataset=valid_dataset,\n    train_bs=32,\n    valid_bs=64,\n    epochs=10,\n    callbacks=[es],\n    fp16=True,\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"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\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    augmentations=test_aug,\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"preds = model.predict(test_dataset, batch_size=32, n_jobs=-1, device=\"cuda\")\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)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","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}