{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"#!pip install tez\n#!pip install efficientnet-pytorch","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Setting up the tez library and efficent pytorch for offline use**"},{"metadata":{"trusted":true},"cell_type":"code","source":"tez_path = '../input/tez-lib/'\neffnet_path = '../input/efficientnet-pytorch/'\nimport sys\nsys.path.append(tez_path)\nsys.path.append(effnet_path)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import os\nimport albumentations\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\nfrom efficientnet_pytorch import EfficientNet\nfrom sklearn import metrics, model_selection, preprocessing","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class LeafModel(tez.Model):\n    def __init__(self, num_classes):\n        super().__init__()\n\n        self.effnet = EfficientNet.from_pretrained(\"efficientnet-b4\")\n        self.dropout = nn.Dropout(0.1)\n        self.out = nn.Linear(1792, 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=3e-4)\n        return opt\n    \n    def fetch_scheduler(self):\n        sch = torch.optim.lr_scheduler.CosineAnnealingWarmRestarts(\n            self.optimizer, T_0=10, T_mult=1, eta_min=1e-6, last_epoch=-1\n        )\n        return sch\n\n    def forward(self, image, targets=None):\n        batch_size, _, _, _ = image.shape\n\n        x = self.effnet.extract_features(image)\n        x = F.adaptive_avg_pool2d(x, 1).reshape(batch_size, -1)\n        outputs = self.out(self.dropout(x))\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":"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.HueSaturationValue(\n                hue_shift_limit=0.2, \n                sat_shift_limit=0.2, \n                val_shift_limit=0.2, \n                p=0.5\n            ),\n            albumentations.RandomBrightnessContrast(\n                brightness_limit=(-0.1,0.1), \n                contrast_limit=(-0.1, 0.1), \n                p=0.5\n            ),\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            albumentations.CoarseDropout(p=0.5),\n            albumentations.Cutout(p=0.5)], p=1.)\n  \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.)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dfx = pd.read_csv('../input/cassava-leaf-disease-classification/train.csv')\ndfx = dfx.dropna().reset_index(drop=True)\ndfx[\"kfold\"] = -1\n\ndfx = dfx.sample(frac=1).reset_index(drop=True)\n\nkf = model_selection.StratifiedKFold(n_splits=5)\n\nfor fold, (trn_, val_) in enumerate(kf.split(X=dfx, y=dfx.label.values)):\n    print(len(trn_), len(val_))\n    dfx.loc[val_, 'kfold'] = fold","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def run(fold):\n    model_p = f\"model_fold{fold}.bin\"\n    df_train = dfx[dfx.kfold != fold].reset_index(drop=True)\n    df_valid = dfx[dfx.kfold == fold].reset_index(drop=True)\n\n    df_train = df_train.reset_index(drop=True)\n    df_valid = df_valid.reset_index(drop=True)\n\n    image_path = \"../input/cassava-leaf-disease-classification/train_images/\"\n    train_image_paths = [os.path.join(image_path, x) for x in df_train.image_id.values]\n    valid_image_paths = [os.path.join(image_path, x) for x in df_valid.image_id.values]\n    train_targets = df_train.label.values\n    valid_targets = df_valid.label.values\n\n    train_dataset = ImageDataset(\n        image_paths=train_image_paths,\n        targets=train_targets,\n        #resize=None,\n        augmentations=train_aug,\n    )\n\n    valid_dataset = ImageDataset(\n        image_paths=valid_image_paths,\n        targets=valid_targets,\n        #resize=None,\n        augmentations=valid_aug,\n    )\n    \n    model = LeafModel(num_classes=dfx.label.nunique())\n    es = EarlyStopping(monitor=\"valid_loss\", model_path=model_p, patience=3, mode=\"min\")\n    model.fit(\n        train_dataset,\n        valid_dataset=valid_dataset,\n        train_bs=64,\n        valid_bs=64,\n        device=\"cuda\",\n        epochs=10,\n        callbacks=[es],\n        fp16=True,\n    )\n    model.save(model_p)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for fold in range(5):\n    run(fold)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Inference Code"},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\nimport albumentations\nimport pandas as pd\nimport numpy as np\n\nimport tez\nfrom tez.datasets import ImageDataset\n\nimport torch\nimport torch.nn as nn\nfrom torch.nn import functional as F\n\nfrom efficientnet_pytorch import EfficientNet","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_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.HueSaturationValue(\n        hue_shift_limit=0.2, \n        sat_shift_limit=0.2,\n        val_shift_limit=0.2, \n        p=0.5\n    ),\n    albumentations.RandomBrightnessContrast(\n        brightness_limit=(-0.1,0.1), \n        contrast_limit=(-0.1, 0.1), \n        p=0.5\n    ),\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], p=1.)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"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 dfx.image_id.values]\n# fake targets\ntest_targets = dfx.label.values\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":"train_dfx = pd.read_csv(\"../input/cassava-leaf-disease-classification/train.csv\")\nmodel0 = LeafModel(num_classes=train_dfx.label.nunique())\nmodel0.load(\"model_fold0.bin\")\n\nmodel1 = LeafModel(num_classes=train_dfx.label.nunique())\nmodel1.load(\"model_fold1.bin\")\n\nmodel2 = LeafModel(num_classes=train_dfx.label.nunique())\nmodel2.load(\"model_fold2.bin\")\n\nmodel3 = LeafModel(num_classes=train_dfx.label.nunique())\nmodel3.load(\"model_fold3.bin\")\n\nmodel4 = LeafModel(num_classes=train_dfx.label.nunique())\nmodel4.load(\"model_fold4.bin\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from statistics import mode\ndef run_inference(model):\n    # run inference 5 times\n    final_preds = None\n    for j in range(5):\n        preds = model.predict(test_dataset, batch_size=32, n_jobs=-1, device=\"cuda\")\n        temp_preds = None\n        for p in preds:\n            if temp_preds is None:\n                temp_preds = p\n            else:\n                temp_preds = np.vstack((temp_preds, p))\n        if final_preds is None:\n            final_preds = temp_preds\n        else:\n            final_preds += temp_preds\n    final_preds /= 5\n    final_preds = final_preds.argmax(axis=1)\n    return final_preds\n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"new_df = pd.DataFrame()\nnew_df['model0'] = run_inference(model0)\nnew_df['model1'] = run_inference(model1)\nnew_df['model2'] = run_inference(model2)\nnew_df['model3'] = run_inference(model3)\nnew_df['model4'] = run_inference(model4)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"new_df.head()\n\nfinal_output = list()\nfor index, row in new_df.iterrows(): \n    mode_row = list()\n    mode_row = [row['model0'], row['model1'], row['model2'], row['model3'], row['model4']]\n    output = mode(mode_row)\n    if output not in [0,1,2,3,4]:\n        output = row['model0']\n    final_output.append(output)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dfx.label = final_output\ndfx.to_csv(\"submission.csv\", index=False)\n","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}