{"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-07-29T08:06:34.601661Z","iopub.execute_input":"2023-07-29T08:06:34.602109Z","iopub.status.idle":"2023-07-29T08:06:34.613686Z","shell.execute_reply.started":"2023-07-29T08:06:34.602071Z","shell.execute_reply":"2023-07-29T08:06:34.61253Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport shutil\nimport torch\nimport random\nimport numpy as np\nfrom torchvision import transforms\nfrom torch.utils.data import Dataset\nfrom sklearn.model_selection import train_test_split\nfrom torch.utils.data import DataLoader\nimport torch.nn as nn\nimport time\nfrom PIL import Image\nimport matplotlib.pyplot as plt","metadata":{"execution":{"iopub.status.busy":"2023-07-29T08:06:34.615563Z","iopub.execute_input":"2023-07-29T08:06:34.615902Z","iopub.status.idle":"2023-07-29T08:06:34.628978Z","shell.execute_reply.started":"2023-07-29T08:06:34.615877Z","shell.execute_reply":"2023-07-29T08:06:34.628067Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#import os\n#import shutil\n\nbase_dir = '../input/dogs-vs-cats-redux-kernels-edition'\ntrain_dir = '../data/train'\ntest_dir = '../data/test'\n\nshutil.unpack_archive(os.path.join(base_dir, 'train.zip'), '../data')\nshutil.unpack_archive(os.path.join(base_dir, 'test.zip'), '../data')\n\ntrain_list = [os.path.join(train_dir, filename) for filename in os.listdir(train_dir) if filename.endswith('.jpg')]\ntest_list = [os.path.join(test_dir, filename) for filename in os.listdir(test_dir) if filename.endswith('.jpg')]","metadata":{"execution":{"iopub.status.busy":"2023-07-29T08:06:34.630478Z","iopub.execute_input":"2023-07-29T08:06:34.630818Z","iopub.status.idle":"2023-07-29T08:06:48.19306Z","shell.execute_reply.started":"2023-07-29T08:06:34.630787Z","shell.execute_reply":"2023-07-29T08:06:48.192057Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#import torch\n#import random\n#import numpy as np\n\nSEED = 1\n\ndevice = 'cuda' if torch.cuda.is_available() else 'cpu'\n\ntorch.manual_seed(SEED)\nif device =='cuda':\n    torch.cuda.manual_seed(SEED)\n\nrandom.seed(SEED)\nnp.random.seed(SEED)\ntorch.backends.cudnn.deterministic = True\ntorch.backends.cudnn.benchmark = False\n\nprint(\"device:\", device)","metadata":{"execution":{"iopub.status.busy":"2023-07-29T08:06:48.197327Z","iopub.execute_input":"2023-07-29T08:06:48.197629Z","iopub.status.idle":"2023-07-29T08:06:48.214895Z","shell.execute_reply.started":"2023-07-29T08:06:48.197595Z","shell.execute_reply":"2023-07-29T08:06:48.212185Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#from torchvision import transforms\n\ndata_transforms = {\n    'train': transforms.Compose([\n        transforms.RandomResizedCrop([512,512]),\n        transforms.RandomHorizontalFlip(),\n        transforms.Resize([256,256]),\n        transforms.ToTensor(),\n    ]),\n    'test': transforms.Compose([\n        transforms.Resize([256,256]),\n        transforms.ToTensor()\n    ])\n}","metadata":{"execution":{"iopub.status.busy":"2023-07-29T08:06:48.216486Z","iopub.execute_input":"2023-07-29T08:06:48.217133Z","iopub.status.idle":"2023-07-29T08:06:49.027329Z","shell.execute_reply.started":"2023-07-29T08:06:48.217086Z","shell.execute_reply":"2023-07-29T08:06:49.026187Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#from torch.utils.data import Dataset\n\nclass Dataset(Dataset):\n    def __init__(self, file_list, transform=None):\n        self.file_list = file_list\n        self.transform = transform\n        \n    def __len__(self):\n        return len(self.file_list)\n    \n    def __getitem__(self, idx):\n        img_path = self.file_list[idx]\n        img = Image.open(img_path)\n        if self.transform is not None:\n            img = self.transform(img)\n        label = img_path.split('/')[-1].split('.')[0]\n        label = 0 if label == 'cat' else 1\n            \n        return img, label","metadata":{"execution":{"iopub.status.busy":"2023-07-29T08:06:49.029149Z","iopub.execute_input":"2023-07-29T08:06:49.029856Z","iopub.status.idle":"2023-07-29T08:06:49.040337Z","shell.execute_reply.started":"2023-07-29T08:06:49.029821Z","shell.execute_reply":"2023-07-29T08:06:49.039599Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#from sklearn.model_selection import train_test_split\n#from torch.utils.data import DataLoader\n\ntrlist, valist = train_test_split(train_list, test_size=0.1, random_state=SEED)\n\ntr_ds = Dataset(trlist, transform=data_transforms['train'])\nva_ds = Dataset(valist, transform=data_transforms['test'])\nte_ds = Dataset(test_list, transform=data_transforms['test'])\n\nbatch_size = 128\ntorch.manual_seed(SEED)\nnum_workers = os.cpu_count()\n\ntr_dl = DataLoader(tr_ds, batch_size=batch_size, shuffle=True, num_workers=num_workers, pin_memory=True)\nva_dl = DataLoader(va_ds, batch_size=batch_size, shuffle=False, num_workers=num_workers, pin_memory=True)","metadata":{"execution":{"iopub.status.busy":"2023-07-29T08:06:49.041785Z","iopub.execute_input":"2023-07-29T08:06:49.045904Z","iopub.status.idle":"2023-07-29T08:06:49.079517Z","shell.execute_reply.started":"2023-07-29T08:06:49.045867Z","shell.execute_reply":"2023-07-29T08:06:49.078219Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#import torch.nn as nn\n\nclass Model(nn.Module):\n    def __init__(self, kernel_size=3, dropout_rate=0.5):\n        super(Model, self).__init__()\n        \n        self.kernel_size = kernel_size\n        self.padding = (kernel_size - 1) // 2\n        self.dropout_rate = dropout_rate\n        \n        self.layer1 = nn.Sequential(\n            nn.Conv2d(in_channels = 3, out_channels = 32, kernel_size = self.kernel_size, padding = self.padding),\n            nn.BatchNorm2d(32),\n            nn.ReLU(),\n            nn.MaxPool2d(kernel_size = 2),\n            nn.Dropout(p = self.dropout_rate)\n        )\n        self.layer2 = nn.Sequential(\n            nn.Conv2d(in_channels = 32, out_channels = 64, kernel_size = self.kernel_size, padding = self.padding),\n            nn.BatchNorm2d(64),\n            nn.ReLU(),\n            nn.MaxPool2d(kernel_size = 2),\n            nn.Dropout(p = self.dropout_rate)\n        )\n        self.layer3 = nn.Sequential(\n            nn.Conv2d(in_channels = 64, out_channels = 128, kernel_size = self.kernel_size, padding = self.padding),\n            nn.BatchNorm2d(128),\n            nn.ReLU(),\n            nn.MaxPool2d(kernel_size = 2),\n            nn.Dropout(p = self.dropout_rate)\n        )\n        self.layer4 = nn.Sequential(\n            nn.Conv2d(in_channels = 128, out_channels = 256, kernel_size = self.kernel_size, padding = self.padding),\n            nn.BatchNorm2d(256),\n            nn.ReLU(),\n            nn.MaxPool2d(kernel_size = 2),\n            nn.Dropout(p = self.dropout_rate)\n        )\n        self.layer5 = nn.Sequential(\n            nn.Conv2d(in_channels = 256, out_channels = 512, kernel_size = self.kernel_size, padding = self.padding),\n            nn.BatchNorm2d(512),\n            nn.ReLU(),\n            nn.AvgPool2d(kernel_size = 16),\n            nn.Dropout(p = self.dropout_rate),\n            nn.Flatten(),\n            nn.Linear(512,1),\n            nn.Sigmoid()\n        )\n        \n    def forward(self,x):\n        x = self.layer1(x)\n        x = self.layer2(x)\n        x = self.layer3(x)\n        x = self.layer4(x)\n        x = self.layer5(x)\n\n        return x","metadata":{"execution":{"iopub.status.busy":"2023-07-29T08:06:49.085014Z","iopub.execute_input":"2023-07-29T08:06:49.085298Z","iopub.status.idle":"2023-07-29T08:06:49.108164Z","shell.execute_reply.started":"2023-07-29T08:06:49.085274Z","shell.execute_reply":"2023-07-29T08:06:49.106545Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"CNN = Model()\nopt = torch.optim.Adam(CNN.parameters(), lr=0.001)\nloss_fn = nn.BCELoss()","metadata":{"execution":{"iopub.status.busy":"2023-07-29T08:06:49.109941Z","iopub.execute_input":"2023-07-29T08:06:49.111032Z","iopub.status.idle":"2023-07-29T08:06:49.136695Z","shell.execute_reply.started":"2023-07-29T08:06:49.110971Z","shell.execute_reply":"2023-07-29T08:06:49.135741Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train(model, num_epochs, train_dl, valid_dl):\n    model.to(device)\n    loss_hist_train = np.zeros(num_epochs)\n    accuracy_hist_train = [0] * num_epochs\n    loss_hist_valid = np.zeros(num_epochs)\n    accuracy_hist_valid = [0] * num_epochs\n    start_time = time.time() \n    for epoch in range(num_epochs):\n        model.train()\n        train_loss = 0.0\n        train_correct = 0\n        train_total = 0\n        \n        for batch_idx, (x_batch, y_batch) in enumerate(train_dl):\n            x_batch = x_batch.to(device)\n            y_batch = y_batch.to(device)\n            pred = model(x_batch)[:, 0]\n            loss = loss_fn(pred, y_batch.float())\n            opt.zero_grad()\n            loss.backward()\n            opt.step()\n            train_loss += loss.item() * y_batch.size(0)\n            train_correct += ((pred >= 0.5).float() == y_batch).sum()\n            train_total += y_batch.size(0)\n            \n            if batch_idx % 50 == 0:\n                print ('Epoch: %03d/%03d | Batch %03d/%03d | Loss: %.4f' \n                       %(epoch+1, num_epochs, batch_idx, \n                         len(train_dl), loss.item()))\n        \n        loss_hist_train[epoch] = train_loss / train_total\n        accuracy_hist_train[epoch] = train_correct / train_total\n        \n        model.eval()\n        valid_loss = 0.0\n        valid_correct = 0\n        valid_total = 0\n        \n        with torch.no_grad():\n            for x_batch, y_batch in valid_dl:\n                x_batch = x_batch.to(device)\n                y_batch = y_batch.to(device)\n                pred = model(x_batch)[:, 0]\n                loss = loss_fn(pred, y_batch.float())\n                valid_loss += loss.item() * y_batch.size(0)\n                valid_correct += ((pred >= 0.5).float() == y_batch).sum()\n                valid_total += y_batch.size(0)\n        \n        loss_hist_valid[epoch] = valid_loss / valid_total\n        accuracy_hist_valid[epoch] = valid_correct / valid_total\n        \n        print(f'Epoch {epoch+1} accuracy: {accuracy_hist_train[epoch]:.4f} val_accuracy: {accuracy_hist_valid[epoch]:.4f}')\n        print('Time elapsed: %.2f min' % ((time.time() - start_time) / 60))\n    \n    print('Total Training Time: %.2f min' % ((time.time() - start_time) / 60))\n    \n    return loss_hist_train, loss_hist_valid, accuracy_hist_train, accuracy_hist_valid","metadata":{"execution":{"iopub.status.busy":"2023-07-29T08:06:49.140283Z","iopub.execute_input":"2023-07-29T08:06:49.140832Z","iopub.status.idle":"2023-07-29T08:06:49.155228Z","shell.execute_reply.started":"2023-07-29T08:06:49.140797Z","shell.execute_reply":"2023-07-29T08:06:49.154164Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#import time\n#from PIL import Image\n\ntorch.manual_seed(SEED)\n\nnum_epochs = 100\nhistory = train(CNN, num_epochs, tr_dl, va_dl)\n\ntorch.save(CNN, 'model_weight.pth')","metadata":{"execution":{"iopub.status.busy":"2023-07-29T08:06:49.156488Z","iopub.execute_input":"2023-07-29T08:06:49.157768Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#import matplotlib.pyplot as plt\n\nmy_dpi = 100\nfig, ax = plt.subplots(nrows=2, ncols=1, figsize=(5.4, 7.2), dpi=my_dpi)\nax[0].plot(history[0], lw=2, label='Train loss')\nax[0].plot(history[1], lw=2, label='Validation loss')\nax[0].legend(fontsize=12)\nax[0].set_xlabel('Epochs', fontsize=12)\n\nax[1].plot([i.cpu() for i in history[2]], lw=2, label='Train acc.')\nax[1].plot([i.cpu() for i in history[3]], lw=2, label='Validation acc.')\nax[1].legend(fontsize=12)\nax[1].set_xlabel('Epochs', fontsize=12)\n\nplt.savefig('model_train_history.png', dpi=my_dpi)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"CNN = torch.load('/kaggle/input/model-weight/model_weight.pth')\n\nCNN.eval()\nte_dl = DataLoader(te_ds, batch_size=batch_size, shuffle=False, num_workers=num_workers, pin_memory=True)\n\npredictions = []\nwith torch.no_grad():\n    for x_batch, _ in te_dl:\n        x_batch = x_batch.to(device)\n        pred = CNN(x_batch)[:, 0]\n        predictions.extend(pred.tolist())\n\nimport csv\n\nsubmission_file = 'submission.csv'\nwith open(submission_file, 'w', newline='') as file:\n    writer = csv.writer(file)\n    writer.writerow(['id', 'label'])\n    for i, pred in enumerate(predictions):\n        writer.writerow([i+1, pred])","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}