{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"_kg_hide-output":true},"cell_type":"code","source":"# !pip install efficientnet-pytorch\nimport sys\nsys.path = [\n    '../input/efficientnet-pytorch/EfficientNet-PyTorch/EfficientNet-PyTorch-master',\n] + sys.path\nsys.path = [\n    '../input/ttach-kaggle/ttach/',\n] + sys.path\nfrom efficientnet_pytorch import EfficientNet\n\n\nimport numpy as np \nimport pandas as pd \nfrom collections import Counter\nfrom sklearn.model_selection import train_test_split\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision.utils import make_grid\nfrom PIL import Image\nfrom tqdm.notebook import tqdm\nimport matplotlib.pyplot as plt\nimport torchvision.models as models\nimport torchvision.transforms as T\nimport torch.nn.functional as F\nimport torch.nn as nn\nimport json\nimport torch\nimport torchvision\nimport cv2\nimport PIL\nimport os\n\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\ndef seed_torch(seed=42):\n    random.seed(seed)\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.backends.cudnn.deterministic = True\n\nseed_torch()\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_image(path):\n    img = Image.open(path)\n    return img\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class GetDataset(Dataset):\n    def __init__(self, df, data_root, transforms = None, output_label = True):\n        super().__init__()\n        self.df = df.reset_index(drop=True).copy()\n        self.data_root = data_root\n        self.transforms = transforms\n        self.output_label = output_label\n        \n    def __len__(self):\n        return self.df.shape[0]\n    \n    def __getitem__(self, index: int):    #enforces index to be int\n            \n        path = \"{}/{}\".format(self.data_root, self.df.iloc[index]['image_id'])\n        img = get_image(path)         \n            \n        #if transforms exist then apply transforms\n        if self.transforms:\n            img = self.transforms(img)\n            \n        #if label exists then get label and return\n        if self.output_label:\n            label = self.df.iloc[index]['label']\n            return img, label\n        else:\n            return img","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_device():\n    if torch.cuda.is_available():\n        return torch.device(\"cuda\")\n    else:\n        return torch.device(\"cpu\")\n    \ndef to_device(data, device):\n    if isinstance(data, (list,tuple)):\n        return [to_device(x, device) for x in data]\n    return data.to(device, non_blocking=True)\n\nclass DeviceDataLoader():\n    def __init__(self, dl, device):\n        self.dl = dl\n        self.device = device\n    \n    def __iter__(self):\n        for x in self.dl:\n            yield to_device(x, self.device)\n            \n    def __len__(self):\n        return len(self.dl)\n\ndevice = get_device()\ndevice","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def accuracy(out, labels):\n    _, preds = torch.max(out, dim=1)\n    return torch.tensor(torch.sum(preds == labels).item() / len(preds))\n\nclass ImageClassificationBase(nn.Module):\n    def training_step(self, batch):\n        images, labels = batch\n        out = self(images)\n        loss = F.cross_entropy(out, labels)\n        return loss\n    \n    def validation_step(self, batch):\n        images, labels = batch\n        out = self(images)\n        loss = F.cross_entropy(out, labels)\n        acc = accuracy(out, labels)\n        return {\"val_loss\": loss.detach(), \"val_acc\": acc}\n    \n    def validation_epoch_end(self, outputs):\n        batch_loss = [x[\"val_loss\"] for x in outputs]\n        epoch_loss = torch.stack(batch_loss).mean()\n        batch_acc = [x[\"val_acc\"] for x in outputs]\n        epoch_acc = torch.stack(batch_acc).mean()\n        return {\"val_loss\": epoch_loss.item(), \"val_acc\": epoch_acc.item()}\n    \n    def epoch_end(self, epoch, epochs, result):\n        print(\"Epoch: [{}/{}], last_lr: {:.6f}, train_loss: {:.4f}, val_loss: {:.4f}, val_acc: {:.4f}\".format(\n        epoch, epochs, result[\"lrs\"][-1], result[\"train_loss\"], result[\"val_loss\"], result[\"val_acc\"]))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class Classifier(ImageClassificationBase):\n    def __init__(self):\n        super().__init__()\n        self.network = EfficientNet.from_name('efficientnet-b4')\n        number_of_features =  self.network._fc.in_features\n        self.network._fc = nn.Linear(number_of_features, 5)\n        \n    def forward(self, xb):\n        return self.network(xb)\n        \n    def freeze(self):\n        for param in self.network.parameters():\n            param.requires_grad=False\n        for param in self.network._fc.parameters():\n            param.requires_grad=True\n        \n    def unfreeze(self):\n        for param in self.network.parameters():\n            param.requires_grad=True\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true,"_kg_hide-output":true},"cell_type":"code","source":"model = torch.load('../input/cassava-leaf-disease-detection-efficientnet-b5/mod.pth', map_location=torch.device(device) )\n\nfor parameter in model.parameters():\n    parameter.requires_grad = False\n\nmodel.eval()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"BATCH_SIZE = 128\nIMG_SIZE = 512 \nIMG_SHAPE = (IMG_SIZE, IMG_SIZE)\nTEST_DIR = '../input/cassava-leaf-disease-classification/test_images'\n\ntest_transforms = T.Compose([\n    T.Resize(IMG_SHAPE),\n    T.ToTensor(),\n    T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),\n\n])\n\ntest_images = os.listdir(TEST_DIR)\ntest_csv = pd.DataFrame()\ntest_csv[\"image_id\"] = test_images\n\ntest_ds = GetDataset(\n    test_csv,\n    TEST_DIR,\n    transforms = test_transforms,\n    output_label = False\n)\n\ntest = torch.utils.data.DataLoader(\n    test_ds,\n    batch_size = BATCH_SIZE,\n    num_workers = 2,\n    shuffle = False,\n    pin_memory = False\n)\n\ntest = DeviceDataLoader(test, device)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def inference(model, test_loader, device):\n    model.to(device)\n    tk0 = tqdm(enumerate(test_loader), total=len(test_loader))\n    probs = []\n\n    for i, (images) in tk0:\n        preds = []\n        \n        model.eval()\n        with torch.no_grad():\n            y_preds = model(images)\n        preds.append(y_preds.softmax(1).to('cpu').numpy())\n        \n        probs.append(preds)\n    \n    probs = np.concatenate(probs, axis=1)\n    print(\"predictions shape : \", probs.shape)\n    return probs\n\npredictions = inference(model, test, device)\ntest_csv['label'] = predictions.argmax(2).reshape((len(test_images)))\ntest_csv[['image_id', 'label']].to_csv('./submission.csv', index=False)\nprint(test_csv)\n","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}