{"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 numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport os\nimport torch\nimport torch.nn as nn\nimport cv2\nimport matplotlib.pyplot as plt\nimport torchvision\nfrom torch.utils.data import Dataset, DataLoader, ConcatDataset\nfrom torchvision import transforms\nimport copy\nimport tqdm\nfrom PIL import Image\n\n%matplotlib inline","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-07-07T07:03:04.194043Z","iopub.execute_input":"2021-07-07T07:03:04.194286Z","iopub.status.idle":"2021-07-07T07:03:05.329555Z","shell.execute_reply.started":"2021-07-07T07:03:04.194238Z","shell.execute_reply":"2021-07-07T07:03:05.328903Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dir = '../input/train/train'\ntest_dir = '../input/test1/test1'\ntrain_files = os.listdir(train_dir)\ntest_files = os.listdir(test_dir)","metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","execution":{"iopub.status.busy":"2021-07-07T07:03:05.331669Z","iopub.execute_input":"2021-07-07T07:03:05.3319Z","iopub.status.idle":"2021-07-07T07:03:05.519126Z","shell.execute_reply.started":"2021-07-07T07:03:05.331851Z","shell.execute_reply":"2021-07-07T07:03:05.459413Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CatDogDataset(Dataset):\n    def __init__(self, file_list, dir, mode='train', transform = None):\n        self.file_list = file_list\n        self.dir = dir\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            img = img.numpy()\n            return img.astype('float32'), self.label\n        else:\n            img = img.numpy()\n            return img.astype('float32'), self.file_list[idx]\n        \ndata_transform = transforms.Compose([\n    transforms.Resize(256),\n    transforms.ColorJitter(),\n    transforms.RandomCrop(224),\n    transforms.RandomHorizontalFlip(),\n    transforms.Resize(128),\n    transforms.ToTensor()\n])\n\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\ncats = CatDogDataset(cat_files, train_dir, transform = data_transform)\ndogs = CatDogDataset(dog_files, train_dir, transform = data_transform)\n\ncatdogs = ConcatDataset([cats, dogs])","metadata":{"execution":{"iopub.status.busy":"2021-07-07T07:03:05.460397Z","iopub.status.idle":"2021-07-07T07:03:05.461137Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataloader = DataLoader(catdogs, batch_size = 32, shuffle=True, num_workers=4)","metadata":{"execution":{"iopub.status.busy":"2021-07-07T07:03:05.462015Z","iopub.status.idle":"2021-07-07T07:03:05.462783Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"samples, labels = iter(dataloader).next()\nplt.figure(figsize=(16,24))\ngrid_imgs = torchvision.utils.make_grid(samples[: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)))","metadata":{"execution":{"iopub.status.busy":"2021-07-07T07:03:05.463747Z","iopub.status.idle":"2021-07-07T07:03:05.464495Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# transfer learning\n\ndevice = 'cuda'\nmodel = torchvision.models.densenet121(pretrained=True)","metadata":{"execution":{"iopub.status.busy":"2021-07-07T07:03:05.465287Z","iopub.status.idle":"2021-07-07T07:03:05.466096Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"num_ftrs = model.classifier.in_features\nmodel.classifier = nn.Sequential(\n    nn.Linear(num_ftrs, 500),\n    nn.Linear(500, 2)\n)\n\nmodel = model.to(device)\ncriterion = nn.CrossEntropyLoss()\noptimizer = torch.optim.Adam(model.parameters(), lr=0.002, amsgrad=True)\nscheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones=[500,1000,1500], gamma=0.5)","metadata":{"execution":{"iopub.status.busy":"2021-07-07T07:03:05.467008Z","iopub.status.idle":"2021-07-07T07:03:05.467771Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"epochs = 3\nitr = 1\np_itr = 200\nmodel.train()\ntotal_loss = 0\nloss_list = []\nacc_list = []\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        output = model(samples)\n        print(ouput)\n        loss = criterion(output, labels)\n        loss.backward()\n        optimizer.step()\n        total_loss += loss.item()\n        scheduler.step()\n        \n        if itr%p_itr == 0:\n            pred = torch.argmax(output, dim=1)\n            correct = pred.eq(labels)\n            acc = torch.mean(correct.float())\n            print('[Epoch {}/{}] Iteration {} -> Train Loss: {:.4f}, Accuracy: {:.3f}'.format(epoch+1, epochs, itr, total_loss/p_itr, acc))\n            loss_list.append(total_loss/p_itr)\n            acc_list.append(acc)\n            total_loss = 0\n            \n        itr += 1\n\nplt.plot(loss_list, label='loss')\nplt.plot(acc_list, label='accuracy')\nplt.legend()\nplt.title('training loss and accuracy')\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"filename_pth = 'ckpt_densenet121_catdog.pth'\ntorch.save(model.state_dict(), filename_pth)\n\ntest_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 = 32, shuffle=False, num_workers=4)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.eval()\nfn_list = []\npred_list = []\nfor x, fn in testloader:\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_densenet121.csv', index=False)\n    ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"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)))","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}