{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import os\nimport gc\nimport cv2\nimport sys\nimport math\nimport time\nimport copy\nimport numpy as np\nimport pandas as pd\nfrom PIL import Image\nfrom pathlib import Path\nfrom tqdm.notebook import tqdm\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import train_test_split, StratifiedShuffleSplit\nPath.ls = lambda x: list(x.iterdir())\n\nimport albumentations\nfrom albumentations.pytorch import ToTensor, ToTensorV2\n\nimport torch\nfrom torch import nn, optim\nfrom torchvision import transforms, models\nimport torch.nn.functional as F\nfrom torch.utils.data import Dataset, DataLoader\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\neffnet_path = '../input/efficientnet-pytorch/'\nsys.path.append(effnet_path)\nfrom efficientnet_pytorch import EfficientNet\n\ntest_path = Path(\"../input/cassava-leaf-disease-classification/test_images\")\ntest_fnames = test_path.ls()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"This is the inference notebook. See the [training notebook](https://www.kaggle.com/moeinshariatnia/pytorch-better-normalization-onecycle-lr-train) if that is what you are interested in."},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"test_df = pd.read_csv(\"../input/cassava-leaf-disease-classification/sample_submission.csv\")\ntrain_df = pd.read_csv(\"../input/cassava-leaf-disease-classification/train.csv\")\nnum_classes = train_df['label'].nunique()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"mean = [0.4589, 0.5314, 0.3236]\nstd = [0.2272, 0.2297, 0.2200]\n\ntest_tfms = albumentations.Compose([\n    albumentations.RandomResizedCrop(256, 256),\n    albumentations.HorizontalFlip(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=mean, \n        std=std, \n        max_pixel_value=255.0, \n        p=1.0\n    ),\n    ToTensorV2()], p=1.)\n\nclass LeafDataTest(Dataset):\n    def __init__(self, df, split=\"test\"):\n        self.transforms = test_tfms\n        self.paths = [test_path/id_ for id_ in df['image_id'].values]\n    \n    def __getitem__(self, idx):\n        img = cv2.imread(str(self.paths[idx]))[..., ::-1]\n        img = self.transforms(image=img)['image']\n       \n        return img\n    \n    def __len__(self):\n        return len(self.paths)\n\ndef make_dataloaders(batch_size=32, num_workers=4, pin_memory=True, **kwargs):\n    dataset = LeafDataTest(**kwargs)\n    dataloader = DataLoader(dataset, batch_size=batch_size, num_workers=num_workers,\n                            pin_memory=pin_memory, shuffle=True if kwargs['split'] == \"train\" else False)\n    return dataloader","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_dl = make_dataloaders(df=test_df, split=\"test\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class EfficientNetModel(nn.Module):\n    def __init__(self, arch=\"b4\", dropout=0.2, n_out=5, \n                 pretrained=True, freeze=True):\n        super().__init__()\n        if pretrained:\n            self.model = EfficientNet.from_pretrained(f\"efficientnet-{arch}\")\n            if freeze:\n                for p in self.model.parameters():\n                    p.requires_grad = False\n        else:\n            self.model = EfficientNet.from_name(f\"efficientnet-{arch}\")\n        \n        self.lin1 = nn.Linear(1792 * 2, 512)\n        self.lin2 = nn.Linear(512, n_out)\n        self.bn1 = nn.BatchNorm1d(1792 * 2)\n        self.bn2 = nn.BatchNorm1d(512)\n        self.dropout = dropout\n        \n    def forward(self, x):\n        x = self.model.extract_features(x)\n        avg = F.adaptive_avg_pool2d(x, 1)\n        max_ = F.adaptive_max_pool2d(x, 1)\n        cat = torch.cat((avg.view(x.size(0), -1), max_.view(x.size(0), -1)), dim=1)\n        x = self.bn1(cat)\n        x = F.dropout(x, self.dropout)\n        x = F.relu(self.bn2(self.lin1(x)))\n        x = self.lin2(x)\n        return x","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Loading the saved weights"},{"metadata":{"trusted":true},"cell_type":"code","source":"model = model = EfficientNetModel(pretrained=False, freeze=False).to(device)\nmodel.load_state_dict(torch.load(\"../input/pytorch-better-normalization-onecycle-lr-train/effnet.pt\", map_location=device))\nmodel.eval();","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"This goes through the whole test set and concatenates all the predictions."},{"metadata":{"trusted":true},"cell_type":"code","source":"def inference_one_pass(model, test_dl):\n    model.eval()\n    all_preds = []\n    with torch.no_grad():\n        for batch in tqdm(test_dl):\n            preds = model(batch.to(device))\n            all_preds.append(preds)\n            \n    return torch.cat(all_preds, dim=0)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"We are doing TTA (test time augmentation). Each images is seen 5 times and finally we take the average of all the predictions."},{"metadata":{"trusted":true},"cell_type":"code","source":"num_passes = 5\ntta = None\nfor _ in range(num_passes):\n    all_preds = inference_one_pass(model, test_dl)\n    if tta is None:\n        tta = all_preds\n    else:\n        tta += all_preds\ntta /= float(num_passes)\nlabel_preds = tta.argmax(dim=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df['label'] = label_preds.cpu().numpy()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df.to_csv(\"submission.csv\", index=False)","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}