{"cells": [{"cell_type": "code", "execution_count": null, "metadata": {"trusted": true, "_kg_hide-input": true, "_kg_hide-output": true}, "outputs": [], "source": ["def __bootstrap__():\n    import sys\n    import base64\n    import gzip\n    import tarfile\n    import os\n    import io\n    from pathlib import Path\n    from tempfile import TemporaryDirectory\n\n    # install required packages\n    pkg_dataset_path = Path.cwd().parent / \"input\" / \"dogs-vs-cats-efficientnet-requirements\"\n    pkg_path_list = []\n    for p in pkg_dataset_path.glob(\"*\"):\n        if p.is_dir():\n            pkg_config_files = [str(p.parent) for p in p.glob(\"**/*\") if p.name in [\"pyproject.toml\", \"setup.py\"]]\n            pkg_root_dir = min(pkg_config_files, key=len)\n            pkg_path_list.append(pkg_root_dir)\n        else:\n            pkg_path_list.append(str(p))\n    if 0 < len(pkg_path_list):\n        pkg_paths = \" \".join(pkg_path_list)\n        os.system(f\"pip install --no-deps {pkg_paths}\")\n\n    # this is base64 encoded source code\n    tar_io = io.BytesIO(gzip.decompress(base64.b64decode(\"H4sIAEZzDF8C/0vJTy+OLyuOT04sKY5PTUvLTM5MzSvJSy3RNdAz1DPQLag01s3Lz0vVTcyr1CvPyGEgAxgAgZmJCZgGAnTayNjMEMaGiBuam5saMigYMNABlBaXJBYpKFBsDrrnhggI8GZmEQHSHECsCBZhgsqoAnEKrtShHx+fmZdZEh+vV1DJjGqIR2fOyi8BQFYwEOvjMwSSxPRSMotLdDPz0vL1wz1cXX24z3v4nr3I662rde7M+c1BBleMHxT5n/XW9dI5qb8pSOOEv67mKpZOpqPNnz57l9h2lzJ7dQcVG01eI+LV5RW800nocuMrrd7Sz58+B5UKf9baieY4mV9L/gszAllAbxqR5Dhf1xBHF8cQx6kTD3oxGwq0vf8tYqllcjhv+67SzO5F7tqujv2pN+amsZt7+m6aum+vp7bWJW99xTM19+2ZNy9p0GWbsv6JTXRwt6HITeGsVa7ZU6db60vzxF1KO8w7mbPN6Rvz8wCHeXt5ohbfvq60W9opPVZ32ouNyelHo33+r/O6dKJW94Jm9oPz1auDmKVWb07/JXFj4vTVtSGPGo7uackymX1E87tt1XnpZTP2F4VZXpnVK9SfcaWhy0X2Nbvu31PFlSvOmS3b/9tuA//Gk7X59kePJsUdlPh0MYfL8sn0/xvLQ1YtL01Yez3a/aCidNbkac4zt8ioqW95axdxvWRT+lXWyWLWEsE7vI6d5VT2tXBindJ+56Om1tJ3FrFfOOKdJ97Q2hiPGsQfwo6+uAVkxQGD2YCkIA5ydfYPcpl69mBUE1Djg93nNylyeNuUKEhIuan1eOj9vsA785CC+ZGqX35y1j+Y/p/ftXhRuCv/0rAp4VMtOPS2PqnyWjnBKTjri73D1ac8trbWnxnyf0/eXeXp7XEye7azyM+aG5+e3Fn0fUf/p6TM6y8F0g7M2fA/I0NqWqKUjwZv65pdmfsO/Xg7b4m4rv20+SrPdse8dtPNM/ru052+Nf6Gs+gmjdtv157Yd4Bnxzdm755O8Yoju92v/ahtWpfhXllW9/GGyBML7kT5zQdiHz/Z9jJl87zVR8O3lTMUXWAObvrrK8Rg8JM5wJuRSYQZd3aDgSWNDMRmPjQjMTIf3EhGV9KzIrrh6JkHYfgjsrISuvnoKQfJ8Uykp6MAb1Y2kG4WIMwDmpjLzDAKRsEoGAWjYBSMglEwCkbBKBgFo2AUjIJRMApGwSgYBaNgFIyCUTAKRsEoGAWjYBSMglEw/AAAxjVP1AAoAAA=\")))\n    with TemporaryDirectory() as temp_dir:\n        with tarfile.open(fileobj=tar_io) as tar:\n            for member in tar.getmembers():\n                pkg_path = Path(temp_dir) / f\"{member.name}\"\n                content_bytes = tar.extractfile(member).read()\n                pkg_path.write_bytes(content_bytes)\n                os.system(\"pip install --no-deps {pkg_path}\".format(pkg_path=pkg_path))\n\n    sys.path.append(\"/kaggle/working\")\n    os.environ.update({})\n__bootstrap__()"]}, {"cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": ["import os\n", "import torch\n", "import torch.nn.functional as F\n", "import pytorch_lightning as pl\n", "from torch.utils.data import Dataset, DataLoader\n", "import timm\n", "from pathlib import Path\n", "from torchvision import transforms\n", "from PIL import Image\n", "import zipfile"]}, {"cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": ["if \"KAGGLE_CONTAINER_NAME\" in os.environ:\n", "    import kaggle_timm_pretrained\n", "    kaggle_timm_pretrained.patch()"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["ROOT_DIR =  Path(os.environ.get(\"ROOT_DIR\", \"../input/dogs-vs-cats\"))\n", "with zipfile.ZipFile(str(ROOT_DIR / \"train.zip\"),\"r\") as z:\n", "    z.extractall(\".\")\n", "\n", "with zipfile.ZipFile(str(ROOT_DIR / \"test1.zip\"),\"r\") as z:\n", "    z.extractall(\".\")\n", "    \n", "TRAIN_DATA_DIR = Path(\"/kaggle/working/train\")\n", "TEST_DATA_DIR = Path(\"/kaggle/working/test1\")"]}, {"cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": ["class DogsVsCatsDataset(Dataset):\n", "    def __init__(self,  root_dir, transform=None, train=True):\n", "        self._transform = transform\n", "        self._train = train\n", "        self._img_paths =list(root_dir.glob(\"*.jpg\"))\n", "        if not self._train:\n", "            self._img_paths = sorted(self._img_paths, key=lambda p:int(int(p.stem)))\n", "        \n", "    def __len__(self):\n", "        return len(self._img_paths)\n", "    \n", "    def __getitem__(self, idx):\n", "        if torch.is_tensor(idx):\n", "            idx = idx.tolist()\n", "        \n", "        img_path = self._img_paths[idx]\n", "        img = Image.open(img_path)\n", "        if self._transform:\n", "            img = self._transform(img)\n", "            \n", "        if self._train:\n", "            label = int(img_path.name.startswith(\"dog\"))\n", "            return img, label\n", "        return img"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["class Network(pl.LightningModule):\n", "    def __init__(self):\n", "        super().__init__()\n", "        self.net = timm.create_model(\"efficientnet_b2\", pretrained=True, num_classes=2)\n", "        \n", "    def forward(self, x):\n", "        return self.net(x)\n", "    \n", "    def training_step(self, batch, batch_idx):\n", "        x, y = batch\n", "        loss = F.cross_entropy(self(x), y)\n", "        return {'loss': loss}\n", "    \n", "    def configure_optimizers(self):\n", "        return torch.optim.Adam(self.parameters(), lr=0.02)\n", "    \n", "    def setup(self, stage):\n", "        train_dataset = DogsVsCatsDataset(\n", "            TRAIN_DATA_DIR,\n", "            transform=transforms.Compose([\n", "                transforms.Resize((224, 224)), \n", "                transforms.ToTensor()\n", "            ])\n", "        )\n", "        train_size = int(len(train_dataset) * 0.8)\n", "        val_size = int(len(train_dataset) - train_size)\n", "        self._train_dataset, self._val_dataset = torch.utils.data.random_split(train_dataset, [train_size, val_size])\n", "        self._test_dataset =DogsVsCatsDataset(\n", "            TEST_DATA_DIR,\n", "            transform=transforms.Compose([\n", "                transforms.Resize((224, 224)), \n", "                transforms.ToTensor()\n", "            ]),\n", "            train=False\n", "        )     \n", "    \n", "    def train_dataloader(self):\n", "        return DataLoader(self._train_dataset, batch_size=32, num_workers=4, shuffle=True)\n", "\n", "    def validation_step(self, batch, batch_idx):\n", "        x ,y = batch\n", "        loss = F.cross_entropy(self(x), y)\n", "        return {'val_loss': loss}\n", "    \n", "    def validation_epoch_end(self, outputs):\n", "        avg_loss = torch.stack([x['val_loss'] for x in outputs]).mean()\n", "        return {\"val_loss\": avg_loss}\n", "    \n", "    def val_dataloader(self):\n", "        return DataLoader(self._val_dataset, batch_size=4, num_workers=4)\n", "    \n", "    def test_step(self, batch, batch_idx):\n", "        x = batch\n", "        label = torch.argmax(self(x), dim=1)\n", "        return {\"label\": (batch_idx, label)}\n", "\n", "    def test_epoch_end(self, outputs):\n", "        return dict([x[\"label\"] for x in outputs])\n", "    \n", "    def test_dataloader(self):\n", "        return DataLoader(self._test_dataset, batch_size=1)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["model = Network()\n", "trainer = pl.Trainer(gpus=1, max_epochs=10)\n", "trainer.fit(model)"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["result = trainer.test()"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["submission_csv = \"\\n\".join([f\"{id},{label}\" for id, label in result.items()])\n", "Path(\"./submission.csv\").write_text(submission_csv)"]}], "metadata": {"kernelspec": {"display_name": "Python 3", "language": "python", "name": "python3"}, "language_info": {"codemirror_mode": {"name": "ipython", "version": 3}, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.3"}}, "nbformat": 4, "nbformat_minor": 4}