{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"# imports\nimport torch\nfrom torch.utils.data import Dataset, DataLoader, ConcatDataset\nimport torchvision\nfrom torchvision import transforms\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport zipfile\nimport os\nfrom PIL import Image","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Unzip the data\nwith zipfile.ZipFile(\"../input/dogs-vs-cats/train.zip\",\"r\") as z:\n    z.extractall(\".\")\nwith zipfile.ZipFile(\"../input/dogs-vs-cats/test1.zip\", \"r\") as z:\n    z.extractall(\".\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_dir = 'train'\ntest_dir = 'test1'\ntrain_files = os.listdir(train_dir)\ntest_files = os.listdir(test_dir)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Implement the Dataset class\nclass CatDogDataset(Dataset):\n    def __init__(self, file_list, directory, mode='train', transform=None):\n        self.file_list = file_list\n        self.dir = directory\n        self.mode = mode\n        self.transform = transform\n        if self.mode == 'train':\n            if 'dog' in self.file_list[0]:\n                self.label = 1\n            else:\n                self.label = 0\n                \n    def __len__(self):\n        return len(self.file_list)\n    \n    def __getitem__(self, idx):\n        img = Image.open(os.path.join(self.dir, self.file_list[idx]))\n        if self.transform:\n            img = self.transform(img)\n        if self.mode == 'train':\n            return img.numpy().astype('float32'), self.label\n        else:\n            return img.numpy().astype('float32'), self.file_list[idx]\n        ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Prepare train dataset\ndata_transform = transforms.Compose([\n    transforms.Resize(256),\n    transforms.RandomHorizontalFlip(),\n    transforms.RandomCrop(224),\n    transforms.Resize(128),\n    transforms.ToTensor()\n])\n\ncat_files = [file for file in train_files if 'cat' in file]\ndog_files = [file for file in train_files if 'dog' in file]\n\ncats = CatDogDataset(cat_files, train_dir, mode='train', transform=data_transform)\ndogs = CatDogDataset(dog_files, train_dir, mode='train', transform=data_transform)\n\ntrain_data = ConcatDataset([cats, dogs])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Prepare the dataloader\ntrain_loader = DataLoader(train_data, batch_size=64, shuffle=True, num_workers=4)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dataiter = iter(train_loader)\nimages, labels = dataiter.next()\n# Plot the images\nfig = plt.figure(figsize=(16, 24))\ngrid_imgs = torchvision.utils.make_grid(images[:24])\nnp_grid_imgs = grid_imgs.numpy()\n# in tensor, image is (batch, width, height), so you have to transpose it to (width, height, batch) in numpy to show it.\nplt.imshow(np.transpose(np_grid_imgs, (1,2,0)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"images.shape, labels.shape # (batch_size, channels, hight, width), (batch_size, 1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Download a pre-trained model\ndevice = 'cuda'\nmodel = torchvision.models.resnet152(pretrained=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Let's see how does the architecture look\nmodel \n# Freeze the model parameters for transfer learning\n# for param in model.parameters():\n#     param.requires_grad = False","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import torch.nn as nn\nfrom torch.optim import Adam\n# Define and Update the last fully-connected layer\ninput_size = model.fc.in_features\noutput_size = 2\nmodel.fc = nn.Sequential(\n    nn.Linear(input_size, 1000),\n    nn.Linear(1000, 500),\n    nn.Linear(500, output_size))\nmodel = model.to(device)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"criterion = nn.CrossEntropyLoss()\noptimizer = Adam(model.parameters(), lr=0.001)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Model training\nnum_epochs = 2\ntrain_loss = 0\nprint_every = 20\ncounter = 1\nloss_list = []\nacc_list = []\nmodel.train\nfor i in range(num_epochs):\n    for images, labels in train_loader:\n        images, labels = images.to(device), labels.to(device)\n        optimizer.zero_grad()\n        preds = model(images)\n        loss = criterion(preds, labels)\n        loss.backward()\n        optimizer.step()\n        train_loss += loss.item()\n        if counter % print_every == 0:\n            predicted_labels = torch.argmax(preds, dim=1)\n            corrects = predicted_labels.eq(labels)\n            accuracy = torch.mean(corrects.float())\n            print('[Epoch {}/{}] Iteration {} -> Train Loss: {:.4f}, Accuracy: {:.3f}'\\\n                  .format(i+1, num_epochs, counter, train_loss/print_every, accuracy))\n            loss_list.append(train_loss/print_every)\n            acc_list.append(accuracy)\n            train_loss = 0\n        counter += 1\n        \n# Plot the training history\nplt.plot(loss_list, label='loss')\nplt.plot(acc_list, label='accuracy')\nplt.legend()\nplt.title('training loss and accuracy')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model_path = 'ckpt_resnet152_catdog.pth'\ntorch.save(model.state_dict(), model_path)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_transform = transforms.Compose([\n    transforms.Resize((128,128)),\n    transforms.ToTensor()\n])\n\ntestset = CatDogDataset(test_files, test_dir, mode='test', transform = test_transform)\ntestloader = DataLoader(testset, batch_size = 64, shuffle=False, num_workers=4)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"samples, _ = iter(testloader).next()\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)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}