{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":11848,"databundleVersionId":862157,"sourceType":"competition"}],"dockerImageVersionId":30646,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport numpy as np\nimport torch.optim as optim\nfrom torch.utils.data import Dataset\nfrom torch.utils.data import DataLoader\nimport pandas as pd\nfrom torchmetrics import Accuracy\nimport torch.nn.init as init\nfrom torchvision.datasets import ImageFolder\nfrom torchvision import transforms\nimport os\nfrom PIL import Image, ImageDraw\nfrom sklearn.model_selection import train_test_split\n%matplotlib inline\nimport matplotlib.pyplot as plt\nimport cv2","metadata":{"execution":{"iopub.status.busy":"2024-02-26T12:50:33.862467Z","iopub.execute_input":"2024-02-26T12:50:33.863333Z","iopub.status.idle":"2024-02-26T12:50:33.871756Z","shell.execute_reply.started":"2024-02-26T12:50:33.863299Z","shell.execute_reply":"2024-02-26T12:50:33.870856Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Hyper parameters\nnum_epochs = 15\nnum_classes = 2\nbatch_size = 1300\nlearning_rate = 0.001\n\n# Device configuration\ndevice = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')","metadata":{"execution":{"iopub.status.busy":"2024-02-26T12:50:33.874252Z","iopub.execute_input":"2024-02-26T12:50:33.874516Z","iopub.status.idle":"2024-02-26T12:50:33.884129Z","shell.execute_reply.started":"2024-02-26T12:50:33.874494Z","shell.execute_reply":"2024-02-26T12:50:33.883432Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"torch.cuda.is_available()","metadata":{"execution":{"iopub.status.busy":"2024-02-26T12:50:33.885137Z","iopub.execute_input":"2024-02-26T12:50:33.885424Z","iopub.status.idle":"2024-02-26T12:50:33.899993Z","shell.execute_reply.started":"2024-02-26T12:50:33.8854Z","shell.execute_reply":"2024-02-26T12:50:33.899184Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device","metadata":{"execution":{"iopub.status.busy":"2024-02-26T12:50:33.901088Z","iopub.execute_input":"2024-02-26T12:50:33.901369Z","iopub.status.idle":"2024-02-26T12:50:33.91101Z","shell.execute_reply.started":"2024-02-26T12:50:33.901338Z","shell.execute_reply":"2024-02-26T12:50:33.910259Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = pd.read_csv('/kaggle/input/histopathologic-cancer-detection/train_labels.csv')\nsub = pd.read_csv('/kaggle/input/histopathologic-cancer-detection/sample_submission.csv')\ntrain_path = '/kaggle/input/histopathologic-cancer-detection/train/'\ntest_path = '/kaggle/input/histopathologic-cancer-detection/test/'","metadata":{"execution":{"iopub.status.busy":"2024-02-26T12:50:33.912914Z","iopub.execute_input":"2024-02-26T12:50:33.913199Z","iopub.status.idle":"2024-02-26T12:50:34.163037Z","shell.execute_reply.started":"2024-02-26T12:50:33.913177Z","shell.execute_reply":"2024-02-26T12:50:34.161979Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels.head()","metadata":{"execution":{"iopub.status.busy":"2024-02-26T12:50:34.16431Z","iopub.execute_input":"2024-02-26T12:50:34.164695Z","iopub.status.idle":"2024-02-26T12:50:34.17381Z","shell.execute_reply.started":"2024-02-26T12:50:34.16466Z","shell.execute_reply":"2024-02-26T12:50:34.172825Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Check for duplicate\nlabels[labels.duplicated(keep=False)]","metadata":{"execution":{"iopub.status.busy":"2024-02-26T12:50:34.175394Z","iopub.execute_input":"2024-02-26T12:50:34.176097Z","iopub.status.idle":"2024-02-26T12:50:34.251522Z","shell.execute_reply.started":"2024-02-26T12:50:34.17606Z","shell.execute_reply":"2024-02-26T12:50:34.250557Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels['label'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2024-02-26T12:50:34.25377Z","iopub.execute_input":"2024-02-26T12:50:34.254107Z","iopub.status.idle":"2024-02-26T12:50:34.263243Z","shell.execute_reply.started":"2024-02-26T12:50:34.254077Z","shell.execute_reply":"2024-02-26T12:50:34.262197Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"malignant = labels.loc[labels['label']==1]['id'].values\nprint(malignant[0:3])","metadata":{"execution":{"iopub.status.busy":"2024-02-26T12:50:34.264489Z","iopub.execute_input":"2024-02-26T12:50:34.264891Z","iopub.status.idle":"2024-02-26T12:50:34.279266Z","shell.execute_reply.started":"2024-02-26T12:50:34.264865Z","shell.execute_reply":"2024-02-26T12:50:34.278343Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"normal = labels.loc[labels['label']==0]['id'].values\nprint(normal[0:3])","metadata":{"execution":{"iopub.status.busy":"2024-02-26T12:50:34.280721Z","iopub.execute_input":"2024-02-26T12:50:34.2818Z","iopub.status.idle":"2024-02-26T12:50:34.294575Z","shell.execute_reply.started":"2024-02-26T12:50:34.281773Z","shell.execute_reply":"2024-02-26T12:50:34.293765Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_fig(ids,title,nrows=5,ncols=15):\n\n    fig,ax = plt.subplots(nrows,ncols,figsize=(18,6))\n    plt.subplots_adjust(wspace=0, hspace=0) \n    for i,j in enumerate(ids[:nrows*ncols]):\n        fname = os.path.join(train_path ,j +'.tif')\n        img = Image.open(fname)\n        idcol = ImageDraw.Draw(img)\n        idcol.rectangle(((0,0),(95,95)),outline='white')\n        plt.subplot(nrows, ncols, i+1) \n        plt.imshow(np.array(img))\n        plt.axis('off')\n\n    plt.suptitle(title, y=0.94)","metadata":{"execution":{"iopub.status.busy":"2024-02-26T12:50:34.295737Z","iopub.execute_input":"2024-02-26T12:50:34.296078Z","iopub.status.idle":"2024-02-26T12:50:34.303612Z","shell.execute_reply.started":"2024-02-26T12:50:34.296045Z","shell.execute_reply":"2024-02-26T12:50:34.302857Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_fig(malignant,'Malignant Cases')","metadata":{"execution":{"iopub.status.busy":"2024-02-26T12:50:34.304726Z","iopub.execute_input":"2024-02-26T12:50:34.304977Z","iopub.status.idle":"2024-02-26T12:50:37.054518Z","shell.execute_reply.started":"2024-02-26T12:50:34.304954Z","shell.execute_reply":"2024-02-26T12:50:37.053525Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_fig(normal,'Non-Malignant Cases')","metadata":{"execution":{"iopub.status.busy":"2024-02-26T12:50:37.056242Z","iopub.execute_input":"2024-02-26T12:50:37.056675Z","iopub.status.idle":"2024-02-26T12:50:39.578553Z","shell.execute_reply.started":"2024-02-26T12:50:37.056644Z","shell.execute_reply":"2024-02-26T12:50:39.577587Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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)","metadata":{"execution":{"iopub.status.busy":"2024-02-26T12:50:39.579757Z","iopub.execute_input":"2024-02-26T12:50:39.58004Z","iopub.status.idle":"2024-02-26T12:50:39.688434Z","shell.execute_reply.started":"2024-02-26T12:50:39.580016Z","shell.execute_reply":"2024-02-26T12:50:39.687562Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class MyDataset(Dataset):\n    def __init__(self, df_data, data_dir = './', transform=None):\n        super(Dataset, self).__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","metadata":{"execution":{"iopub.status.busy":"2024-02-26T12:50:39.689457Z","iopub.execute_input":"2024-02-26T12:50:39.689781Z","iopub.status.idle":"2024-02-26T12:50:39.696903Z","shell.execute_reply.started":"2024-02-26T12:50:39.689757Z","shell.execute_reply":"2024-02-26T12:50:39.695777Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_transforms = transforms.Compose([\n    transforms.ToPILImage(),\n    transforms.RandomHorizontalFlip(),\n    transforms.RandomRotation(13),\n    transforms.RandomVerticalFlip(),\n    transforms.ToTensor(),\n    transforms.Resize((96, 96)),\n])\nvalid_transforms = transforms.Compose([\n    transforms.ToPILImage(),\n    transforms.ToTensor(),\n    transforms.Resize((96, 96)),\n])","metadata":{"execution":{"iopub.status.busy":"2024-02-26T12:50:39.700582Z","iopub.execute_input":"2024-02-26T12:50:39.700847Z","iopub.status.idle":"2024-02-26T12:50:39.71178Z","shell.execute_reply.started":"2024-02-26T12:50:39.700824Z","shell.execute_reply":"2024-02-26T12:50:39.711052Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset_train = MyDataset(df_data=train, data_dir=train_path, transform=train_transforms)\ndataset_valid = MyDataset(df_data=val, data_dir=train_path, transform=valid_transforms)","metadata":{"execution":{"iopub.status.busy":"2024-02-26T12:50:39.712738Z","iopub.execute_input":"2024-02-26T12:50:39.712999Z","iopub.status.idle":"2024-02-26T12:50:39.740431Z","shell.execute_reply.started":"2024-02-26T12:50:39.712977Z","shell.execute_reply":"2024-02-26T12:50:39.739572Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"loader_train = DataLoader(dataset = dataset_train, batch_size=batch_size, shuffle=True)\nloader_valid = DataLoader(dataset = dataset_valid, batch_size=batch_size//2, shuffle=False)","metadata":{"execution":{"iopub.status.busy":"2024-02-26T12:50:39.74158Z","iopub.execute_input":"2024-02-26T12:50:39.741911Z","iopub.status.idle":"2024-02-26T12:50:39.753388Z","shell.execute_reply.started":"2024-02-26T12:50:39.741877Z","shell.execute_reply":"2024-02-26T12:50:39.752511Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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.fc = nn.Linear(512 * 4 * 4, 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        #print(x.shape) # lifehack to find out the correct dimension for the Linear Layer\n        x = x.view(-1, 512 * 4 * 4) # !!!\n        x = self.fc(x)\n        return x","metadata":{"execution":{"iopub.status.busy":"2024-02-26T12:50:39.754599Z","iopub.execute_input":"2024-02-26T12:50:39.754852Z","iopub.status.idle":"2024-02-26T12:50:39.766013Z","shell.execute_reply.started":"2024-02-26T12:50:39.754829Z","shell.execute_reply":"2024-02-26T12:50:39.765173Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = SimpleCNN().to(device)","metadata":{"execution":{"iopub.status.busy":"2024-02-26T12:50:39.767144Z","iopub.execute_input":"2024-02-26T12:50:39.767396Z","iopub.status.idle":"2024-02-26T12:50:39.796786Z","shell.execute_reply.started":"2024-02-26T12:50:39.767374Z","shell.execute_reply":"2024-02-26T12:50:39.796033Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# calculate linear forward size\nimage, label = next(iter(loader_train))\nmodel.forward(image)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Loss and optimizer\ncriterion = nn.CrossEntropyLoss()\noptimizer = torch.optim.Adamax(model.parameters(), lr=learning_rate)","metadata":{"execution":{"iopub.status.busy":"2024-02-26T12:50:44.200464Z","iopub.execute_input":"2024-02-26T12:50:44.200829Z","iopub.status.idle":"2024-02-26T12:50:44.206577Z","shell.execute_reply.started":"2024-02-26T12:50:44.200802Z","shell.execute_reply":"2024-02-26T12:50:44.205585Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(loader_train)","metadata":{"execution":{"iopub.status.busy":"2024-02-26T12:50:46.752073Z","iopub.execute_input":"2024-02-26T12:50:46.752706Z","iopub.status.idle":"2024-02-26T12:50:46.758463Z","shell.execute_reply.started":"2024-02-26T12:50:46.752674Z","shell.execute_reply":"2024-02-26T12:50:46.757566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"total_step = len(loader_train)\nfor 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        print ('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}' \n                .format(epoch+1, num_epochs, i+1, total_step, loss.item()))","metadata":{"execution":{"iopub.status.busy":"2024-02-26T12:52:19.822995Z","iopub.execute_input":"2024-02-26T12:52:19.823362Z","iopub.status.idle":"2024-02-26T15:20:42.887628Z","shell.execute_reply.started":"2024-02-26T12:52:19.823334Z","shell.execute_reply":"2024-02-26T15:20:42.886728Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.eval()  # eval mode (batchnorm uses moving mean/variance instead of mini-batch mean/variance)\nwith 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\ntorch.save(model.state_dict(), 'model.ckpt')","metadata":{"execution":{"iopub.status.busy":"2024-02-26T16:00:37.656059Z","iopub.execute_input":"2024-02-26T16:00:37.656868Z","iopub.status.idle":"2024-02-26T16:05:18.484095Z","shell.execute_reply.started":"2024-02-26T16:00:37.656837Z","shell.execute_reply":"2024-02-26T16:05:18.483196Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset_valid = MyDataset(df_data=sub, data_dir=test_path, transform=valid_transforms)\nloader_test = DataLoader(dataset = dataset_valid, batch_size=64)","metadata":{"execution":{"iopub.status.busy":"2024-02-26T16:49:08.105721Z","iopub.execute_input":"2024-02-26T16:49:08.106445Z","iopub.status.idle":"2024-02-26T16:49:08.114985Z","shell.execute_reply.started":"2024-02-26T16:49:08.106412Z","shell.execute_reply":"2024-02-26T16:49:08.114218Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image, label = next(iter(loader_test))","metadata":{"execution":{"iopub.status.busy":"2024-02-26T16:42:31.811499Z","iopub.execute_input":"2024-02-26T16:42:31.812132Z","iopub.status.idle":"2024-02-26T16:42:31.888897Z","shell.execute_reply.started":"2024-02-26T16:42:31.812102Z","shell.execute_reply":"2024-02-26T16:42:31.888105Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"output = model(image.cuda())","metadata":{"execution":{"iopub.status.busy":"2024-02-26T16:44:30.495482Z","iopub.execute_input":"2024-02-26T16:44:30.495831Z","iopub.status.idle":"2024-02-26T16:44:30.502597Z","shell.execute_reply.started":"2024-02-26T16:44:30.495807Z","shell.execute_reply":"2024-02-26T16:44:30.501769Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"torch.max(output.data, 1)","metadata":{"execution":{"iopub.status.busy":"2024-02-26T16:49:16.203997Z","iopub.execute_input":"2024-02-26T16:49:16.204779Z","iopub.status.idle":"2024-02-26T16:49:16.21415Z","shell.execute_reply.started":"2024-02-26T16:49:16.204746Z","shell.execute_reply":"2024-02-26T16:49:16.213239Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"_, pred = torch.max(output.data, 1)","metadata":{"execution":{"iopub.status.busy":"2024-02-26T16:45:53.029987Z","iopub.execute_input":"2024-02-26T16:45:53.030623Z","iopub.status.idle":"2024-02-26T16:45:53.034793Z","shell.execute_reply.started":"2024-02-26T16:45:53.03059Z","shell.execute_reply":"2024-02-26T16:45:53.033814Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred","metadata":{"execution":{"iopub.status.busy":"2024-02-26T16:45:55.897044Z","iopub.execute_input":"2024-02-26T16:45:55.897893Z","iopub.status.idle":"2024-02-26T16:45:55.904779Z","shell.execute_reply.started":"2024-02-26T16:45:55.897854Z","shell.execute_reply":"2024-02-26T16:45:55.903766Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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    _, pred = torch.max(output.data, 1)\n    for i in pred:\n        preds.append(i)\nsub.shape, len(preds)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"outputs = [tensor.cpu().numpy() for tensor in preds]","metadata":{"execution":{"iopub.status.busy":"2024-02-26T16:56:35.831731Z","iopub.execute_input":"2024-02-26T16:56:35.832435Z","iopub.status.idle":"2024-02-26T16:56:36.924229Z","shell.execute_reply.started":"2024-02-26T16:56:35.8324Z","shell.execute_reply":"2024-02-26T16:56:36.923216Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub['label'] = outputs\nsub.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2024-02-26T16:56:56.693267Z","iopub.execute_input":"2024-02-26T16:56:56.693703Z","iopub.status.idle":"2024-02-26T16:56:57.020219Z","shell.execute_reply.started":"2024-02-26T16:56:56.693672Z","shell.execute_reply":"2024-02-26T16:56:57.019187Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub","metadata":{"execution":{"iopub.status.busy":"2024-02-26T16:58:50.873461Z","iopub.execute_input":"2024-02-26T16:58:50.874375Z","iopub.status.idle":"2024-02-26T16:58:50.885359Z","shell.execute_reply.started":"2024-02-26T16:58:50.874338Z","shell.execute_reply":"2024-02-26T16:58:50.884303Z"},"trusted":true},"execution_count":null,"outputs":[]}]}