{"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 \nimport pandas as pd \nimport os\nimport zipfile\nimport matplotlib.pyplot as plt\nimport albumentations as A\nfrom albumentations.pytorch.transforms import ToTensor\nfrom torch.utils.data.dataset import Dataset\nfrom torch.utils.data import DataLoader\nimport cv2\nimport torch\nfrom torch import nn\nfrom albumentations.pytorch.transforms import ToTensorV2\nfrom sklearn.model_selection import train_test_split\nimport torchvision.models as models\nimport torch.optim as optim\n\nfrom torchvision.utils import make_grid\nfrom torchvision import transforms as T","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_zip = zipfile.ZipFile('../input/dogs-vs-cats-redux-kernels-edition/train.zip','r')\ntest_zip = zipfile.ZipFile('../input/dogs-vs-cats-redux-kernels-edition/test.zip','r')\ntrain_zip.extractall('./')\ntest_zip.extractall('./')\ntrain_zip.close()\ntest_zip.close()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_images_paths = [os.path.join(\"/kaggle/working/train/\", i) for i in os.listdir(\"/kaggle/working/train/\") ]\ntest_images_paths = [os.path.join(\"/kaggle/working/test/\", i) for i in os.listdir(\"/kaggle/working/test/\") ]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = pd.DataFrame(train_images_paths)\ntrain.columns = ['path']\n\ntest = pd.DataFrame(test_images_paths)\ntest.columns = ['path']","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train['label'] = train['path'].apply(lambda x: (x.find('cat') >=0)*1 )","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train, val, _,_  = train_test_split(train, train, test_size=0.1)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train= train.reset_index(drop=True)\nval= val.reset_index(drop=True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in range (10):\n    plt.figure(figsize=(6,6))\n    img = plt.imread(train.loc[i,'path'])\n    plt.imshow(img)\n    plt.title(train.loc[i,'path'])\n    plt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in range (10):\n    img = plt.imread(train.loc[i,'path'])\n    print(img.shape)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(6,6))\nplt.hist(img[:,:,0].flatten(), bins = 100, label = 'r', color='r', alpha = 0.3)\nplt.hist(img[:,:,1].flatten(), bins = 100, label = 'g', color='g', alpha = 0.3)\nplt.hist(img[:,:,2].flatten(), bins = 100, label = 'b', color='b', alpha = 0.3)\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n\ndef get_train_transform(size=224):\n    return A.Compose([\n        A.Resize(size, size),\n        A.HorizontalFlip(p=0.5),\n        A.ColorJitter (brightness=0.07, contrast=0.07,\n                           saturation=0.1, hue=0.1, always_apply=False, p=0.3)\n    ])\n\ntrain_transform = get_train_transform()\n\ntest_transform = A.Compose([\n    A.Resize(224,224)\n])\n\n\nto_tensor_transform = T.Compose([\n        T.ToTensor(),\n        T.Normalize([0.485, 0.456, 0.406],\n                    [0.229, 0.224, 0.225]),\n    ])\n\n\ndef get_inverse_transform(mean_ = [0.485, 0.456, 0.406], \n                          std_ = [0.229, 0.224, 0.225]):\n    return T.Compose([T.Normalize(mean=[0., 0., 0.],\n                                  std=[1. / std_[0], 1. / std_[1], 1. / std_[2]]),\n                      T.Normalize(mean=[-mean_[0], -mean_[1], -mean_[2]],\n                                  std=[1., 1., 1.]),\n                      ])\n\ninverse_transform = get_inverse_transform()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class TrainDataset(Dataset):\n    def __init__(self, train, transform=None, is_test= False ):\n        self.X = train['path']\n        self.is_test = is_test\n        self.transform = transform\n        if not self.is_test:\n            self.y = train['label']\n    \n    def __len__(self):\n        return len(self.X) \n    \n    def __getitem__(self, index):\n        image = cv2.imread(self.X[index])\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        \n        if self.transform:\n                image = self.transform(image=image)['image'] #.astype(np.float32)\n        \n        if self.is_test:\n             return   to_tensor_transform(image) #.permute(2, 0 ,1).float()\n        else: \n            label = self.y[index]\n            return  to_tensor_transform(image) , label  # .permute(2, 0 ,1).float() \n      \n    # H , W , C\n    # C , H, W\n    ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset = TrainDataset(train, train_transform)\nval_dataset = TrainDataset(val, train_transform)\n\ntrain_dataloader =   DataLoader(train_dataset, batch_size = 16, shuffle = True)\nval_dataloader =   DataLoader(val_dataset, batch_size = 16, shuffle = False)\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def _imshow(img):\n    print(img.shape)\n    img = inverse_transform(img) #    # unnormalize\n    npimg = img.numpy()\n    npimg = np.transpose(npimg, (1, 2, 0))\n    plt.figure(figsize=(20,20))\n    plt.imshow(npimg)\n    plt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataiter = iter(train_dataloader)\nimages, labels = dataiter.next()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#look at single image\nplt.imshow(inverse_transform(images[0]).permute(1,2,0).numpy())","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#make image grid for batch\ndataiter = iter(train_dataloader)\nimages, labels = dataiter.next()\n_imshow(make_grid(images))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_dataset = TrainDataset(test, test_transform, is_test=True)\ntest_dataloader =  DataLoader(test_dataset, batch_size = 16, shuffle = False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # look at tensors shape\n# for image_batch, label_batch in train_dataloader:\n#     print(image_batch.shape, label_batch.shape )","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"resnet = models.resnet101(pretrained = True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"resnet","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# transfer learning \nfor param in resnet.parameters():\n    param.requires_grad=False","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"![](https://www.topbots.com/wp-content/uploads/2020/05/cover_transfer_image_1600px_web.jpg)","metadata":{}},{"cell_type":"code","source":"class NN(nn.Module):\n    def __init__(self, resnet_pretrained):\n        super().__init__()\n        self.resnet_pretrained = resnet_pretrained\n        self.fc1 = nn.Linear(1000, 2)\n        \n    def forward(self, x):\n        x = torch.relu(self.resnet_pretrained(x))\n        x = self.fc1(x)\n        return x","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"our_resnet_model = NN(resnet)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device('cuda:0' if torch.cuda.is_available else 'cpu')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"our_resnet_model = our_resnet_model.to(device)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Trainer:\n    def __init__(self, model, device):\n        self.model = model\n        self.device = device\n    \n        self.loss = nn.CrossEntropyLoss()\n        self.optimizer = optim.Adam( [param for param in self.model.parameters() if param.requires_grad],\n                                    lr=0.001)\n        \n    def fit(self, train_dataloader, val_dataloader, num_epochs):\n        total = 0\n        correct= 0\n        \n        loss_values = []\n        accuracy_values = []\n        \n        for epoch in range(num_epochs):\n            self.model.train()\n            batch_number = 0\n            loss_values_batch = []\n            for x, y in train_dataloader:\n                self.optimizer.zero_grad()\n                x = x.to(self.device)\n                y = y.to(self.device)\n                outputs = self.model(x)\n                l = self.loss(outputs, y)  \n                l.backward()\n                self.optimizer.step()\n                \n                _, predicted = torch.max(outputs, 1)\n                total += y.size(0)\n                correct += (predicted == y).sum().item()\n                loss_value = l.item()\n                loss_values.append(loss_value)\n                accuracy_values.append(correct/total)\n\n               \n                if batch_number%100 ==0:\n                    print(f\"batch number {batch_number}, loss_value: {loss_value}\")\n                    current_accuracy = correct/total\n                    print(f\"current_accuracy: {current_accuracy}\")\n#                     plt.figure(figsize=(5,5))\n#                     plt.plot(loss_values_batch)\n#                     plt.show()\n                    \n                batch_number+= 1\n                \n            epoch_accuracy = correct/total\n            print(f\"epoch_accuracy: {epoch_accuracy}\")\n            print(f\"end of epoch {epoch}\")\n            #make validation \n            \n            epoch_val_loss = []\n            \n            correct = 0\n            total = 0\n            self.model.eval()\n            with torch.no_grad():\n                for x, y in val_dataloader:\n                    x = x.to(self.device)\n                    y = y.to(self.device)\n                    outputs = self.model(x)\n                    l = self.loss(outputs, y)\n                    loss_value = l.item()\n                    epoch_val_loss.append(loss_value)\n                    _, predicted = torch.max(outputs, 1)\n                    total += y.size(0)\n                    correct += (predicted == y).sum().item()\n                    \n            print(f\"Total {total} Correct {correct} Accuracy {correct/total}\")\n        \n#         plt.figure(figsize=(5,5))\n#         plt.plot(loss_values_batch)\n#         plt.show()\n\n    def predict(self, test_dataloader):\n        self.model.eval()\n        predictions = torch.tensor([]) \n        with torch.no_grad():\n            for x  in test_dataloader:\n                x = x.to(self.device)\n                outputs = torch.nn.functional.softmax(self.model(x))\n                predictions = torch.cat([predictions,outputs.detach().cpu()])\n        return predictions.numpy()\n                \n               \n                \n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"trainer = Trainer( model= our_resnet_model, device= device)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"trainer.fit(train_dataloader, val_dataloader, num_epochs=2) ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_predictions= trainer.predict(test_dataloader)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_predictions[0]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_predictions","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test['label']= test_predictions[:,1]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.hist(test['label'], bins = 100)\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in range(0, 40):\n    plt.figure(figsize=(6,6))\n    img = plt.imread(test.loc[i,'path'])\n    plt.imshow(img)\n    plt.title(f\"predicted label: {round(test.loc[i,'label'],3)}\")\n    plt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ss = pd.read_csv('/kaggle/input/dogs-vs-cats-redux-kernels-edition/sample_submission.csv')\ndel ss['label']\ntest['id'] = test['path'].apply(lambda x: int(x.split('/')[-1].split('.')[0]))\nss = ss.merge(test[['id', 'label']], how = 'left', on ='id')\nss.to_csv('submission4.csv', index = None)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}