{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# Libraries\nimport os\nimport numpy as np\nimport pandas as pd\nimport cv2\nimport matplotlib.pyplot as plt\n%matplotlib inline\n\nfrom sklearn.model_selection import train_test_split\n\nimport torch \nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torchvision\nimport torchvision.transforms as transforms\nfrom torch.utils.data import TensorDataset, DataLoader, Dataset","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"## Parameters for model\n\n# Hyper parameters\nnum_epochs = 24\nnum_classes = 2\nbatch_size = 128\nlearning_rate = 0.001\n\n# Device configuration\ndevice = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"labels = pd.read_csv('../input/train_labels.csv')\nsub = pd.read_csv('../input/sample_submission.csv')\ntrain_path = '../input/train/'\ntest_path = '../input/test/'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Splitting data into train and val\ntrain, val = train_test_split(labels, stratify=labels.label, test_size=0.1)\nlen(train), len(val)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class MyDataset(Dataset):\n    def __init__(self, df_data, data_dir = './', transform=None):\n        super().__init__()\n        self.df = df_data.values\n        self.data_dir = data_dir\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.df)\n    \n    def __getitem__(self, index):\n        img_name,label = self.df[index]\n        img_path = os.path.join(self.data_dir, img_name+'.tif')\n        image = cv2.imread(img_path)\n        if self.transform is not None:\n            image = self.transform(image)\n        return image, label","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"trans_train = transforms.Compose([transforms.ToPILImage(),\n                                  transforms.Pad(64, padding_mode='reflect'),\n                                  transforms.RandomHorizontalFlip(), \n                                  transforms.RandomVerticalFlip(),\n                                  #transforms.RandomCrop(),\n                                  transforms.RandomRotation(20),\n                                  \n                                  transforms.ToTensor(),\n                                  transforms.Normalize(mean=[0.5, 0.5, 0.5],std=[0.5, 0.5, 0.5])])\n\ntrans_valid = transforms.Compose([transforms.ToPILImage(),\n                                  transforms.Pad(64, padding_mode='reflect'),\n                                  transforms.ToTensor(),\n                                  transforms.Normalize(mean=[0.5, 0.5, 0.5],std=[0.5, 0.5, 0.5])])\n\ndataset_train = MyDataset(df_data=train, data_dir=train_path, transform=trans_train)\ndataset_valid = MyDataset(df_data=val, data_dir=train_path, transform=trans_valid)\n\nloader_train = DataLoader(dataset = dataset_train, batch_size=batch_size, shuffle=True, num_workers=0)\nloader_valid = DataLoader(dataset = dataset_valid, batch_size=batch_size//2, shuffle=False, num_workers=0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"len(loader_valid)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class SimpleCNN(nn.Module):\n    def __init__(self):\n        # ancestor constructor call\n        super(SimpleCNN, self).__init__()\n        self.conv1 = nn.Conv2d(in_channels=3, out_channels=32, kernel_size=3, padding=2)\n        self.conv2 = nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3, padding=2)\n        self.conv3 = nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3, padding=2)\n        self.conv4 = nn.Conv2d(in_channels=128, out_channels=256, kernel_size=3, padding=2)\n        self.conv5 = nn.Conv2d(in_channels=256, out_channels=512, kernel_size=3, padding=2)\n        self.bn1 = nn.BatchNorm2d(32)\n        self.bn2 = nn.BatchNorm2d(64)\n        self.bn3 = nn.BatchNorm2d(128)\n        self.bn4 = nn.BatchNorm2d(256)\n        self.bn5 = nn.BatchNorm2d(512)\n        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)\n        self.avg = nn.AvgPool2d(8)\n        self.fc = nn.Linear(512 * 1 * 1, 2) # !!!\n    def forward(self, x):\n        x = self.pool(F.leaky_relu(self.bn1(self.conv1(x)))) # first convolutional layer then batchnorm, then activation then pooling layer.\n        x = self.pool(F.leaky_relu(self.bn2(self.conv2(x))))\n        x = self.pool(F.leaky_relu(self.bn3(self.conv3(x))))\n        x = self.pool(F.leaky_relu(self.bn4(self.conv4(x))))\n        x = self.pool(F.leaky_relu(self.bn5(self.conv5(x))))\n        x = self.avg(x)\n        #print(x.shape) # lifehack to find out the correct dimension for the Linear Layer\n        x = x.view(-1, 512 * 1 * 1) # !!!\n        x = self.fc(x)\n        return x","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = SimpleCNN().to(device)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Loss and optimizer\ncriterion = nn.CrossEntropyLoss()\noptimizer = torch.optim.Adamax(model.parameters(), lr=learning_rate)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Model got trained for almost 8 hours**"},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\ntrain_losses, test_losses = [],[]\nfor epoch in range(num_epochs):\n    running_loss = 0\n    for images, labels in loader_train:\n        images = images.to(device)\n        labels = labels.to(device)\n        \n        optimizer.zero_grad()\n        \n        log_ps = model(images)\n        loss = criterion(log_ps, labels)\n        loss.backward()\n        optimizer.step()\n        \n        running_loss += loss.item()\n        \n    else:\n        ## TODO: Implement the validation pass and print out the validation accuracy\n        test_loss = 0\n        accuracy = 0\n        # Test the model\n        model.eval()  # eval mode (batchnorm uses moving mean/variance instead of mini-batch mean/variance)\n        with torch.no_grad():\n            for images, labels in loader_valid:\n                images = images.to(device)\n                labels = labels.to(device)\n                \n                log_ps = model(images)\n                test_loss += criterion(log_ps, labels)\n                \n                ps = torch.exp(log_ps)\n                top_p, top_class = ps.topk(1, dim=1)\n                equals = top_class == labels.view(*top_class.shape)\n                accuracy += torch.mean(equals.type(torch.FloatTensor))\n                \n                                \n        train_losses.append(running_loss/len(loader_train))\n        test_losses.append(test_loss/len(loader_valid))\n        \n        print(\"Epoch: {}/{}..\".format(epoch+1, num_epochs),\n             \"Training Loss: {:.3f}..\".format(running_loss/len(loader_train)),\n             \"Test Loss: {:3f}.. \".format(test_loss/len(loader_valid)),\n             \"Test Accuracy: {:.3f}\".format(accuracy/len(loader_valid)))\n        \n        torch.save(model.state_dict(), 'model1.ckpt')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%matplotlib inline\n%config InlineBackend.figure_format = 'retina'\n\nimport matplotlib.pyplot as plt","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.plot(train_losses, label='Training loss')\nplt.plot(test_losses, label=\"validation loss\")\nplt.legend(frameon=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"torch.save(model.state_dict(), 'model1.ckpt')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dataset_valid = MyDataset(df_data=sub, data_dir=test_path, transform=trans_valid)\nloader_test = DataLoader(dataset = dataset_valid, batch_size=32, shuffle=False, num_workers=0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.eval()\n\npreds = []\nfor batch_i, (data, target) in enumerate(loader_test):\n    data, target = data.cuda(), target.cuda()\n    output = model(data)\n\n    pr = output[:,1].detach().cpu().numpy()\n    for i in pr:\n        preds.append(i)\nsub.shape, len(preds)\nsub['label'] = preds\nsub.to_csv('s.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Train the model\n#total_step = len(loader_train)\n#for epoch in range(num_epochs):\n#    for i, (images, labels) in enumerate(loader_train):\n##        images = images.to(device)\n #       labels = labels.to(device)\n #       \n#        # Forward pass\n#        outputs = model(images)\n#        loss = criterion(outputs, labels)\n#        \n#        # Backward and optimize\n#        optimizer.zero_grad()\n#        loss.backward()\n#        optimizer.step()\n#        \n#        if (i+1) % 100 == 0:\n#            print ('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}' \n#                   .format(epoch+1, num_epochs, i+1, total_step, loss.item()))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Test the model\n#model.eval()  # eval mode (batchnorm uses moving mean/variance instead of mini-batch mean/variance)\n#with torch.no_grad():\n#    correct = 0\n#    total = 0\n#    for images, labels in loader_valid:\n#        images = images.to(device)\n#        labels = labels.to(device)\n#        outputs = model(images)\n#        _, predicted = torch.max(outputs.data, 1)\n#        total += labels.size(0)\n#        correct += (predicted == labels).sum().item()\n#          \n#    print('Test Accuracy of the model on the 22003 test images: {} %'.format(100 * correct / total))\n\n# Save the model checkpoint\n#torch.save(model.state_dict(), 'model.ckpt')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# import the modules we'll need\nfrom IPython.display import HTML\nimport pandas as pd\nimport numpy as np\nimport base64\n\n# function that takes in a dataframe and creates a text link to  \n# download it (will only work for files < 2MB or so)\ndef create_download_link(df, title = \"Download CSV file\", filename = \"s.csv\"):  \n    csv = df.to_csv()\n    b64 = base64.b64encode(csv.encode())\n    payload = b64.decode()\n    html = '<a download=\"{filename}\" href=\"data:text/csv;base64,{payload}\" target=\"_blank\">{title}</a>'\n    html = html.format(payload=payload,title=title,filename=filename)\n    return HTML(html)\n\n# create a random sample dataframe\n#df = pd.DataFrame(np.random.randn(50, 4), columns=list('ABCD'))\n\n# create a link to download the dataframe\ncreate_download_link(sub)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"my_submission = pd.DataFrame(sub)\n# you could use any filename. We choose submission here\nmy_submission.to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}