{"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, glob\nimport matplotlib.pyplot as plt\nfrom tqdm import tqdm\nfrom PIL import Image\n\nimport torch\nfrom torch import nn\nimport torch.nn.functional as F\nfrom torch.autograd import Function\n\nfrom torchvision import utils\nfrom torch import optim\nfrom torch.utils.data import Dataset, DataLoader\n\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-08-11T07:22:25.528663Z","iopub.execute_input":"2021-08-11T07:22:25.529103Z","iopub.status.idle":"2021-08-11T07:22:28.797738Z","shell.execute_reply.started":"2021-08-11T07:22:25.529002Z","shell.execute_reply":"2021-08-11T07:22:28.796750Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# unzipping the files\n#!unzip \"/kaggle/input/carvana-image-masking-challenge/train_hq.zip\" -d './'\n#!unzip \"/kaggle/input/carvana-image-masking-challenge/train.zip\" -d './'\n#!unzip \"/kaggle/input/carvana-image-masking-challenge/train_masks.zip\" -d './'\n#!unzip \"/kaggle/input/carvana-image-masking-challenge/train_masks.csv.zip\" -d './'","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#print(\"train data size: \", len(glob.glob(\"../train_masks/*\")))\n#data = pd.read_csv(\"../train_masks.csv\")\n#data","metadata":{"execution":{"iopub.status.busy":"2021-08-11T07:22:58.923571Z","iopub.execute_input":"2021-08-11T07:22:58.924506Z","iopub.status.idle":"2021-08-11T07:22:58.929510Z","shell.execute_reply.started":"2021-08-11T07:22:58.924454Z","shell.execute_reply":"2021-08-11T07:22:58.928272Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = plt.figure(figsize=(10,10))\nimg = np.array(Image.open(\"/kaggle/working/train/11acc40dc0ea_03.jpg\"))\nimg_mask = np.array(Image.open(\"/kaggle/working/train_masks/11acc40dc0ea_03_mask.gif\"))\n\nplt.subplot(1, 2, 1)\nplt.imshow(img)\n\nplt.subplot(1, 2, 2)\nplt.imshow(img_mask)","metadata":{"execution":{"iopub.status.busy":"2021-08-11T07:22:58.931451Z","iopub.execute_input":"2021-08-11T07:22:58.932089Z","iopub.status.idle":"2021-08-11T07:23:00.253885Z","shell.execute_reply.started":"2021-08-11T07:22:58.932045Z","shell.execute_reply":"2021-08-11T07:23:00.252910Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CarvanaDataset(Dataset):\n    def __init__(self, root_dir, train_img_list):\n        super().__init__()\n        self.img_dir = os.path.join(root_dir, \"train\")\n        self.mask_dir = os.path.join(root_dir, \"train_masks\")\n        self.img_list = train_img_list\n        self.img_transform = A.Compose([\n            A.Resize(256, 256),\n            A.Normalize(mean=[0.485, 0.456, 0.406], \n                        std=[0.229, 0.224, 0.225]),\n            ToTensorV2()\n        ])\n        self.mask_transform = A.Compose([\n            A.Resize(256, 256),\n            ToTensorV2()\n        ])\n    \n    def __len__(self):\n        return len(self.img_list)\n    \n    def __getitem__(self, idx):\n        img_abs_path = os.path.join(self.img_dir, self.img_list[idx])\n        mask_abs_path = os.path.join(\n                self.mask_dir, \n                self.img_list[idx].split(\".\")[0] + \"_mask.gif\")\n    \n        img = np.array(Image.open(img_abs_path))\n        mask = np.array(Image.open(mask_abs_path))\n        \n        img = self.img_transform(image=img)[\"image\"]\n        mask = self.mask_transform(image=mask)[\"image\"]\n        \n        return img, mask","metadata":{"execution":{"iopub.status.busy":"2021-08-11T07:23:00.255494Z","iopub.execute_input":"2021-08-11T07:23:00.255931Z","iopub.status.idle":"2021-08-11T07:23:00.266798Z","shell.execute_reply.started":"2021-08-11T07:23:00.255887Z","shell.execute_reply":"2021-08-11T07:23:00.265732Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_img_list = pd.read_csv(\"/kaggle/working/train_masks.csv\")['img']\ndataset = CarvanaDataset(\"/kaggle/working\", train_img_list)\n\ntrain_size = int(len(train_img_list) * 0.8)\nval_size = len(train_img_list) - train_size\n\ntrain_set, val_set = torch.utils.data.random_split(\n                    dataset, [train_size, val_size])\n\ntrain_loader = DataLoader(train_set, batch_size=8, shuffle=True)\nval_loader = DataLoader(val_set, batch_size=8, shuffle=True)","metadata":{"execution":{"iopub.status.busy":"2021-08-11T07:23:00.268382Z","iopub.execute_input":"2021-08-11T07:23:00.268782Z","iopub.status.idle":"2021-08-11T07:23:00.794653Z","shell.execute_reply.started":"2021-08-11T07:23:00.268743Z","shell.execute_reply":"2021-08-11T07:23:00.793687Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class DoubleConv(nn.Module):\n    def __init__(self, in_channels, out_channels):\n        super().__init__()\n        self.main = nn.Sequential(\n            nn.Conv2d(in_channels, out_channels, 3, stride=1, padding=1),\n            nn.BatchNorm2d(out_channels),\n            nn.ReLU(inplace=True),\n            \n            nn.Conv2d(out_channels, out_channels, 3, stride=1, padding=1),\n            nn.BatchNorm2d(out_channels),\n            nn.ReLU(inplace=True)\n        )\n        \n    def forward(self, x):\n        return self.main(x)\n\nclass Down(nn.Module):\n    def __init__(self, in_channels, out_channels):\n        super().__init__()\n        self.main = nn.Sequential(\n            DoubleConv(in_channels, out_channels),\n            nn.MaxPool2d(2)\n        )\n    def forward(self, x):\n        return self.main(x)\n    \n    \nclass Up(nn.Module):\n    def __init__(self, in_channels, out_channels):\n        super().__init__()\n        \n        mid_channels = in_channels // 2\n        self.up_conv =  nn.ConvTranspose2d(in_channels, mid_channels, \n                               kernel_size=2, stride=2, padding=0)\n        \n        self.double_conv =  DoubleConv(mid_channels*2, out_channels)\n\n        \n    def forward(self, x, copy):\n        x = self.up_conv(x)\n        #pad_lower = (copy.size()[2] - x.size()[2]) // 2\n        #pad_upper = copy.size()[2] - pad_lower\n        #copy = copy[:, :, pad_lower:pad_upper, pad_lower:pad_upper]\n        x = torch.cat([copy, x], dim=1)\n        \n        return self.double_conv(x)\n    \nclass UNet(nn.Module):\n    def __init__(self, img_channels, num_classes, features=64):\n        super().__init__()\n        self.max_pool = nn.MaxPool2d(2)\n        \n        self.dc1 = DoubleConv(img_channels, features)\n        self.dc2 = DoubleConv(features, features*2)\n        self.dc3 = DoubleConv(features*2, features*4)\n        self.dc4 = DoubleConv(features*4, features*8)\n        self.dc5 = DoubleConv(features*8, features*16)\n        \n        self.up1 = Up(features*16, features*8)\n        self.up2 = Up(features*8, features*4)\n        self.up3 = Up(features*4, features*2)\n        self.up4 = Up(features*2, features)\n        \n        self.final = nn.Conv2d(features, num_classes, 1, 1, 0)\n        \n    def forward(self, x):\n        #contracting path\n        d1 = self.dc1(x)\n        d2 = self.dc2(self.max_pool(d1))\n        d3 = self.dc3(self.max_pool(d2))\n        d4 = self.dc4(self.max_pool(d3))\n        x = self.dc5(self.max_pool(d4)) #bottlenek\n        \n        #expansive path\n        x = self.up1(x, d4)\n        x = self.up2(x, d3)\n        x = self.up3(x, d2)\n        x = self.up4(x, d1)\n        return self.final(x)\n    \n    \n","metadata":{"execution":{"iopub.status.busy":"2021-08-11T07:23:00.796256Z","iopub.execute_input":"2021-08-11T07:23:00.796658Z","iopub.status.idle":"2021-08-11T07:23:00.816659Z","shell.execute_reply.started":"2021-08-11T07:23:00.796618Z","shell.execute_reply":"2021-08-11T07:23:00.815730Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class ImageSegment(object):\n    def __init__(self, train_loader, val_loader, device):\n        super().__init__()\n        self.device = device\n        self.train_loader = train_loader\n        self.val_loader = val_loader\n        self.num_classes = 1\n        self.img_channels = 3\n        self.unet = UNet(self.img_channels, self.num_classes).to(device)\n        self.optim = optim.RMSprop(\n            self.unet.parameters(), \n            lr=1e-4, momentum=0.9, weight_decay=1e-8)\n        \n        self.scheduler = optim.lr_scheduler.ReduceLROnPlateau(\n            self.optim, \n            \"min\" if self.num_classes > 1 else \"max\", \n            patience=2)\n        \n        self.criterion = nn.BCEWithLogitsLoss()\n\n    def dice_calc(self, gt, pred) :\n        pred = torch.sigmoid(pred)\n        pred = ((pred) >= .5).float()\n        dice_score = (2 * (pred * gt).sum()) / ((pred + gt).sum() + 1e-8)\n        return dice_score\n    \n    def train(self, num_epochs=1):\n        loop = tqdm(train_loader, leave=False, total=train_loader.__len__())\n        total_loss = 0\n        dice_score = 0\n        \n        for epoch in range(num_epochs):\n            for img, mask in loop:\n                img, mask = img.to(self.device), mask.to(self.device)\n\n                self.optim.zero_grad()\n                mask_pred = self.unet(img)\n                loss = self.criterion(mask_pred, mask.float())\n                total_loss += loss.item()\n                loss.backward()\n                self.optim.step()\n\n                #buji na\n                run_DS = self.dice_calc(mask, mask_pred)\n                dice_score += run_DS\n\n                loop.set_postfix(loss=loss.item())\n\n            print(\"Epoch %d| loss: %f | dice score %f\" % (epoch+1, total_loss, dice_score))\n            \n    def test(self):\n        with torch.no_grad():\n            images ,masks =next(iter(self.val_loader))\n            images = images.to(self.device)\n            masks  = masks.to(self.device)\n\n            mask_pred = self.unet(images)\n\n            img = mask_pred.cpu().numpy()\n            masks = masks.cpu().numpy()\n            masks_2 = (masks > 0.5).astype(int)\n\n            fig, axes = plt.subplots(1, 3, figsize=(15, 15))\n\n            axes[0].imshow(masks[0][0])\n            axes[0].set_title('Ground Truth Mask')\n\n            axes[1].imshow(img[0][0])\n            axes[1].set_title('Prababilistic Mask')\n\n            axes[2].imshow(masks_2[0][0])\n            axes[2].set_title('Probabilistic Mask threshold')","metadata":{"execution":{"iopub.status.busy":"2021-08-11T07:45:44.080295Z","iopub.execute_input":"2021-08-11T07:45:44.080740Z","iopub.status.idle":"2021-08-11T07:45:44.100089Z","shell.execute_reply.started":"2021-08-11T07:45:44.080693Z","shell.execute_reply":"2021-08-11T07:45:44.097592Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n#img_seq = ImageSegment(train_loader, val_loader, device)\n#img_seq.train(num_epochs=7)\n#img_seq.test()","metadata":{"execution":{"iopub.status.busy":"2021-08-11T07:47:15.910875Z","iopub.execute_input":"2021-08-11T07:47:15.911268Z","iopub.status.idle":"2021-08-11T07:47:16.933453Z","shell.execute_reply.started":"2021-08-11T07:47:15.911231Z","shell.execute_reply":"2021-08-11T07:47:16.932336Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}