{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[],"dockerImageVersionId":28755,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport cv2\nimport torch\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport torch.nn as nn\n\nfrom glob import glob\nfrom torch.utils.data import Dataset\nfrom torch.utils.data import random_split\nfrom torch.utils.data import DataLoader\n\n\nroot_dir = \"/kaggle/working/\"\n\ndevice = torch.device(\n    \"cuda\" if torch.cuda.is_available() else \"cpu\"\n)\n\nprint(device)","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-07-04T20:49:33.09697Z","iopub.execute_input":"2026-07-04T20:49:33.097649Z","iopub.status.idle":"2026-07-04T20:49:35.057017Z","shell.execute_reply.started":"2026-07-04T20:49:33.097614Z","shell.execute_reply":"2026-07-04T20:49:35.056304Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\n\nfor root, dirs, files in os.walk(\"/kaggle/input/competitions/carvana-image-masking-challenge\"):\n    print(root)\n    print(files[:5])\n    print(\"-\"*50)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T20:49:35.058317Z","iopub.execute_input":"2026-07-04T20:49:35.05873Z","iopub.status.idle":"2026-07-04T20:49:35.06496Z","shell.execute_reply.started":"2026-07-04T20:49:35.058704Z","shell.execute_reply":"2026-07-04T20:49:35.064381Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# import zipfile\n# import os\n\n# os.makedirs(\"/kaggle/working/train\", exist_ok=True)\n# os.makedirs(\"/kaggle/working/train_masks\", exist_ok=True)\n\n# with zipfile.ZipFile(\n#     \"/kaggle/input/competitions/carvana-image-masking-challenge/train.zip\"\n# ) as z:\n#     z.extractall(\"/kaggle/working/train\")\n\n# with zipfile.ZipFile(\n#     \"/kaggle/input/competitions/carvana-image-masking-challenge/train_masks.zip\"\n# ) as z:\n#     z.extractall(\"/kaggle/working/train_masks\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T20:49:35.065924Z","iopub.execute_input":"2026-07-04T20:49:35.066646Z","iopub.status.idle":"2026-07-04T20:49:35.07549Z","shell.execute_reply.started":"2026-07-04T20:49:35.066584Z","shell.execute_reply":"2026-07-04T20:49:35.074692Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class CarvanaDataset(Dataset):\n\n    def __init__(self,image_dir,mask_dir,size=256):\n\n        self.image_dir=image_dir\n        self.mask_dir=mask_dir\n        self.size=size\n\n        self.images=sorted(glob(os.path.join(image_dir,\"*.jpg\")))\n\n    def __len__(self):\n\n        return len(self.images)\n\n    def __getitem__(self,index):\n\n        image_path=self.images[index]\n\n        name=os.path.basename(image_path)\n\n        mask_name=name.replace(\".jpg\",\"_mask.gif\")\n\n        mask_path=os.path.join(self.mask_dir,mask_name)\n\n        image=cv2.imread(image_path)\n        image=cv2.cvtColor(image,cv2.COLOR_BGR2RGB)\n        image=cv2.resize(image,(self.size,self.size))\n        image=image.astype(np.float32)/255.0\n        image=np.transpose(image,(2,0,1))\n        image=torch.tensor(image,dtype=torch.float32)\n\n        mask=cv2.imread(mask_path,0)\n        mask=cv2.resize(mask,(self.size,self.size))\n        mask=(mask>0).astype(np.float32)\n        mask=np.expand_dims(mask,0)\n        mask=torch.tensor(mask,dtype=torch.float32)\n\n        return image,mask","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T20:49:35.077234Z","iopub.execute_input":"2026-07-04T20:49:35.077427Z","iopub.status.idle":"2026-07-04T20:49:35.088204Z","shell.execute_reply.started":"2026-07-04T20:49:35.077409Z","shell.execute_reply":"2026-07-04T20:49:35.087518Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"image_dir = \"/kaggle/working/train\"\nmask_dir = \"/kaggle/working/train_masks\"\n\ndataset = CarvanaDataset(image_dir, mask_dir)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T20:49:35.089078Z","iopub.execute_input":"2026-07-04T20:49:35.089332Z","iopub.status.idle":"2026-07-04T20:49:35.11629Z","shell.execute_reply.started":"2026-07-04T20:49:35.089311Z","shell.execute_reply":"2026-07-04T20:49:35.115709Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"image, mask = dataset[0]\n\nprint(image.shape)\n\nprint(mask.shape)\n\nprint(mask.unique())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T20:49:35.117116Z","iopub.execute_input":"2026-07-04T20:49:35.117511Z","iopub.status.idle":"2026-07-04T20:49:35.188715Z","shell.execute_reply.started":"2026-07-04T20:49:35.117484Z","shell.execute_reply":"2026-07-04T20:49:35.187948Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def show_sample(dataset, index):\n\n    image, mask = dataset[index]\n\n    image = image.permute(1,2,0).numpy()\n\n    mask = mask.squeeze().numpy()\n\n    fig, ax = plt.subplots(\n        1,\n        2,\n        figsize=(10,5)\n    )\n\n    ax[0].imshow(image)\n    ax[0].set_title(\"Image\")\n    ax[0].axis(\"off\")\n\n    ax[1].imshow(mask, cmap=\"gray\")\n    ax[1].set_title(\"Mask\")\n    ax[1].axis(\"off\")\n\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T20:49:35.190478Z","iopub.execute_input":"2026-07-04T20:49:35.19074Z","iopub.status.idle":"2026-07-04T20:49:35.196898Z","shell.execute_reply.started":"2026-07-04T20:49:35.190716Z","shell.execute_reply":"2026-07-04T20:49:35.195911Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"show_sample(dataset, 5)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T20:49:35.197633Z","iopub.execute_input":"2026-07-04T20:49:35.197822Z","iopub.status.idle":"2026-07-04T20:49:35.413926Z","shell.execute_reply.started":"2026-07-04T20:49:35.197803Z","shell.execute_reply":"2026-07-04T20:49:35.413048Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dataset_size = len(dataset)\n\ntrain_size = int(0.7 * dataset_size)\n\nval_size = int(0.15 * dataset_size)\n\ntest_size = dataset_size - train_size - val_size\n\ntrain_dataset, val_dataset, test_dataset = random_split(\n\n    dataset,\n\n    [train_size, val_size, test_size]\n\n)\n\nprint(len(train_dataset))\n\nprint(len(val_dataset))\n\nprint(len(test_dataset))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T20:49:35.414897Z","iopub.execute_input":"2026-07-04T20:49:35.415212Z","iopub.status.idle":"2026-07-04T20:49:35.421468Z","shell.execute_reply.started":"2026-07-04T20:49:35.415179Z","shell.execute_reply":"2026-07-04T20:49:35.420514Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"batch_size = 8\n\ntrain_loader = DataLoader(\n\n    train_dataset,\n\n    batch_size=batch_size,\n\n    shuffle=True\n\n)\n\nval_loader = DataLoader(\n\n    val_dataset,\n\n    batch_size=batch_size,\n\n    shuffle=False\n\n)\n\ntest_loader = DataLoader(\n\n    test_dataset,\n\n    batch_size=batch_size,\n\n    shuffle=False\n\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T20:49:35.424262Z","iopub.execute_input":"2026-07-04T20:49:35.424606Z","iopub.status.idle":"2026-07-04T20:49:35.438569Z","shell.execute_reply.started":"2026-07-04T20:49:35.424556Z","shell.execute_reply":"2026-07-04T20:49:35.437918Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class ConvBlock(nn.Module):\n\n    def __init__(self, in_channels, out_channels):\n\n        super().__init__()\n\n        self.block = nn.Sequential(\n\n            nn.Conv2d(\n                in_channels,\n                out_channels,\n                kernel_size=3,\n                padding=1\n            ),\n\n            nn.BatchNorm2d(out_channels),\n\n            nn.ReLU(inplace=True),\n\n            nn.Conv2d(\n                out_channels,\n                out_channels,\n                kernel_size=3,\n                padding=1\n            ),\n\n            nn.BatchNorm2d(out_channels),\n\n            nn.ReLU(inplace=True)\n\n        )\n\n    def forward(self, x):\n\n        return self.block(x)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T20:49:35.439601Z","iopub.execute_input":"2026-07-04T20:49:35.43983Z","iopub.status.idle":"2026-07-04T20:49:35.451916Z","shell.execute_reply.started":"2026-07-04T20:49:35.43981Z","shell.execute_reply":"2026-07-04T20:49:35.451044Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class EncoderBlock(nn.Module):\n\n    def __init__(self, in_channels, out_channels):\n\n        super().__init__()\n\n        self.conv = ConvBlock(\n            in_channels,\n            out_channels\n        )\n\n        self.pool = nn.MaxPool2d(2)\n\n    def forward(self, x):\n\n        skip = self.conv(x)\n\n        down = self.pool(skip)\n\n        return skip, down","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T20:49:35.452937Z","iopub.execute_input":"2026-07-04T20:49:35.453266Z","iopub.status.idle":"2026-07-04T20:49:35.464982Z","shell.execute_reply.started":"2026-07-04T20:49:35.453232Z","shell.execute_reply":"2026-07-04T20:49:35.464374Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class DecoderBlock(nn.Module):\n\n    def __init__(self, in_channels, out_channels):\n\n        super().__init__()\n\n        self.up = nn.ConvTranspose2d(\n\n            in_channels,\n\n            out_channels,\n\n            kernel_size=2,\n\n            stride=2\n\n        )\n\n        self.conv = ConvBlock(\n\n            out_channels * 2,\n\n            out_channels\n\n        )\n\n    def forward(self, x, skip):\n\n        x = self.up(x)\n\n        x = torch.cat(\n            [skip, x],\n            dim=1\n        )\n\n        x = self.conv(x)\n\n        return x","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T20:49:35.465824Z","iopub.execute_input":"2026-07-04T20:49:35.466676Z","iopub.status.idle":"2026-07-04T20:49:35.477844Z","shell.execute_reply.started":"2026-07-04T20:49:35.46665Z","shell.execute_reply":"2026-07-04T20:49:35.477062Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class UNet(nn.Module):\n\n    def __init__(self):\n\n        super().__init__()\n\n        self.e1 = EncoderBlock(3, 64)\n\n        self.e2 = EncoderBlock(64, 128)\n\n        self.e3 = EncoderBlock(128, 256)\n\n        self.e4 = EncoderBlock(256, 512)\n\n        self.bridge = ConvBlock(\n            512,\n            1024\n        )\n\n        self.d4 = DecoderBlock(\n            1024,\n            512\n        )\n\n        self.d3 = DecoderBlock(\n            512,\n            256\n        )\n\n        self.d2 = DecoderBlock(\n            256,\n            128\n        )\n\n        self.d1 = DecoderBlock(\n            128,\n            64\n        )\n\n        self.output = nn.Conv2d(\n            64,\n            1,\n            kernel_size=1\n        )\n\n    def forward(self, x):\n\n        s1, p1 = self.e1(x)\n\n        s2, p2 = self.e2(p1)\n\n        s3, p3 = self.e3(p2)\n\n        s4, p4 = self.e4(p3)\n\n        b = self.bridge(p4)\n\n        d4 = self.d4(b, s4)\n\n        d3 = self.d3(d4, s3)\n\n        d2 = self.d2(d3, s2)\n\n        d1 = self.d1(d2, s1)\n\n        out = self.output(d1)\n\n        return out","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T20:49:35.478782Z","iopub.execute_input":"2026-07-04T20:49:35.479051Z","iopub.status.idle":"2026-07-04T20:49:35.494391Z","shell.execute_reply.started":"2026-07-04T20:49:35.479024Z","shell.execute_reply":"2026-07-04T20:49:35.493653Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = UNet().to(device)\n\nprint(model)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T20:49:35.495382Z","iopub.execute_input":"2026-07-04T20:49:35.495681Z","iopub.status.idle":"2026-07-04T20:49:36.003986Z","shell.execute_reply.started":"2026-07-04T20:49:35.49565Z","shell.execute_reply":"2026-07-04T20:49:36.003288Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sample = torch.randn(\n    1,\n    3,\n    256,\n    256\n).to(device)\n\noutput = model(sample)\n\nprint(output.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T20:49:36.00485Z","iopub.execute_input":"2026-07-04T20:49:36.005253Z","iopub.status.idle":"2026-07-04T20:49:36.281741Z","shell.execute_reply.started":"2026-07-04T20:49:36.005226Z","shell.execute_reply":"2026-07-04T20:49:36.281043Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"total_params = sum(\n\n    p.numel()\n\n    for p in model.parameters()\n\n)\n\nprint(\"Total Parameters :\", total_params)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T20:49:36.283556Z","iopub.execute_input":"2026-07-04T20:49:36.283985Z","iopub.status.idle":"2026-07-04T20:49:36.288821Z","shell.execute_reply.started":"2026-07-04T20:49:36.283959Z","shell.execute_reply":"2026-07-04T20:49:36.288047Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class DiceLoss(nn.Module):\n\n    def __init__(self):\n\n        super().__init__()\n\n    def forward(self, pred, target):\n\n        pred = torch.sigmoid(pred)\n\n        pred = pred.view(-1)\n\n        target = target.view(-1)\n\n        smooth = 1.0\n\n        intersection = (pred * target).sum()\n\n        dice = (2.0 * intersection + smooth) / (\n            pred.sum() + target.sum() + smooth\n        )\n\n        return 1 - dice","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T20:49:36.289825Z","iopub.execute_input":"2026-07-04T20:49:36.290149Z","iopub.status.idle":"2026-07-04T20:49:36.301503Z","shell.execute_reply.started":"2026-07-04T20:49:36.290099Z","shell.execute_reply":"2026-07-04T20:49:36.300767Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def iou_score(pred, target):\n\n    pred = torch.sigmoid(pred)\n\n    pred = (pred > 0.5).float()\n\n    pred = pred.view(-1)\n\n    target = target.view(-1)\n\n    intersection = (pred * target).sum()\n\n    union = pred.sum() + target.sum() - intersection\n\n    iou = (intersection + 1e-6) / (union + 1e-6)\n\n    return iou.item()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T20:49:36.302262Z","iopub.execute_input":"2026-07-04T20:49:36.302541Z","iopub.status.idle":"2026-07-04T20:49:36.317596Z","shell.execute_reply.started":"2026-07-04T20:49:36.302518Z","shell.execute_reply":"2026-07-04T20:49:36.316688Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def dice_score(pred, target):\n\n    pred = torch.sigmoid(pred)\n\n    pred = (pred > 0.5).float()\n\n    pred = pred.view(-1)\n\n    target = target.view(-1)\n\n    intersection = (pred * target).sum()\n\n    dice = (2 * intersection + 1e-6) / (\n        pred.sum() + target.sum() + 1e-6\n    )\n\n    return dice.item()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T20:49:36.318797Z","iopub.execute_input":"2026-07-04T20:49:36.319114Z","iopub.status.idle":"2026-07-04T20:49:36.327228Z","shell.execute_reply.started":"2026-07-04T20:49:36.319074Z","shell.execute_reply":"2026-07-04T20:49:36.326405Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"criterion = DiceLoss()\n\noptimizer = torch.optim.Adam(\n\n    model.parameters(),\n\n    lr=0.001\n\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T20:49:36.328162Z","iopub.execute_input":"2026-07-04T20:49:36.328449Z","iopub.status.idle":"2026-07-04T20:49:37.355029Z","shell.execute_reply.started":"2026-07-04T20:49:36.328418Z","shell.execute_reply":"2026-07-04T20:49:37.35418Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def train_one_epoch(loader):\n\n    model.train()\n\n    total_loss = 0\n\n    total_dice = 0\n\n    total_iou = 0\n\n    for images, masks in loader:\n\n        images = images.to(device)\n\n        masks = masks.to(device)\n\n        optimizer.zero_grad()\n\n        outputs = model(images)\n\n        loss = criterion(outputs, masks)\n\n        loss.backward()\n\n        optimizer.step()\n\n        total_loss += loss.item()\n\n        total_dice += dice_score(outputs, masks)\n\n        total_iou += iou_score(outputs, masks)\n\n    n = len(loader)\n\n    return (\n\n        total_loss / n,\n\n        total_dice / n,\n\n        total_iou / n\n\n    )","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T20:49:37.356024Z","iopub.execute_input":"2026-07-04T20:49:37.356424Z","iopub.status.idle":"2026-07-04T20:49:37.362691Z","shell.execute_reply.started":"2026-07-04T20:49:37.356392Z","shell.execute_reply":"2026-07-04T20:49:37.362048Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def validate(loader):\n\n    model.eval()\n\n    total_loss = 0\n\n    total_dice = 0\n\n    total_iou = 0\n\n    with torch.no_grad():\n\n        for images, masks in loader:\n\n            images = images.to(device)\n\n            masks = masks.to(device)\n\n            outputs = model(images)\n\n            loss = criterion(outputs, masks)\n\n            total_loss += loss.item()\n\n            total_dice += dice_score(outputs, masks)\n\n            total_iou += iou_score(outputs, masks)\n\n    n = len(loader)\n\n    return (\n\n        total_loss / n,\n\n        total_dice / n,\n\n        total_iou / n\n\n    )","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T20:49:37.363643Z","iopub.execute_input":"2026-07-04T20:49:37.364079Z","iopub.status.idle":"2026-07-04T20:49:37.377582Z","shell.execute_reply.started":"2026-07-04T20:49:37.364044Z","shell.execute_reply":"2026-07-04T20:49:37.376896Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_loss = []\n\nval_loss = []\n\ntrain_dice = []\n\nval_dice = []\n\ntrain_iou = []\n\nval_iou = []","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T20:49:37.37843Z","iopub.execute_input":"2026-07-04T20:49:37.378708Z","iopub.status.idle":"2026-07-04T20:49:37.395207Z","shell.execute_reply.started":"2026-07-04T20:49:37.378677Z","shell.execute_reply":"2026-07-04T20:49:37.394407Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"best_loss = 100\nEPOCHS=5\n\n\nfor epoch in range(EPOCHS):\n\n    loss1, dice1, iou1 = train_one_epoch(\n\n        train_loader\n\n    )\n\n    loss2, dice2, iou2 = validate(\n\n        val_loader\n\n    )\n\n    train_loss.append(loss1)\n\n    val_loss.append(loss2)\n\n    train_dice.append(dice1)\n\n    val_dice.append(dice2)\n\n    train_iou.append(iou1)\n\n    val_iou.append(iou2)\n\n    print(\n\n        f\"Epoch [{epoch+1}/{EPOCHS}]\",\n\n        f\"Train Loss : {loss1:.4f}\",\n\n        f\"Val Loss : {loss2:.4f}\",\n\n        f\"Dice : {dice2:.4f}\",\n\n        f\"IoU : {iou2:.4f}\"\n\n    )\n\n    if loss2 < best_loss:\n\n        best_loss = loss2\n\n        torch.save(\n\n            model.state_dict(),\n\n            \"best_unet.pth\"\n\n        )","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T20:58:27.529052Z","iopub.execute_input":"2026-07-04T20:58:27.529572Z","iopub.status.idle":"2026-07-04T21:30:32.499712Z","shell.execute_reply.started":"2026-07-04T20:58:27.529538Z","shell.execute_reply":"2026-07-04T21:30:32.498563Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.load_state_dict(\n\n    torch.load(\n\n        \"best_unet.pth\",\n\n        map_location=device\n\n    )\n\n)\n\nmodel.eval()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T21:32:23.483682Z","iopub.execute_input":"2026-07-04T21:32:23.484213Z","iopub.status.idle":"2026-07-04T21:32:23.609735Z","shell.execute_reply.started":"2026-07-04T21:32:23.484177Z","shell.execute_reply":"2026-07-04T21:32:23.608999Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def test_model(loader):\n\n    model.eval()\n\n    dice_scores = []\n\n    iou_scores = []\n\n    with torch.no_grad():\n\n        for images, masks in loader:\n\n            images = images.to(device)\n\n            masks = masks.to(device)\n\n            outputs = model(images)\n\n            dice_scores.append(\n                dice_score(outputs, masks)\n            )\n\n            iou_scores.append(\n                iou_score(outputs, masks)\n            )\n\n    print()\n\n    print(\"Average Dice :\", round(np.mean(dice_scores), 4))\n\n    print(\"Average IoU  :\", round(np.mean(iou_scores), 4))\n\n    return dice_scores, iou_scores","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T21:34:54.058748Z","iopub.execute_input":"2026-07-04T21:34:54.059456Z","iopub.status.idle":"2026-07-04T21:34:54.064736Z","shell.execute_reply.started":"2026-07-04T21:34:54.059425Z","shell.execute_reply":"2026-07-04T21:34:54.063821Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dice_scores, iou_scores = test_model(test_loader)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T21:32:41.363428Z","iopub.execute_input":"2026-07-04T21:32:41.363833Z","iopub.status.idle":"2026-07-04T21:33:26.627815Z","shell.execute_reply.started":"2026-07-04T21:32:41.363804Z","shell.execute_reply":"2026-07-04T21:33:26.626847Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.eval()\n\nimages, masks = next(iter(test_loader))\n\nimages = images.to(device)\n\nwith torch.no_grad():\n\n    outputs = model(images)\n\noutputs = torch.sigmoid(outputs)\n\noutputs = (outputs > 0.5).float()\n\nimages = images.cpu()\n\nmasks = masks.cpu()\n\noutputs = outputs.cpu()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T21:33:34.884683Z","iopub.execute_input":"2026-07-04T21:33:34.885519Z","iopub.status.idle":"2026-07-04T21:33:35.441341Z","shell.execute_reply.started":"2026-07-04T21:33:34.885487Z","shell.execute_reply":"2026-07-04T21:33:35.440719Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"samples = 3\n\nplt.figure(figsize=(12, 10))\n\nfor i in range(samples):\n\n    plt.subplot(samples, 3, i*3 + 1)\n\n    plt.imshow(\n        images[i].permute(1,2,0)\n    )\n\n    plt.title(\"Input\")\n\n    plt.axis(\"off\")\n\n\n    plt.subplot(samples,3,i*3+2)\n\n    plt.imshow(\n        masks[i].squeeze(),\n        cmap=\"gray\"\n    )\n\n    plt.title(\"Ground Truth\")\n\n    plt.axis(\"off\")\n\n\n    plt.subplot(samples,3,i*3+3)\n\n    plt.imshow(\n        outputs[i].squeeze(),\n        cmap=\"gray\"\n    )\n\n    plt.title(\"Prediction\")\n\n    plt.axis(\"off\")\n\nplt.tight_layout()\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T21:33:40.078489Z","iopub.execute_input":"2026-07-04T21:33:40.078895Z","iopub.status.idle":"2026-07-04T21:33:40.622778Z","shell.execute_reply.started":"2026-07-04T21:33:40.078865Z","shell.execute_reply":"2026-07-04T21:33:40.621855Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(8,5))\n\nplt.plot(\n\n    train_dice,\n\n    label=\"Train Dice\",\n\n    linewidth=2\n\n)\n\nplt.plot(\n\n    val_dice,\n\n    label=\"Validation Dice\",\n\n    linewidth=2\n\n)\n\nplt.xlabel(\"Epoch\")\n\nplt.ylabel(\"Dice Score\")\n\nplt.title(\"Dice Score Curve\")\n\nplt.legend()\n\nplt.grid(True)\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T21:33:49.158342Z","iopub.execute_input":"2026-07-04T21:33:49.158895Z","iopub.status.idle":"2026-07-04T21:33:49.307957Z","shell.execute_reply.started":"2026-07-04T21:33:49.158864Z","shell.execute_reply":"2026-07-04T21:33:49.307183Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(8,5))\n\nplt.plot(\n\n    train_loss,\n\n    label=\"Train Loss\"\n\n)\n\nplt.plot(\n\n    val_loss,\n\n    label=\"Validation Loss\"\n\n)\n\nplt.xlabel(\"Epoch\")\n\nplt.ylabel(\"Loss\")\n\nplt.title(\"Training Loss\")\n\nplt.legend()\n\nplt.grid(True)\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T21:33:55.918349Z","iopub.execute_input":"2026-07-04T21:33:55.919009Z","iopub.status.idle":"2026-07-04T21:33:56.04908Z","shell.execute_reply.started":"2026-07-04T21:33:55.918975Z","shell.execute_reply":"2026-07-04T21:33:56.048426Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(6,6))\n\nplt.boxplot(\n\n    iou_scores,\n\n    patch_artist=True\n\n)\n\nplt.ylabel(\"IoU\")\n\nplt.title(\"IoU Score Distribution\")\n\nplt.grid(True)\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T21:34:03.024517Z","iopub.execute_input":"2026-07-04T21:34:03.025272Z","iopub.status.idle":"2026-07-04T21:34:03.126712Z","shell.execute_reply.started":"2026-07-04T21:34:03.025243Z","shell.execute_reply":"2026-07-04T21:34:03.126047Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print()\n\nprint(\"========== Final Result ==========\")\n\nprint()\n\nprint(\"Dice Score :\", round(np.mean(dice_scores),4))\n\nprint(\"IoU Score  :\", round(np.mean(iou_scores),4))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T21:34:09.039062Z","iopub.execute_input":"2026-07-04T21:34:09.039748Z","iopub.status.idle":"2026-07-04T21:34:09.044678Z","shell.execute_reply.started":"2026-07-04T21:34:09.039715Z","shell.execute_reply":"2026-07-04T21:34:09.0439Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"\"\"\n\nObservation\n\n1. The U-Net model successfully segmented the object from the background.\n\n2. Dice score increased with training while the loss decreased.\n\n3. IoU values show good overlap between predicted masks and ground truth masks.\n\n4. Predicted masks are visually similar to the original masks.\n\n\"\"\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T20:56:05.925656Z","iopub.status.idle":"2026-07-04T20:56:05.925977Z","shell.execute_reply.started":"2026-07-04T20:56:05.925848Z","shell.execute_reply":"2026-07-04T20:56:05.925869Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"\"\"\n\nConclusion\n\nThe U-Net model was successfully trained for semantic segmentation.\n\nThe model learned pixel-wise classification and produced accurate segmentation masks.\n\nDice Score and IoU were used to evaluate the segmentation performance.\n\nThe results show that U-Net is an effective deep learning architecture for image segmentation.\n\n\"\"\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-04T20:56:05.927287Z","iopub.status.idle":"2026-07-04T20:56:05.927599Z","shell.execute_reply.started":"2026-07-04T20:56:05.927439Z","shell.execute_reply":"2026-07-04T20:56:05.92746Z"}},"outputs":[],"execution_count":null}]}