{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\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","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-10-01T14:25:03.155907Z","iopub.execute_input":"2023-10-01T14:25:03.156830Z","iopub.status.idle":"2023-10-01T14:25:03.502636Z","shell.execute_reply.started":"2023-10-01T14:25:03.156791Z","shell.execute_reply":"2023-10-01T14:25:03.501668Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!unzip /kaggle/input/dogs-vs-cats/test1.zip","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2023-10-01T14:25:03.504555Z","iopub.execute_input":"2023-10-01T14:25:03.505259Z","iopub.status.idle":"2023-10-01T14:25:11.268790Z","shell.execute_reply.started":"2023-10-01T14:25:03.505225Z","shell.execute_reply":"2023-10-01T14:25:11.267665Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!unzip /kaggle/input/dogs-vs-cats/train.zip","metadata":{"execution":{"iopub.status.busy":"2023-10-01T14:25:11.270702Z","iopub.execute_input":"2023-10-01T14:25:11.271690Z","iopub.status.idle":"2023-10-01T14:25:26.129470Z","shell.execute_reply.started":"2023-10-01T14:25:11.271648Z","shell.execute_reply":"2023-10-01T14:25:26.128245Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nfrom os import path\n\nfrom torch.utils.data import Dataset\nimport torchvision\n\nfrom PIL import Image\n\nclass DogCatDataset(Dataset):\n\n    def __init__(self, root, transforms=torchvision.transforms.ToTensor()):\n        super().__init__()\n        self.dataset_root = root\n        \n        self.image_list = get_files(root)\n        self.image_labels = get_image_label(self.image_list)\n\n        self.chars = sorted(list(set(self.image_labels)))\n        self.stoi = {s:i for i, s in enumerate(self.chars)}\n\n        self.dataset = list(zip(self.image_list, self.image_labels))\n\n        self.transforms = transforms\n\n\n    def __len__(self):\n        return len(self.dataset)\n\n    def __getitem__(self, idx):\n        image, label = self.dataset[idx]\n\n        image = Image.open(path.join(self.dataset_root, image))\n\n        if self.transforms:\n            image = self.transforms(image)\n\n        return image, self.stoi[label]\n\n    \ndef get_image_label(image_list):\n    return [x.split(\".\")[0] for x in image_list]\n\n\ndef get_files(root):\n    return [x for x in os.listdir(root) if path.isfile(path.join(root, x))]\n\ndef get_idx2label(label_list):\n    return dict(enumerate(set(label_list)))","metadata":{"execution":{"iopub.status.busy":"2023-10-01T14:25:26.132722Z","iopub.execute_input":"2023-10-01T14:25:26.133747Z","iopub.status.idle":"2023-10-01T14:25:29.876499Z","shell.execute_reply.started":"2023-10-01T14:25:26.133704Z","shell.execute_reply":"2023-10-01T14:25:29.875512Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\n\ndef convblock(out_channels=6):\n    return nn.Sequential(\n        nn.LazyConv2d(out_channels, kernel_size=3),\n        nn.LazyBatchNorm2d(),\n        nn.Sigmoid(),\n        nn.AvgPool2d(kernel_size=3)\n    )\n\nclass SmallCNN(nn.Module):\n    \n    def __init__(self, out_n_classes):\n        super().__init__()\n\n        self.net = nn.Sequential(\n            convblock(2),\n            # convblock(6),\n            nn.Flatten(),\n            # nn.LazyLinear(120),\n            # nn.LazyBatchNorm1d(),\n            # nn.Sigmoid(),\n            nn.LazyLinear(32),\n            nn.LazyBatchNorm1d(),\n            nn.Sigmoid(),\n            nn.LazyLinear(out_n_classes)\n        )\n\n    def forward(self, X):\n        return self.net(X)\n","metadata":{"execution":{"iopub.status.busy":"2023-10-01T14:25:29.881126Z","iopub.execute_input":"2023-10-01T14:25:29.881830Z","iopub.status.idle":"2023-10-01T14:25:29.889618Z","shell.execute_reply.started":"2023-10-01T14:25:29.881800Z","shell.execute_reply":"2023-10-01T14:25:29.888566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Average:\n    def __init__(self):\n\n        self.val = 0.0\n        self.n = 0.0\n\n    def __add__(self, x):\n\n        self.val += x\n        self.n += 1\n\n        return self\n\n    def item(self):\n\n        return self.val / self.n","metadata":{"execution":{"iopub.status.busy":"2023-10-01T14:25:29.890697Z","iopub.execute_input":"2023-10-01T14:25:29.891504Z","iopub.status.idle":"2023-10-01T14:25:29.907719Z","shell.execute_reply.started":"2023-10-01T14:25:29.891474Z","shell.execute_reply":"2023-10-01T14:25:29.906839Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport torchvision\nfrom tqdm.notebook import tqdm\n\n\nn_epoch = 10\n\ntransforms = torchvision.transforms.Compose([\n    torchvision.transforms.Resize(54),\n    torchvision.transforms.CenterCrop(54),\n    torchvision.transforms.ToTensor()\n])\n\ndataset = DogCatDataset(\"/kaggle/working/train\", transforms=transforms)\ntrain_data, val_data = torch.utils.data.random_split(dataset, [0.9, 0.1])\n\ntrain_loader = torch.utils.data.DataLoader(train_data, batch_size=64, shuffle=True)\nval_loader = torch.utils.data.DataLoader(val_data, batch_size=64, shuffle=False)\n\ndevice = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n\nmodel = SmallCNN(out_n_classes=2)\nmodel = model.to(device)\n\nloss_fn = torch.nn.CrossEntropyLoss()\n\noptim = torch.optim.Adam(model.parameters(), lr=1e-2)\nscheduler1 = torch.optim.lr_scheduler.LinearLR(optimizer=optim, total_iters=n_epoch*0.1)\nscheduler2 = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer=optim, T_max=n_epoch*0.9)\n\n# Training Loop\n\nepoch_logger = tqdm(range(n_epoch))\n\nfor i in epoch_logger:\n    \n    train_loss_avg = Average()\n    val_loss_avg = Average()\n\n    model.train()\n    \n    train_logger = tqdm(train_loader)\n    \n    for X, y in train_logger:\n        \n        X = X.to(device)\n        y = y.to(device)\n        \n        optim.zero_grad()\n\n        preds = model(X)\n\n        loss = loss_fn(preds, y)\n        loss.backward()\n\n        optim.step()\n\n        train_loss_avg += loss.item()\n        \n    model.eval()\n    with torch.no_grad():\n        for X, y in tqdm(val_loader):\n\n            X = X.to(device)\n            y = y.to(device)\n            \n            \n            preds = model(X)\n            loss = loss_fn(preds, y)\n            val_loss_avg += loss.item()\n\n\n    epoch_logger.set_description(f\"Avg train loss: {train_loss_avg.item()} | Avg valid loss: {val_loss_avg.item()}\")    \n\n","metadata":{"execution":{"iopub.status.busy":"2023-10-01T14:25:29.909093Z","iopub.execute_input":"2023-10-01T14:25:29.909752Z","iopub.status.idle":"2023-10-01T14:35:07.359638Z","shell.execute_reply.started":"2023-10-01T14:25:29.909703Z","shell.execute_reply":"2023-10-01T14:35:07.358647Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"check_x, check_y = next(iter(val_loader))","metadata":{"execution":{"iopub.status.busy":"2023-10-01T14:43:52.045455Z","iopub.execute_input":"2023-10-01T14:43:52.046192Z","iopub.status.idle":"2023-10-01T14:43:52.183786Z","shell.execute_reply.started":"2023-10-01T14:43:52.046158Z","shell.execute_reply":"2023-10-01T14:43:52.182859Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds = model(check_x.to(device))","metadata":{"execution":{"iopub.status.busy":"2023-10-01T14:44:17.466191Z","iopub.execute_input":"2023-10-01T14:44:17.466515Z","iopub.status.idle":"2023-10-01T14:44:17.472619Z","shell.execute_reply.started":"2023-10-01T14:44:17.466489Z","shell.execute_reply":"2023-10-01T14:44:17.471747Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred_class = torch.nn.functional.softmax(preds).max(1)[1].tolist()","metadata":{"execution":{"iopub.status.busy":"2023-10-01T14:44:36.374933Z","iopub.execute_input":"2023-10-01T14:44:36.376025Z","iopub.status.idle":"2023-10-01T14:44:36.382502Z","shell.execute_reply.started":"2023-10-01T14:44:36.375982Z","shell.execute_reply":"2023-10-01T14:44:36.381442Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset.chars[pred_class[0]]","metadata":{"execution":{"iopub.status.busy":"2023-10-01T14:43:19.794524Z","iopub.execute_input":"2023-10-01T14:43:19.795665Z","iopub.status.idle":"2023-10-01T14:43:19.802754Z","shell.execute_reply.started":"2023-10-01T14:43:19.795616Z","shell.execute_reply":"2023-10-01T14:43:19.801656Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nn = 4\n\nplt.imshow(check_x[n].permute(1,2,0).numpy())\nplt.title(f\"Prediction: {dataset.chars[pred_class[n]]}\")","metadata":{"execution":{"iopub.status.busy":"2023-10-01T14:48:12.005952Z","iopub.execute_input":"2023-10-01T14:48:12.006323Z","iopub.status.idle":"2023-10-01T14:48:12.305580Z","shell.execute_reply.started":"2023-10-01T14:48:12.006283Z","shell.execute_reply":"2023-10-01T14:48:12.304562Z"},"trusted":true},"execution_count":null,"outputs":[]}]}