{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":6927,"databundleVersionId":45059,"sourceType":"competition"}],"dockerImageVersionId":31011,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\ncnt = 0\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n        cnt += 1\nprint(cnt)\n        \n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-05-13T14:04:29.160637Z","iopub.execute_input":"2025-05-13T14:04:29.161188Z","iopub.status.idle":"2025-05-13T14:04:29.166313Z","shell.execute_reply.started":"2025-05-13T14:04:29.161167Z","shell.execute_reply":"2025-05-13T14:04:29.165633Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"x = Image.open('/kaggle/input/carvana-image-masking-challenge/29bb3ece3180_11.jpg')\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-13T14:13:23.544934Z","iopub.execute_input":"2025-05-13T14:13:23.545176Z","iopub.status.idle":"2025-05-13T14:13:23.548971Z","shell.execute_reply.started":"2025-05-13T14:13:23.545159Z","shell.execute_reply":"2025-05-13T14:13:23.548452Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"x","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-13T14:13:17.913560Z","iopub.execute_input":"2025-05-13T14:13:17.914237Z","iopub.status.idle":"2025-05-13T14:13:18.083169Z","shell.execute_reply.started":"2025-05-13T14:13:17.914213Z","shell.execute_reply":"2025-05-13T14:13:18.082218Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Unzipping the Dataset","metadata":{}},{"cell_type":"code","source":"import zipfile\nimport os\n\n# Destination path (working directory)\nextract_path = '/kaggle/working'\n\n# Extract the zip file\ndef unzip(dir_):\n    with zipfile.ZipFile(dir_, 'r') as zip_ref:\n        zip_ref.extractall(extract_path)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-13T14:20:17.070787Z","iopub.execute_input":"2025-05-13T14:20:17.071084Z","iopub.status.idle":"2025-05-13T14:20:17.075173Z","shell.execute_reply.started":"2025-05-13T14:20:17.071065Z","shell.execute_reply":"2025-05-13T14:20:17.074471Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"unzip('/kaggle/input/carvana-image-masking-challenge/train.zip')\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-13T14:20:32.669438Z","iopub.execute_input":"2025-05-13T14:20:32.670097Z","iopub.status.idle":"2025-05-13T14:20:39.691114Z","shell.execute_reply.started":"2025-05-13T14:20:32.670074Z","shell.execute_reply":"2025-05-13T14:20:39.690571Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Setting Paths and Transformations","metadata":{}},{"cell_type":"code","source":"from torchvision import transforms\n\n# Paths after unzip\nimg_dir = '/kaggle/working/train/train/'\nmask_dir = '/kaggle/working/train_masks/train_masks/'\n\n# Resize values\nIMAGE_HEIGHT = 128\nIMAGE_WIDTH = 128\n\n# Transformations\ntransform = transforms.Compose([\n    transforms.Resize((IMAGE_HEIGHT, IMAGE_WIDTH)),\n    transforms.ToTensor()\n])\n\ntarget_transform = transforms.Compose([\n    transforms.Resize((IMAGE_HEIGHT, IMAGE_WIDTH)),\n    transforms.ToTensor()\n])\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-20T08:24:04.630903Z","iopub.execute_input":"2025-04-20T08:24:04.6314Z","iopub.status.idle":"2025-04-20T08:24:12.144464Z","shell.execute_reply.started":"2025-04-20T08:24:04.631375Z","shell.execute_reply":"2025-04-20T08:24:12.14391Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Creating the Dataset Class","metadata":{}},{"cell_type":"markdown","source":"#### Importing Required libraries and modules","metadata":{}},{"cell_type":"code","source":"from torch.utils.data import Dataset\nfrom PIL import Image\nimport os\nfrom torch.utils.data import DataLoader","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-13T14:08:00.752452Z","iopub.execute_input":"2025-05-13T14:08:00.753070Z","iopub.status.idle":"2025-05-13T14:08:04.650946Z","shell.execute_reply.started":"2025-05-13T14:08:00.753050Z","shell.execute_reply":"2025-05-13T14:08:04.650427Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#### Defining the Class","metadata":{}},{"cell_type":"code","source":"class CarvanaDataset(Dataset):\n    def __init__(self, img_dir, mask_dir, transform=None, target_transform=None):\n        self.img_dir = img_dir\n        self.mask_dir = mask_dir\n        self.transform = transform\n        self.target_transform = target_transform\n\n        self.images = sorted([f for f in os.listdir(img_dir) if f.endswith('.jpg')])\n    \n    def __len__(self):\n        return len(self.images)\n    \n    def __getitem__(self, idx):\n        img_name = self.images[idx]\n        img_path = os.path.join(self.img_dir, img_name)\n        \n        mask_name = img_name.replace(\".jpg\", \"_mask.gif\")\n        mask_path = os.path.join(self.mask_dir, mask_name)\n\n        image = Image.open(img_path).convert(\"RGB\")\n        mask = Image.open(mask_path).convert(\"L\")\n\n        if self.transform:\n            image = self.transform(image)\n        if self.target_transform:\n            mask = self.target_transform(mask)\n\n        return image, mask\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-20T08:24:48.430748Z","iopub.execute_input":"2025-04-20T08:24:48.43107Z","iopub.status.idle":"2025-04-20T08:24:48.439107Z","shell.execute_reply.started":"2025-04-20T08:24:48.431029Z","shell.execute_reply":"2025-04-20T08:24:48.438274Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#### Creating the dataset and loader","metadata":{}},{"cell_type":"code","source":"transform = transforms.Compose([\n    transforms.Resize((256, 256)),\n    transforms.ToTensor()\n])\n\ntarget_transform = transforms.Compose([\n    transforms.Resize((256, 256)),\n    transforms.ToTensor()\n])\n\ndataset = CarvanaDataset(img_dir, mask_dir, transform=transform, target_transform=target_transform)\ntrain_loader = DataLoader(dataset, batch_size=8, shuffle=True)\n\n# Optional sanity check\nimg, msk = next(iter(train_loader))\nprint(\"Image batch shape:\", img.shape)\nprint(\"Mask batch shape:\", msk.shape)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-20T08:24:54.150134Z","iopub.execute_input":"2025-04-20T08:24:54.150822Z","iopub.status.idle":"2025-04-20T08:24:54.593443Z","shell.execute_reply.started":"2025-04-20T08:24:54.150796Z","shell.execute_reply":"2025-04-20T08:24:54.592598Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## U-Net Architecture","metadata":{}},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nclass UNet(nn.Module):\n    def __init__(self):\n        super(UNet, self).__init__()\n\n        def CBR(in_channels, out_channels):\n            return nn.Sequential(\n                nn.Conv2d(in_channels, out_channels, 3, padding=1),\n                nn.BatchNorm2d(out_channels),\n                nn.ReLU(inplace=True),\n                nn.Conv2d(out_channels, out_channels, 3, padding=1),\n                nn.BatchNorm2d(out_channels),\n                nn.ReLU(inplace=True)\n            )\n\n        self.enc1 = CBR(3, 64)\n        self.enc2 = CBR(64, 128)\n        self.enc3 = CBR(128, 256)\n        self.enc4 = CBR(256, 512)\n\n        self.pool = nn.MaxPool2d(2)\n\n        self.bottleneck = CBR(512, 1024)\n\n        self.upconv4 = nn.ConvTranspose2d(1024, 512, 2, stride=2)\n        self.dec4 = CBR(1024, 512)\n\n        self.upconv3 = nn.ConvTranspose2d(512, 256, 2, stride=2)\n        self.dec3 = CBR(512, 256)\n\n        self.upconv2 = nn.ConvTranspose2d(256, 128, 2, stride=2)\n        self.dec2 = CBR(256, 128)\n\n        self.upconv1 = nn.ConvTranspose2d(128, 64, 2, stride=2)\n        self.dec1 = CBR(128, 64)\n\n        self.out = nn.Conv2d(64, 1, 1)\n\n    def forward(self, x):\n        e1 = self.enc1(x)\n        e2 = self.enc2(self.pool(e1))\n        e3 = self.enc3(self.pool(e2))\n        e4 = self.enc4(self.pool(e3))\n\n        b = self.bottleneck(self.pool(e4))\n\n        d4 = self.upconv4(b)\n        d4 = self.dec4(torch.cat([d4, e4], dim=1))\n\n        d3 = self.upconv3(d4)\n        d3 = self.dec3(torch.cat([d3, e3], dim=1))\n\n        d2 = self.upconv2(d3)\n        d2 = self.dec2(torch.cat([d2, e2], dim=1))\n\n        d1 = self.upconv1(d2)\n        d1 = self.dec1(torch.cat([d1, e1], dim=1))\n\n        return torch.sigmoid(self.out(d1))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-20T08:24:59.155236Z","iopub.execute_input":"2025-04-20T08:24:59.155502Z","iopub.status.idle":"2025-04-20T08:24:59.16485Z","shell.execute_reply.started":"2025-04-20T08:24:59.155479Z","shell.execute_reply":"2025-04-20T08:24:59.164105Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Training the Model","metadata":{}},{"cell_type":"markdown","source":"#### Importing Optim and selecting device","metadata":{}},{"cell_type":"code","source":"import torch.optim as optim\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\nprint(device)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-20T08:25:03.826232Z","iopub.execute_input":"2025-04-20T08:25:03.826675Z","iopub.status.idle":"2025-04-20T08:25:03.90941Z","shell.execute_reply.started":"2025-04-20T08:25:03.826651Z","shell.execute_reply":"2025-04-20T08:25:03.908514Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#### Training Loop","metadata":{}},{"cell_type":"code","source":"model = UNet().to(device)\ncriterion = nn.BCELoss()\noptimizer = optim.Adam(model.parameters(), lr=1e-4)\n\nEPOCHS = 10\n\nfor epoch in range(EPOCHS):\n    model.train()\n    epoch_loss = 0\n    \n    for images, masks in train_loader:\n        images, masks = images.to(device), masks.to(device)\n        masks = masks.float()  # for BCELoss\n\n        outputs = model(images)\n        loss = criterion(outputs, masks)\n\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n\n        epoch_loss += loss.item()\n    \n    print(f\"Epoch {epoch+1}/{EPOCHS}, Loss: {epoch_loss:.4f}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-20T08:25:26.030516Z","iopub.execute_input":"2025-04-20T08:25:26.031138Z","iopub.status.idle":"2025-04-20T09:51:10.782408Z","shell.execute_reply.started":"2025-04-20T08:25:26.031115Z","shell.execute_reply":"2025-04-20T09:51:10.781761Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Visualizing the Predictions","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nmodel.eval()\nwith torch.no_grad():\n    sample_img, sample_mask = next(iter(train_loader))\n    sample_img = sample_img.to(device)\n    pred_mask = model(sample_img)\n    pred_mask = pred_mask.cpu()\n\nfor i in range(3):  # Showing & saving 3 examples\n    fig, ax = plt.subplots(1, 3, figsize=(10, 4))\n    ax[0].imshow(sample_img[i].permute(1, 2, 0).cpu())\n    ax[0].set_title(\"Input\")\n    ax[1].imshow(sample_mask[i][0], cmap='gray')\n    ax[1].set_title(\"True Mask\")\n    ax[2].imshow(pred_mask[i][0], cmap='gray')\n    ax[2].set_title(\"Predicted Mask\")\n    for a in ax:\n        a.axis('off')\n    \n    plt.tight_layout()\n    plt.savefig(f\"carvana_result_{i}.png\")  # Save image\n    plt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-20T09:53:45.587871Z","iopub.execute_input":"2025-04-20T09:53:45.588293Z","iopub.status.idle":"2025-04-20T09:53:47.314875Z","shell.execute_reply.started":"2025-04-20T09:53:45.588266Z","shell.execute_reply":"2025-04-20T09:53:47.31409Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"torch.save(model.state_dict(), \"carvana_segmentation_model.pth\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-20T09:56:06.262852Z","iopub.execute_input":"2025-04-20T09:56:06.263443Z","iopub.status.idle":"2025-04-20T09:56:06.468696Z","shell.execute_reply.started":"2025-04-20T09:56:06.263418Z","shell.execute_reply":"2025-04-20T09:56:06.468175Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}