{"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":"import os \nimport torch\nimport numpy as np\n\nfrom PIL import Image\nfrom matplotlib import pyplot as plt\n\nimport torchvision\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import DataLoader, Dataset\nfrom torchvision.datasets.folder import default_loader\nfrom torchvision import transforms\nimport torchvision.models as models","metadata":{"execution":{"iopub.status.busy":"2022-03-04T08:56:03.519708Z","iopub.execute_input":"2022-03-04T08:56:03.520338Z","iopub.status.idle":"2022-03-04T08:56:05.156251Z","shell.execute_reply.started":"2022-03-04T08:56:03.520237Z","shell.execute_reply":"2022-03-04T08:56:05.155520Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# hyperparams\n\nCLASSES = {0:\"cat\", 1:\"dog\"}\nBATCH_SIZE = 64\nIMG_SIZE = (224, 224)\nNUM_EPOCHS = 30\nTRAIN_DATA_PATH = \"../input/dog-vs-cat-classification/train/train\"\nTEST_DATA_PATH = \"../input/dog-vs-cat-classification/test/test\"\nTRANSFORM_IMG = transforms.Compose([\n    transforms.ToTensor(),\n    transforms.Resize(IMG_SIZE),\n    transforms.Normalize(mean=[0.485, 0.456, 0.406],\n                         std=[0.229, 0.224, 0.225] )\n    ])","metadata":{"execution":{"iopub.status.busy":"2022-03-04T08:56:05.159808Z","iopub.execute_input":"2022-03-04T08:56:05.160084Z","iopub.status.idle":"2022-03-04T08:56:05.165797Z","shell.execute_reply.started":"2022-03-04T08:56:05.160052Z","shell.execute_reply":"2022-03-04T08:56:05.165012Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# custom dataloader for testing samples\nclass TestingDataset(Dataset):\n    \n    def __init__(self, root, transforms=None):\n        self.transforms = transforms\n        self.img_paths = sorted(os.path.join(root, x) for x in os.listdir(root) if x.endswith('.jpg'))\n\n        \n    def __len__(self):\n        return len(self.img_paths)\n    \n    def __getitem__(self, idx):\n        img_path = self.img_paths[idx]\n        sample = default_loader(img_path)\n        if self.transforms is not None:\n            sample = self.transforms(sample)\n        return sample, img_path.split('/')[-1]","metadata":{"execution":{"iopub.status.busy":"2022-03-04T08:56:05.167206Z","iopub.execute_input":"2022-03-04T08:56:05.167487Z","iopub.status.idle":"2022-03-04T08:56:05.176606Z","shell.execute_reply.started":"2022-03-04T08:56:05.167432Z","shell.execute_reply":"2022-03-04T08:56:05.175969Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# data loader\ntrain_data = torchvision.datasets.ImageFolder(root=TRAIN_DATA_PATH, transform=TRANSFORM_IMG)\ntrain_data_loader = DataLoader(train_data, batch_size=BATCH_SIZE, shuffle=True)\ntest_data = TestingDataset(root=TEST_DATA_PATH, transforms=TRANSFORM_IMG)\ntest_data_loader = DataLoader(test_data, batch_size=BATCH_SIZE, shuffle=True)","metadata":{"execution":{"iopub.status.busy":"2022-03-04T08:56:05.178573Z","iopub.execute_input":"2022-03-04T08:56:05.179380Z","iopub.status.idle":"2022-03-04T08:56:23.878445Z","shell.execute_reply.started":"2022-03-04T08:56:05.179330Z","shell.execute_reply":"2022-03-04T08:56:23.877679Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# model\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nmodel = models.vgg16_bn(pretrained=False, num_classes=2)\nmodel.to(device)","metadata":{"execution":{"iopub.status.busy":"2022-03-04T08:56:23.880558Z","iopub.execute_input":"2022-03-04T08:56:23.881168Z","iopub.status.idle":"2022-03-04T08:56:29.510501Z","shell.execute_reply.started":"2022-03-04T08:56:23.881127Z","shell.execute_reply":"2022-03-04T08:56:29.509793Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"criterion = nn.CrossEntropyLoss()\noptimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)","metadata":{"execution":{"iopub.status.busy":"2022-03-04T08:56:29.511544Z","iopub.execute_input":"2022-03-04T08:56:29.511779Z","iopub.status.idle":"2022-03-04T08:56:29.518681Z","shell.execute_reply.started":"2022-03-04T08:56:29.511745Z","shell.execute_reply":"2022-03-04T08:56:29.515999Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# training\nmodel.train()\n\nfor epoch in range(NUM_EPOCHS): \n    running_loss = 0.0\n    \n    for i, (img,label) in enumerate(train_data_loader):\n\n        inputs, labels = img.to(device), label.to(device)\n\n        optimizer.zero_grad()\n\n        outputs = model(inputs)\n        loss = criterion(outputs, labels)\n        loss.backward()\n        optimizer.step()\n\n        running_loss += loss.item()                                                                                                                                                                                                                                                                                                                                                                                                              \n\n    print('[%d, %5d] loss: %.3f' % (epoch + 1, epoch, running_loss / len(train_data_loader)))\n    running_loss = 0.0\nprint('[INFO]: Finished Training')  \n","metadata":{"execution":{"iopub.status.busy":"2022-03-04T08:56:29.520122Z","iopub.execute_input":"2022-03-04T08:56:29.520666Z","iopub.status.idle":"2022-03-04T11:47:36.057294Z","shell.execute_reply.started":"2022-03-04T08:56:29.520629Z","shell.execute_reply":"2022-03-04T11:47:36.056565Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# PATH = f'./vgg16-plain-{NUM_EPOCHS}.pth'\n# torch.save(model.state_dict(), PATH)","metadata":{"execution":{"iopub.status.busy":"2022-03-04T11:47:36.058386Z","iopub.execute_input":"2022-03-04T11:47:36.058617Z","iopub.status.idle":"2022-03-04T11:47:36.063300Z","shell.execute_reply.started":"2022-03-04T11:47:36.058583Z","shell.execute_reply":"2022-03-04T11:47:36.062251Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# testing\n\nprint('[INFO]: Start Testing')\nmodel.eval()\n\nresult_array, image_paths = np.array([]), np.array([])\n \nwith torch.no_grad():\n    for i, (image, image_path) in enumerate(test_data_loader):\n        test_input = image.to(device)\n        outputs = model(test_input)\n        _, predicted = torch.max(outputs, 1)\n        result_array = np.append(result_array, predicted.cpu().detach().numpy())\n        image_paths = np.append(image_paths, image_path)\n                \n","metadata":{"execution":{"iopub.status.busy":"2022-03-04T11:47:36.064531Z","iopub.execute_input":"2022-03-04T11:47:36.064962Z","iopub.status.idle":"2022-03-04T11:49:36.460030Z","shell.execute_reply.started":"2022-03-04T11:47:36.064927Z","shell.execute_reply":"2022-03-04T11:49:36.459284Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"result_array = result_array.astype('uint8')\nresult_array","metadata":{"execution":{"iopub.status.busy":"2022-03-04T11:49:36.462199Z","iopub.execute_input":"2022-03-04T11:49:36.462437Z","iopub.status.idle":"2022-03-04T11:49:36.469771Z","shell.execute_reply.started":"2022-03-04T11:49:36.462403Z","shell.execute_reply":"2022-03-04T11:49:36.469124Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# visualization \n\nfor i in range(12):\n    plt.subplot(3, 4,i+1)\n    image = plt.imread(os.path.join(TEST_DATA_PATH, image_paths[i]))\n    plt.imshow(image)\n    plt.axis(\"off\")\n    title = CLASSES[int(result_array[i])]\n    plt.title(f\"label: {title}\")","metadata":{"execution":{"iopub.status.busy":"2022-03-04T11:49:36.470937Z","iopub.execute_input":"2022-03-04T11:49:36.471643Z","iopub.status.idle":"2022-03-04T11:49:37.253451Z","shell.execute_reply.started":"2022-03-04T11:49:36.471518Z","shell.execute_reply":"2022-03-04T11:49:37.252739Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# submission \n\nimport pandas as pd\n\ndf = pd.DataFrame({'id': image_paths, 'labels': result_array})\ndf.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2022-03-04T11:49:37.254401Z","iopub.execute_input":"2022-03-04T11:49:37.254625Z","iopub.status.idle":"2022-03-04T11:49:37.279703Z","shell.execute_reply.started":"2022-03-04T11:49:37.254595Z","shell.execute_reply":"2022-03-04T11:49:37.279095Z"},"trusted":true},"execution_count":null,"outputs":[]}]}