{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","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"},{"sourceId":139610084,"sourceType":"kernelVersion"}],"dockerImageVersionId":30626,"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\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\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","execution":{"iopub.status.busy":"2023-12-22T19:52:25.824700Z","iopub.execute_input":"2023-12-22T19:52:25.825140Z","iopub.status.idle":"2023-12-22T19:52:30.608646Z","shell.execute_reply.started":"2023-12-22T19:52:25.825113Z","shell.execute_reply":"2023-12-22T19:52:30.607621Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport torchvision\nfrom torchvision import datasets,transforms\nfrom tqdm import tqdm\nimport cv2\nfrom torch.utils.data import Dataset,DataLoader\nimport torch.optim as optim\nfrom PIL import Image\nimport torchvision.transforms as transforms\nimport os\nimport torch.nn.functional as F","metadata":{"execution":{"iopub.status.busy":"2023-12-22T19:52:30.610618Z","iopub.execute_input":"2023-12-22T19:52:30.611070Z","iopub.status.idle":"2023-12-22T19:52:34.685655Z","shell.execute_reply.started":"2023-12-22T19:52:30.611040Z","shell.execute_reply":"2023-12-22T19:52:34.684829Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import zipfile\n# 'test.zip'\ndirs = ['train.zip','train_masks.zip']\nfor x in dirs:\n    with zipfile.ZipFile(\"../input/carvana-image-masking-challenge/\"+ x,'r') as z:\n        z.extractall(\".\")","metadata":{"execution":{"iopub.status.busy":"2023-12-22T19:52:34.687176Z","iopub.execute_input":"2023-12-22T19:52:34.687913Z","iopub.status.idle":"2023-12-22T19:52:44.273452Z","shell.execute_reply.started":"2023-12-22T19:52:34.687876Z","shell.execute_reply":"2023-12-22T19:52:44.272628Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls ","metadata":{"execution":{"iopub.status.busy":"2023-12-22T19:52:44.275903Z","iopub.execute_input":"2023-12-22T19:52:44.276838Z","iopub.status.idle":"2023-12-22T19:52:45.236831Z","shell.execute_reply.started":"2023-12-22T19:52:44.276792Z","shell.execute_reply":"2023-12-22T19:52:45.235671Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"LEARNING_RATE = 1e-4\nSPLIT=0.2\nDEVICE = \"cuda\" if torch.cuda.is_available() else \"cpu\"\nBATCH_SIZE = 4\nEPOCHS = 4\nNUM_WORKERS = 4\nIMAGE_HEIGHT = 572\nIMAGE_WIDTH = 572\nPIN_MEMORY = True\nDATAPATH = \"../input/carvana-image-masking-challenge/\"\nTRAIN_IMG_DIR = './train'\nTRAIN_MASK_DIR = './train_masks'","metadata":{"execution":{"iopub.status.busy":"2023-12-22T19:52:45.238545Z","iopub.execute_input":"2023-12-22T19:52:45.238989Z","iopub.status.idle":"2023-12-22T19:52:45.305598Z","shell.execute_reply.started":"2023-12-22T19:52:45.238947Z","shell.execute_reply":"2023-12-22T19:52:45.304666Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\n\n\ndef double_conv(in_c, out_c):\n    conv = nn.Sequential(\n        nn.Conv2d(in_c, out_c, kernel_size=3, stride=1, padding=1),\n        nn.BatchNorm2d(out_c),\n        nn.ReLU(inplace=True),\n        nn.Conv2d(out_c, out_c, kernel_size=3, stride=1, padding=1),\n        nn.BatchNorm2d(out_c),\n        nn.ReLU(inplace=True)\n    )\n    return conv.to(DEVICE)\n\ndef addPadding(srcShapeTensor, tensor_whose_shape_isTobechanged):\n\n    if(srcShapeTensor.shape != tensor_whose_shape_isTobechanged.shape):\n        target = torch.zeros(srcShapeTensor.shape)\n        target[:, :, :tensor_whose_shape_isTobechanged.shape[2],\n               :tensor_whose_shape_isTobechanged.shape[3]] = tensor_whose_shape_isTobechanged\n        return target.to(DEVICE)\n    return tensor_whose_shape_isTobechanged.to(DEVICE)\nclass UNet(nn.Module):\n    def __init__(self):\n        super(UNet, self).__init__()\n        self.max_pool_2x2 = nn.MaxPool2d(kernel_size=2, stride=2)\n        self.down_conv_1 = double_conv(3, 64)\n        self.down_conv_2 = double_conv(64, 128)\n        self.down_conv_3 = double_conv(128, 256)\n        self.down_conv_4 = double_conv(256, 512)\n        self.down_conv_5 = double_conv(512, 1024)\n\n        self.up_trans_1 = nn.ConvTranspose2d(\n            in_channels=1024,\n            out_channels=512,\n            kernel_size=2,\n            stride=2\n        )\n        self.up_conv_1 = double_conv(1024, 512)\n        self.up_trans_2 = nn.ConvTranspose2d(\n            in_channels=512,\n            out_channels=256,\n            kernel_size=2,\n            stride=2\n        )\n        self.up_conv_2 = double_conv(512, 256)\n\n        self.up_trans_3 = nn.ConvTranspose2d(\n            in_channels=256,\n            out_channels=128,\n            kernel_size=2,\n            stride=2\n        )\n        self.up_conv_3 = double_conv(256, 128)\n\n        self.up_trans_4 = nn.ConvTranspose2d(\n            in_channels=128,\n            out_channels=64,\n            kernel_size=2,\n            stride=2\n        )\n        self.up_conv_4 = double_conv(128, 64)\n\n        self.out = nn.Conv2d(\n            in_channels=64,\n            out_channels=1,\n            kernel_size=1\n        )\n    def forward(self, image):\n        # expected size\n        # encoder (Normal convolutions decrease the size)\n        x1 = self.down_conv_1(image)\n        # print(\"x1 \"+str(x1.shape))\n        x2 = self.max_pool_2x2(x1)\n        # print(\"x2 \"+str(x2.shape))\n        x3 = self.down_conv_2(x2)\n        # print(\"x3 \"+str(x3.shape))\n        x4 = self.max_pool_2x2(x3)\n        # print(\"x4 \"+str(x4.shape))\n        x5 = self.down_conv_3(x4)\n        # print(\"x5 \"+str(x5.shape))\n        x6 = self.max_pool_2x2(x5)\n        # print(\"x6 \"+str(x6.shape))\n        x7 = self.down_conv_4(x6)\n        # print(\"x7 \"+str(x7.shape))\n        x8 = self.max_pool_2x2(x7)\n        # print(\"x8 \"+str(x8.shape))\n        x9 = self.down_conv_5(x8)\n        # print(\"x9 \"+str(x9.shape))\n        x = self.up_trans_1(x9)\n        x = addPadding(x7, x)\n        x = self.up_conv_1(torch.cat([x7, x], 1))\n\n        x = self.up_trans_2(x)\n        x = addPadding(x5, x)\n        x = self.up_conv_2(torch.cat([x5, x], 1))\n\n        x = self.up_trans_3(x)\n        x = addPadding(x3, x)\n        x = self.up_conv_3(torch.cat([x3, x], 1))\n\n        x = self.up_trans_4(x)\n        x = addPadding(x1, x)\n        x = self.up_conv_4(torch.cat([x1, x], 1))\n\n        x = self.out(x)\n        # print(x.shape)\n        return x.to(DEVICE)","metadata":{"execution":{"iopub.status.busy":"2023-12-22T19:52:45.307117Z","iopub.execute_input":"2023-12-22T19:52:45.307526Z","iopub.status.idle":"2023-12-22T19:52:45.328427Z","shell.execute_reply.started":"2023-12-22T19:52:45.307494Z","shell.execute_reply":"2023-12-22T19:52:45.327624Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CarvanaDataset(Dataset):\n    def __init__(self,images,image_dir,mask_dir,transform=None,train=True):\n        self.image_dir = image_dir\n        self.mask_dir = mask_dir\n        self.transform = transform\n        self.isTrain = train\n        self.images = images\n    def __len__(self):\n        return len(self.images)\n    def __getitem__(self,index):\n        img_path = os.path.join(self.image_dir,self.images[index])\n        mask_path = os.path.join(self.mask_dir,self.images[index].replace(\".jpg\",\"_mask.gif\"))\n        image = np.array(Image.open(img_path).convert(\"RGB\"))\n        mask = np.array(Image.open(mask_path).convert(\"L\"),dtype=np.float32)\n        mask[mask == 255.0] = 1.0\n        \n        if self.transform is not None:\n            augmentations = self.transform(image=image,mask=mask)\n            image = augmentations['image']\n            mask = augmentations['mask']\n            \n        return {\"image\":image,\"mask\":mask}","metadata":{"execution":{"iopub.status.busy":"2023-12-22T19:52:45.329443Z","iopub.execute_input":"2023-12-22T19:52:45.329693Z","iopub.status.idle":"2023-12-22T19:52:45.345292Z","shell.execute_reply.started":"2023-12-22T19:52:45.329671Z","shell.execute_reply":"2023-12-22T19:52:45.344281Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images = os.listdir(TRAIN_IMG_DIR)\nmasks = os.listdir(TRAIN_MASK_DIR)","metadata":{"execution":{"iopub.status.busy":"2023-12-22T19:52:45.346480Z","iopub.execute_input":"2023-12-22T19:52:45.346784Z","iopub.status.idle":"2023-12-22T19:52:45.365074Z","shell.execute_reply.started":"2023-12-22T19:52:45.346758Z","shell.execute_reply":"2023-12-22T19:52:45.364170Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img = np.array(Image.open(TRAIN_IMG_DIR+\"/\"+images[0]).convert(\"RGB\"))\nplt.imshow(img,cmap=\"gray\")\nprint(img.shape)","metadata":{"execution":{"iopub.status.busy":"2023-12-22T19:52:45.366037Z","iopub.execute_input":"2023-12-22T19:52:45.366317Z","iopub.status.idle":"2023-12-22T19:52:46.198692Z","shell.execute_reply.started":"2023-12-22T19:52:45.366285Z","shell.execute_reply":"2023-12-22T19:52:46.197723Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"msk = np.array(Image.open(TRAIN_MASK_DIR+\"/\"+images[0].replace(\".jpg\",\"_mask.gif\")).convert(\"L\"))\nplt.imshow(msk,cmap=\"gray\")\nprint(msk.shape)","metadata":{"execution":{"iopub.status.busy":"2023-12-22T19:52:46.201732Z","iopub.execute_input":"2023-12-22T19:52:46.202028Z","iopub.status.idle":"2023-12-22T19:52:46.651039Z","shell.execute_reply.started":"2023-12-22T19:52:46.202002Z","shell.execute_reply":"2023-12-22T19:52:46.650119Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def fit(model,dataloader,data,optimizer,criterion):\n    print('-------------Training---------------')\n    model.train()\n    train_running_loss = 0.0\n    counter=0\n    \n    # num of batches\n    num_batches = int(len(data)/dataloader.batch_size)\n    for i,data in tqdm(enumerate(dataloader),total=num_batches):\n        counter+=1\n        image,mask = data[\"image\"].to(DEVICE),data[\"mask\"].to(DEVICE)\n        optimizer.zero_grad()\n        outputs = model(image)\n        outputs =outputs.squeeze(1)\n        loss = criterion(outputs,mask)\n        train_running_loss += loss.item()\n        loss.backward()\n        optimizer.step()\n    train_loss = train_running_loss/counter\n    return train_loss\ndef validate(model,dataloader,data,criterion):\n    print(\"\\n--------Validating---------\\n\")\n    model.eval()\n    valid_running_loss = 0.0\n    counter = 0\n    # number of batches\n    num_batches = int(len(data)/dataloader.batch_size)\n    with torch.no_grad():\n        for i,data in tqdm(enumerate(dataloader),total=num_batches):\n            counter+=1\n            image,mask = data[\"image\"].to(DEVICE),data[\"mask\"].to(DEVICE)\n            outputs = model(image)\n            outputs =outputs.squeeze(1)\n            loss = criterion(outputs,mask)\n            valid_running_loss += loss.item()\n    valid_loss = valid_running_loss/counter\n    return valid_loss\n        ","metadata":{"execution":{"iopub.status.busy":"2023-12-22T19:52:46.652359Z","iopub.execute_input":"2023-12-22T19:52:46.652732Z","iopub.status.idle":"2023-12-22T19:52:46.663703Z","shell.execute_reply.started":"2023-12-22T19:52:46.652698Z","shell.execute_reply":"2023-12-22T19:52:46.662691Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import albumentations as A\nfrom albumentations.pytorch import ToTensorV2 ","metadata":{"execution":{"iopub.status.busy":"2023-12-22T19:52:46.664881Z","iopub.execute_input":"2023-12-22T19:52:46.665175Z","iopub.status.idle":"2023-12-22T19:52:48.243191Z","shell.execute_reply.started":"2023-12-22T19:52:46.665149Z","shell.execute_reply":"2023-12-22T19:52:48.242211Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_transform = A.Compose([\n    A.Resize(IMAGE_HEIGHT,IMAGE_WIDTH),\n    A.Rotate(limit=35,p=1.0),\n    A.HorizontalFlip(p=0.5),\n    A.VerticalFlip(p=0.1),\n    A.Normalize(\n        mean=[0.0,0.0,0.0],\n        std = [1.0,1.0,1.0],\n        max_pixel_value=255.0\n    ),\n    ToTensorV2()  \n])\nvalidation_transform = A.Compose([\n    A.Resize(IMAGE_HEIGHT,IMAGE_WIDTH),\n    A.Normalize(\n        mean = [0.0,0.0,0.0],\n        std = [1.0,1.0,1.0],\n        max_pixel_value=255.0,\n    ),\n    ToTensorV2()\n])","metadata":{"execution":{"iopub.status.busy":"2023-12-22T19:52:48.244343Z","iopub.execute_input":"2023-12-22T19:52:48.244728Z","iopub.status.idle":"2023-12-22T19:52:48.251768Z","shell.execute_reply.started":"2023-12-22T19:52:48.244703Z","shell.execute_reply":"2023-12-22T19:52:48.250775Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_test_split(images,splitSize):\n    imageLen = len(images)\n    val_len = int(splitSize*imageLen)\n    train_len = imageLen - val_len\n    train_images,val_images = images[:train_len],images[train_len:]\n    return train_images,val_images","metadata":{"execution":{"iopub.status.busy":"2023-12-22T19:52:48.252876Z","iopub.execute_input":"2023-12-22T19:52:48.253156Z","iopub.status.idle":"2023-12-22T19:52:48.263091Z","shell.execute_reply.started":"2023-12-22T19:52:48.253133Z","shell.execute_reply":"2023-12-22T19:52:48.262237Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_images_path,val_images_path = train_test_split(images,SPLIT)\ntrain_data = CarvanaDataset(train_images_path,TRAIN_IMG_DIR,TRAIN_MASK_DIR,train_transform,True)\nvalid_data = CarvanaDataset(val_images_path,TRAIN_IMG_DIR,TRAIN_MASK_DIR,validation_transform,True)\ntrain_dataloader = DataLoader(train_data,batch_size=BATCH_SIZE,shuffle=True)\nvalid_dataloader = DataLoader(valid_data,batch_size=BATCH_SIZE,shuffle=False)","metadata":{"execution":{"iopub.status.busy":"2023-12-22T19:52:48.265844Z","iopub.execute_input":"2023-12-22T19:52:48.266126Z","iopub.status.idle":"2023-12-22T19:52:48.276855Z","shell.execute_reply.started":"2023-12-22T19:52:48.266103Z","shell.execute_reply":"2023-12-22T19:52:48.276052Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_loss = []\nval_loss =[]\nmodel = UNet().to(DEVICE)\noptimizer = optim.Adam(model.parameters(),lr=LEARNING_RATE)\ncriterion = nn.BCEWithLogitsLoss()\nfor epoch in range(EPOCHS):\n    print(f\"Epoch {epoch+1} of {EPOCHS}\")\n    train_epoch_loss = fit(model, train_dataloader, train_data,optimizer,criterion)\n    val_epoch_loss = validate(model, valid_dataloader, valid_data, criterion)\n    train_loss.append(train_epoch_loss)\n    val_loss.append(val_epoch_loss)\n    print(f\"Train Loss: {train_epoch_loss:.4f}\")\n    print(f'Val Loss: {val_epoch_loss:.4f}')\nplt.figure(figsize=(10, 7))\nplt.plot(train_loss, color=\"orange\", label='train loss')\nplt.plot(val_loss, color=\"red\", label='validation loss')\nplt.xlabel(\"Epochs\")\nplt.ylabel(\"Loss\")\nplt.legend()\n# plt.savefig(f\"../input/loss.png\")\nplt.show()\ntorch.save({\n    'epoch': EPOCHS,\n    'model_state_dict': model.state_dict(),\n    'optimizer_state_dict': optimizer.state_dict(),\n    'loss': criterion,\n}, \"./model.pth\")\n\nprint(\"\\n---------DONE TRAINING----------\\n\")\n    ","metadata":{"execution":{"iopub.status.busy":"2023-12-22T19:52:48.278076Z","iopub.execute_input":"2023-12-22T19:52:48.278649Z","iopub.status.idle":"2023-12-22T21:49:04.183886Z","shell.execute_reply.started":"2023-12-22T19:52:48.278615Z","shell.execute_reply":"2023-12-22T21:49:04.182881Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data = train_data.__getitem__(100)\nplt.imshow(data['mask'],cmap=\"gray\")\nprint(train_data.__getitem__(0)['mask'].shape)","metadata":{"execution":{"iopub.status.busy":"2023-12-22T21:50:07.736147Z","iopub.execute_input":"2023-12-22T21:50:07.736561Z","iopub.status.idle":"2023-12-22T21:50:08.096877Z","shell.execute_reply.started":"2023-12-22T21:50:07.736530Z","shell.execute_reply":"2023-12-22T21:50:08.095997Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(data['image'].shape)\nimg = data['image'].unsqueeze(0).to(device=\"cuda\")\n# model = UNet()\noutput = model(img)\noutput = torch.squeeze(output)\noutput[output>0.0] = 1.0\noutput[output<=0.0]=0\nprint(torch.max(output))\nprint(output.shape)\ndisp = output.detach().cpu()\nplt.imshow(disp,cmap=\"gray\")","metadata":{"execution":{"iopub.status.busy":"2023-12-22T21:50:24.597946Z","iopub.execute_input":"2023-12-22T21:50:24.598858Z","iopub.status.idle":"2023-12-22T21:50:25.078522Z","shell.execute_reply.started":"2023-12-22T21:50:24.598810Z","shell.execute_reply":"2023-12-22T21:50:25.077578Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"https://medium.com/mlearning-ai/semantic-segmentation-with-pytorch-u-net-from-scratch-502d6565910a","metadata":{}},{"cell_type":"markdown","source":"https://youtu.be/IHq1t7NxS8k?si=BUOB7ojCFWy5R3wX\nhttps://youtu.be/u1loyDCoGbE?si=D-f4X3JNmkN7fhLt\n","metadata":{}},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}