{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":3362,"databundleVersionId":31148,"sourceType":"competition"}],"dockerImageVersionId":30627,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import torch\nimport torchvision\nimport torchvision.transforms as transforms\nimport torch.optim as optim\nimport torch.nn as nn\nimport zipfile\nimport os\nimport glob\nfrom tqdm.notebook import tqdm\nfrom PIL import Image\nimport matplotlib.pyplot as plt\nimport numpy as np\nfrom sklearn.model_selection import train_test_split\nimport warnings\nfrom torch.utils.data import Dataset, DataLoader\nwarnings.filterwarnings('ignore')","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-12-17T14:16:04.229069Z","iopub.execute_input":"2023-12-17T14:16:04.229421Z","iopub.status.idle":"2023-12-17T14:16:08.090436Z","shell.execute_reply.started":"2023-12-17T14:16:04.229391Z","shell.execute_reply":"2023-12-17T14:16:08.089580Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"net = torchvision.models.resnet50(pretrained=True)\nfor params in net.parameters():\n    params.requires_grad_ = False\nnr_filters = net.fc.in_features\nnet.fc = nn.Sequential(nn.Linear(nr_filters, 1), nn.Sigmoid())","metadata":{"execution":{"iopub.status.busy":"2023-12-17T14:16:08.091999Z","iopub.execute_input":"2023-12-17T14:16:08.092395Z","iopub.status.idle":"2023-12-17T14:16:09.048448Z","shell.execute_reply.started":"2023-12-17T14:16:08.092368Z","shell.execute_reply":"2023-12-17T14:16:09.047552Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\nnet.to(device)\ndevice","metadata":{"execution":{"iopub.status.busy":"2023-12-17T14:16:09.049511Z","iopub.execute_input":"2023-12-17T14:16:09.051018Z","iopub.status.idle":"2023-12-17T14:16:11.851063Z","shell.execute_reply.started":"2023-12-17T14:16:09.050988Z","shell.execute_reply":"2023-12-17T14:16:11.850175Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base_dir = '../input/dogs-vs-cats'\nwith zipfile.ZipFile(os.path.join(base_dir, 'train.zip')) as train_zip:\n    train_zip.extractall('../data')\nwith zipfile.ZipFile(os.path.join(base_dir, 'test1.zip')) as test_zip:\n    test_zip.extractall('../data')\n\ntrain_dir = '../data/train'\ntest_dir = '../data/test'","metadata":{"execution":{"iopub.status.busy":"2023-12-17T14:16:11.853762Z","iopub.execute_input":"2023-12-17T14:16:11.854157Z","iopub.status.idle":"2023-12-17T14:16:26.371038Z","shell.execute_reply.started":"2023-12-17T14:16:11.854123Z","shell.execute_reply":"2023-12-17T14:16:26.370248Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"all_train_files = glob.glob(os.path.join(train_dir, '*.jpg'))\ntrain_list, val_list = train_test_split(all_train_files, random_state=42)\nprint(len(train_list))\nprint(len(val_list))","metadata":{"execution":{"iopub.status.busy":"2023-12-17T14:16:26.372166Z","iopub.execute_input":"2023-12-17T14:16:26.372453Z","iopub.status.idle":"2023-12-17T14:16:26.476522Z","shell.execute_reply.started":"2023-12-17T14:16:26.372420Z","shell.execute_reply":"2023-12-17T14:16:26.475629Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def extract_class_from(path):\n    file = path.split('/')[-1]\n    return file.split('.')[0]","metadata":{"execution":{"iopub.status.busy":"2023-12-17T14:16:26.477754Z","iopub.execute_input":"2023-12-17T14:16:26.478081Z","iopub.status.idle":"2023-12-17T14:16:28.367221Z","shell.execute_reply.started":"2023-12-17T14:16:26.478054Z","shell.execute_reply":"2023-12-17T14:16:28.366321Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class DogVsCatDataset(Dataset):\n  \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        if torch.is_tensor(idx):\n            idx = idx.tolist()\n       \n        img_name = self.file_list[idx]\n        image = Image.open(img_name)\n        if self.transform:\n            image = self.transform(image)\n    \n        label_category = extract_class_from(img_name)\n        label = 1 if label_category == 'dog' else 0\n    \n        return image, label","metadata":{"execution":{"iopub.status.busy":"2023-12-17T14:16:28.368524Z","iopub.execute_input":"2023-12-17T14:16:28.368863Z","iopub.status.idle":"2023-12-17T14:16:28.377395Z","shell.execute_reply.started":"2023-12-17T14:16:28.368835Z","shell.execute_reply":"2023-12-17T14:16:28.376258Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"transform = transforms.Compose(\n    [\n        transforms.Resize((224, 224)),\n        transforms.ToTensor(),\n        transforms.Normalize((0.5), (0.5)),\n        transforms.RandomErasing(),\n    ]\n)\nbatch_size = 10\n\ntrainset = DogVsCatDataset(train_list, transform=transform)\ntrainloader = DataLoader(\n    trainset, batch_size=batch_size, shuffle=True, num_workers=8\n)\n\ntestset = DogVsCatDataset(val_list, transform=transform)\ntestloader = torch.utils.data.DataLoader(\n    testset, batch_size=batch_size, shuffle=False, num_workers=8\n)","metadata":{"execution":{"iopub.status.busy":"2023-12-17T14:16:28.378388Z","iopub.execute_input":"2023-12-17T14:16:28.378625Z","iopub.status.idle":"2023-12-17T14:16:28.387505Z","shell.execute_reply.started":"2023-12-17T14:16:28.378603Z","shell.execute_reply":"2023-12-17T14:16:28.386705Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from torch.nn.modules.loss import BCEWithLogitsLoss\nfrom torch.optim import lr_scheduler\n\n#loss\ncriterion = BCEWithLogitsLoss() #binary cross entropy with sigmoid, so no need to use sigmoid in the model\n\n#optimizer\noptimizer = torch.optim.Adam(net.fc.parameters()) ","metadata":{"execution":{"iopub.status.busy":"2023-12-17T14:16:28.388549Z","iopub.execute_input":"2023-12-17T14:16:28.388832Z","iopub.status.idle":"2023-12-17T14:16:28.399672Z","shell.execute_reply.started":"2023-12-17T14:16:28.388798Z","shell.execute_reply":"2023-12-17T14:16:28.398955Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_loss = []\ntest_loss = []\ntrain_acc = []\ntest_acc = []","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for epoch in range(10):\n    print(f\"Epoch: {epoch + 1}\")\n    running_loss = 0.0\n    train_correct = 0\n    train_total = 0\n    for i, data in enumerate(tqdm(trainloader, 0)):\n        inputs, labels = data[0].to(device), data[1].to(device)\n        optimizer.zero_grad()\n        outputs = net(inputs)\n        loss = criterion(outputs, labels.unsqueeze(1).float())\n        predicted = (outputs > 0.5).float()\n        train_correct += (predicted == labels.unsqueeze(1).float()).sum().item()\n        train_total += labels.size(0)\n        loss.backward()\n        optimizer.step()\n        running_loss += loss.item()\n\n    val_loss = 0.0\n    val_correct = 0\n    val_total = 0\n    for i, data in enumerate(testloader, 0):\n        inputs, labels = data[0].to(device), data[1].to(device)\n        outputs = net(inputs)\n        loss = criterion(outputs, labels.unsqueeze(1).float())\n        val_loss += loss.item()\n        predicted = (outputs > 0.5).float()\n        val_correct += (predicted == labels.unsqueeze(1).float()).sum().item()\n        val_total += labels.size(0)\n\n    train_loss.append(running_loss / len(trainloader))\n    test_loss.append(val_loss / len(testloader))\n    train_acc.append(train_correct / train_total)\n    test_acc.append(val_correct / val_total)\n\n    print(f\"[{epoch + 1}, {i + 1:5d}]\")\n    print(f\"\\tloss: {train_loss[-1]:.3f} val loss: {test_loss[-1]:.3f}\")\n    print(f\"\\taccuracy: {train_acc[-1]:.3f} val accuracy: {test_acc[-1]:.3f}\")","metadata":{"execution":{"iopub.status.busy":"2023-12-17T15:25:44.064187Z","iopub.execute_input":"2023-12-17T15:25:44.064600Z","iopub.status.idle":"2023-12-17T15:49:41.874215Z","shell.execute_reply.started":"2023-12-17T15:25:44.064553Z","shell.execute_reply":"2023-12-17T15:49:41.873055Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, axs = plt.subplots(2, 1, layout='constrained')\naxs[0].plot(train_loss, label=\"Train\")\naxs[0].plot(test_loss, label=\"Test\")\naxs[0].set_xlabel('Epoch')\naxs[0].set_ylabel('Loss')\naxs[0].legend(loc=\"upper right\")\naxs[0].set_title(\"Loss\")\naxs[0].grid(True)\n\naxs[1].plot(train_acc, label=\"Train\")\naxs[1].plot(test_acc, label=\"Test\")\naxs[1].set_xlabel('Epoch')\naxs[1].set_ylabel('Accuracy')\naxs[1].legend(loc=\"upper left\")\naxs[1].set_title(\"Accuracy\")\naxs[1].grid(True)\n\nprint(train_loss)\nprint(test_loss)\nprint(train_acc)\nprint(test_acc)","metadata":{"execution":{"iopub.status.busy":"2023-12-17T14:40:31.184664Z","iopub.execute_input":"2023-12-17T14:40:31.185006Z","iopub.status.idle":"2023-12-17T14:40:31.977696Z","shell.execute_reply.started":"2023-12-17T14:40:31.184971Z","shell.execute_reply":"2023-12-17T14:40:31.976749Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Finished Training\")\ntorch.save(net.state_dict(), \"./cat_dog_net.pth\")","metadata":{"execution":{"iopub.status.busy":"2023-12-17T14:40:31.979143Z","iopub.execute_input":"2023-12-17T14:40:31.979747Z","iopub.status.idle":"2023-12-17T14:40:32.135481Z","shell.execute_reply.started":"2023-12-17T14:40:31.979709Z","shell.execute_reply":"2023-12-17T14:40:32.134588Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}