{"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":"markdown","source":"# **Import libraries**","metadata":{}},{"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\nimport torch\nimport torchvision\nimport torch.nn as nn\nfrom torch.utils.data import Dataset, DataLoader, ConcatDataset\nfrom torchvision import transforms\nimport random\nimport matplotlib.pyplot as plt\nfrom PIL import Image\nimport shutil\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-05-12T16:08:03.797804Z","iopub.execute_input":"2023-05-12T16:08:03.798615Z","iopub.status.idle":"2023-05-12T16:08:08.750514Z","shell.execute_reply.started":"2023-05-12T16:08:03.798581Z","shell.execute_reply":"2023-05-12T16:08:08.749121Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Extracting ZIP Files**\n<!-- # Split the data set into two pieces: -->\n<!-- *     Train: 10000 dog images and 10000 cat images\n*     Val: 2500 dog images and 2500 cat images -->","metadata":{}},{"cell_type":"code","source":"# Extracting zip files\nfrom zipfile import ZipFile\ndataset = '/kaggle/input/dogs-vs-cats/train.zip'\ntest_dataset = '/kaggle/input/dogs-vs-cats/test1.zip'\nwith ZipFile(dataset, 'r') as zip:\n  zip.extractall()\nwith ZipFile(test_dataset, 'r') as zip:\n  zip.extractall()","metadata":{"execution":{"iopub.status.busy":"2023-05-12T16:08:12.379240Z","iopub.execute_input":"2023-05-12T16:08:12.380046Z","iopub.status.idle":"2023-05-12T16:08:30.143584Z","shell.execute_reply.started":"2023-05-12T16:08:12.380009Z","shell.execute_reply":"2023-05-12T16:08:30.137845Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Split dataset\n# os.mkdir('/kaggle/working/val')\ntrain_dir = '/kaggle/working/train'\ntest_dir = '/kaggle/working/test1'\n# val_dir = '/kaggle/working/val'\ntrain_files = os.listdir(train_dir)\ntest_files = os.listdir(test_dir)\ncat_files = [tf for tf in train_files if 'cat' in tf]\ndog_files = [tf for tf in train_files if 'dog' in tf]\n# cat_files_val = []\n# dog_files_val = []\n# for i in range(2500):\n#     cat_file = random.choice(cat_files)\n#     shutil.move(f'/kaggle/working/train/{cat_file}', f'/kaggle/working/val/{cat_file}')\n#     cat_files_val.append(cat_file)\n#     cat_files.remove(cat_file)\n#     dog_file = random.choice(dog_files)\n#     shutil.move(f'/kaggle/working/train/{dog_file}', f'/kaggle/working/val/{dog_file}')\n#     dog_files_val.append(dog_file)\n#     dog_files.remove(dog_file)","metadata":{"execution":{"iopub.status.busy":"2023-05-12T16:08:30.145554Z","iopub.execute_input":"2023-05-12T16:08:30.145896Z","iopub.status.idle":"2023-05-12T16:08:30.228916Z","shell.execute_reply.started":"2023-05-12T16:08:30.145863Z","shell.execute_reply":"2023-05-12T16:08:30.226224Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Define Dataset, DataLoader**","metadata":{}},{"cell_type":"code","source":"class DogCatDataset(Dataset):\n    def __init__(self, folder_dir, file_list, mode='train', transform=None) -> None:\n        self.folder_dir = folder_dir\n        self.file_list = file_list\n        self.mode = mode\n        self.transform = transform\n        if mode == 'train':\n            self.label = 1 if 'dog' in self.file_list[0] else 0 \n            \n    def __getitem__(self, index):\n        img = Image.open(os.path.join(self.folder_dir, self.file_list[index]))\n        if self.transform:\n            img = self.transform(img)\n        img = img.numpy()\n        return img.astype('float32'), (self.label if self.mode == 'train' else self.file_list[index])\n    \n    def __len__(self):\n        return len(self.file_list)","metadata":{"execution":{"iopub.status.busy":"2023-05-12T16:08:30.230342Z","iopub.execute_input":"2023-05-12T16:08:30.230688Z","iopub.status.idle":"2023-05-12T16:08:30.247504Z","shell.execute_reply.started":"2023-05-12T16:08:30.230652Z","shell.execute_reply":"2023-05-12T16:08:30.246271Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_transform = transforms.Compose([\n    transforms.Resize(256),\n    transforms.RandomCrop(224),\n    transforms.RandomHorizontalFlip(),\n    transforms.ColorJitter(),\n    transforms.Resize(128),\n    transforms.ToTensor()\n])\ncats = DogCatDataset(train_dir, cat_files, transform = data_transform)\ndogs = DogCatDataset(train_dir, dog_files, transform = data_transform)\ncatdogs = ConcatDataset([cats, dogs])\n\n# cats_val = DogCatDataset(val_dir, cat_files_val, transform = data_transform)\n# dogs_val = DogCatDataset(val_dir, dog_files_val, transform = data_transform)\n# catdogs_val = ConcatDataset([cats_val, dogs_val])","metadata":{"execution":{"iopub.status.busy":"2023-05-12T16:08:30.250086Z","iopub.execute_input":"2023-05-12T16:08:30.250486Z","iopub.status.idle":"2023-05-12T16:08:30.283624Z","shell.execute_reply.started":"2023-05-12T16:08:30.250437Z","shell.execute_reply":"2023-05-12T16:08:30.282567Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataloader = DataLoader(catdogs,batch_size = 32,shuffle=True,num_workers=2)\n# dataloader_val = DataLoader(catdogs_val|,batch_size = 32,shuffle=False,num_workers=2)","metadata":{"execution":{"iopub.status.busy":"2023-05-12T16:26:31.463731Z","iopub.execute_input":"2023-05-12T16:26:31.464122Z","iopub.status.idle":"2023-05-12T16:26:31.470241Z","shell.execute_reply.started":"2023-05-12T16:26:31.464090Z","shell.execute_reply":"2023-05-12T16:26:31.469213Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataiter = iter(dataloader)\nsamples, labels  = next(dataiter)\nplt.figure(figsize=(24,16))\ngrid_imgs = torchvision.utils.make_grid(samples[:32])\nnp_grid_imgs = grid_imgs.numpy()\nplt.imshow(np.transpose(np_grid_imgs, (1,2,0)))","metadata":{"execution":{"iopub.status.busy":"2023-05-12T16:08:30.310103Z","iopub.execute_input":"2023-05-12T16:08:30.310409Z","iopub.status.idle":"2023-05-12T16:08:33.967371Z","shell.execute_reply.started":"2023-05-12T16:08:30.310382Z","shell.execute_reply":"2023-05-12T16:08:33.966060Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Create model**","metadata":{}},{"cell_type":"code","source":"device = 'cuda'\nmodel = torchvision.models.resnet18(pretrained=True)","metadata":{"execution":{"iopub.status.busy":"2023-05-12T16:26:34.127814Z","iopub.execute_input":"2023-05-12T16:26:34.128231Z","iopub.status.idle":"2023-05-12T16:26:34.372294Z","shell.execute_reply.started":"2023-05-12T16:26:34.128164Z","shell.execute_reply":"2023-05-12T16:26:34.371286Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.classifier = nn.Sequential(\n    nn.Linear(512,100),\n    nn.Linear(100,2)\n)\n\nmodel.to(device)\ncriterion = nn.CrossEntropyLoss()\noptimizer = torch.optim.Adam(model.parameters(), lr=0.001)","metadata":{"execution":{"iopub.status.busy":"2023-05-12T16:27:07.994512Z","iopub.execute_input":"2023-05-12T16:27:07.994920Z","iopub.status.idle":"2023-05-12T16:27:08.021762Z","shell.execute_reply.started":"2023-05-12T16:27:07.994886Z","shell.execute_reply":"2023-05-12T16:27:08.020693Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# def validate(model, data):\n#     total = 0\n#     correct = 0\n\n#     for samples, labels in data:\n#         samples, labels = samples.to(device), labels.to(device)\n#         output = model(samples)\n#         _, pred = torch.max(output, 1)\n#         correct += torch.sum(pred == labels)\n\n#     return correct*100/len(data)","metadata":{"execution":{"iopub.status.busy":"2023-05-12T13:54:49.454327Z","iopub.execute_input":"2023-05-12T13:54:49.454701Z","iopub.status.idle":"2023-05-12T13:54:49.462359Z","shell.execute_reply.started":"2023-05-12T13:54:49.454673Z","shell.execute_reply":"2023-05-12T13:54:49.461376Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"epochs = 5\nitr = 0\nmodel.train()\nrunning_loss = 0\nrunning_acc = 0\n\nfor epoch in range(epochs):\n    for samples, labels in dataloader:\n        samples, labels = samples.to(device), labels.to(device)\n        optimizer.zero_grad()\n        with torch.set_grad_enabled(True):\n            outputs = model(samples)\n            loss = criterion(outputs, labels)\n            _, preds = torch.max(outputs, 1)\n\n            loss.backward()\n            optimizer.step()\n\n        running_loss += loss.item() * samples.size(0)\n        running_acc += torch.sum(preds == labels.data)\n        itr += len(labels)\n        \n    loss = running_loss / float(itr)\n    acc = running_acc.double() / float(itr)\n    print(f'[Epoch {epoch+1}/{epochs}] -> Train Loss: {loss:.4f}, Accuracy: {acc:.3f}')\n    ","metadata":{"execution":{"iopub.status.busy":"2023-05-12T16:27:12.624380Z","iopub.execute_input":"2023-05-12T16:27:12.625062Z","iopub.status.idle":"2023-05-12T16:35:41.420945Z","shell.execute_reply.started":"2023-05-12T16:27:12.625028Z","shell.execute_reply":"2023-05-12T16:35:41.418558Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"filename_pth = 'cp_resnet18_dogcat.pth'\ntorch.save(model.state_dict(), filename_pth)","metadata":{"execution":{"iopub.status.busy":"2023-05-12T16:36:42.361934Z","iopub.execute_input":"2023-05-12T16:36:42.363099Z","iopub.status.idle":"2023-05-12T16:36:42.466098Z","shell.execute_reply.started":"2023-05-12T16:36:42.363035Z","shell.execute_reply":"2023-05-12T16:36:42.465050Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_transform = transforms.Compose([\n    transforms.Resize((128,128)),\n    transforms.ToTensor()\n])\n\ntest_set = DogCatDataset(test_dir, test_files, mode='test', transform = test_transform)\ntest_dataloader = DataLoader(test_set, batch_size = 32, shuffle=False, num_workers=2)","metadata":{"execution":{"iopub.status.busy":"2023-05-12T16:38:40.517736Z","iopub.execute_input":"2023-05-12T16:38:40.518157Z","iopub.status.idle":"2023-05-12T16:38:40.525644Z","shell.execute_reply.started":"2023-05-12T16:38:40.518123Z","shell.execute_reply":"2023-05-12T16:38:40.524497Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.eval()\nfn_list = []\npred_list = []\nfor x, fn in test_dataloader:\n    with torch.no_grad():\n        x = x.to(device)\n        output = model(x)\n        pred = torch.argmax(output, dim=1)\n        fn_list += [n[:-4] for n in fn]\n        pred_list += [p.item() for p in pred]\n\nsubmission = pd.DataFrame({\"id\":fn_list, \"label\":pred_list})\nsubmission.to_csv('preds_resnet18_20230512.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2023-05-12T16:39:29.689946Z","iopub.execute_input":"2023-05-12T16:39:29.690370Z","iopub.status.idle":"2023-05-12T16:39:59.001133Z","shell.execute_reply.started":"2023-05-12T16:39:29.690333Z","shell.execute_reply":"2023-05-12T16:39:58.999845Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\ndata = pd.read_csv(\"preds_resnet18_20230512.csv\")\ndata.head()","metadata":{"execution":{"iopub.status.busy":"2023-05-12T16:41:20.137288Z","iopub.execute_input":"2023-05-12T16:41:20.137743Z","iopub.status.idle":"2023-05-12T16:41:20.167964Z","shell.execute_reply.started":"2023-05-12T16:41:20.137706Z","shell.execute_reply":"2023-05-12T16:41:20.166353Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"iter_test = iter(test_dataloader)\nsamples, _ = next(iter_test)\nsamples = samples.to(device)\nfig = plt.figure(figsize=(24, 16))\nfig.tight_layout()\noutput = model(samples[:24])\npred = torch.argmax(output, dim=1)\npred = [p.item() for p in pred]\nad = {0:'cat', 1:'dog'}\nfor num, sample in enumerate(samples[:24]):\n    plt.subplot(4,6,num+1)\n    plt.title(ad[pred[num]])\n    plt.axis('off')\n    sample = sample.cpu().numpy()\n    plt.imshow(np.transpose(sample, (1,2,0)))","metadata":{"execution":{"iopub.status.busy":"2023-05-12T16:44:58.362479Z","iopub.execute_input":"2023-05-12T16:44:58.362882Z","iopub.status.idle":"2023-05-12T16:45:02.251921Z","shell.execute_reply.started":"2023-05-12T16:44:58.362851Z","shell.execute_reply":"2023-05-12T16:45:02.246307Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}