{"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":"nvidiaTeslaT4","dataSources":[{"sourceId":6927,"databundleVersionId":45059,"sourceType":"competition"}],"dockerImageVersionId":30648,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"### UNet Model","metadata":{}},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torchvision.transforms.functional as TF\n\nclass DoubleConv(nn.Module):\n    def __init__(self, in_channels, out_channels):\n        super(DoubleConv, self).__init__()\n        self.conv = nn.Sequential(\n            nn.Conv2d(in_channels, out_channels, 3, 1, 1, bias = False),\n            nn.BatchNorm2d(out_channels),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(out_channels, out_channels, 3, 1, 1, bias = False),\n            nn.BatchNorm2d(out_channels),\n            nn.ReLU(inplace=True),\n        )\n\n    def forward(self, x):\n        return self.conv(x)\n\nclass UNET(nn.Module):\n    def __init__(self,in_channels=3,out_channels=1, features=[64, 128, 256, 512]):\n        super(UNET, self).__init__()\n        self.ups = nn.ModuleList()\n        self.downs = nn.ModuleList()\n        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)\n\n        #Down part of UNET\n        for feature in features:\n            self.downs.append(DoubleConv(in_channels, feature))\n            in_channels = feature\n\n        # Up part of UNET\n        for feature in reversed(features):\n            self.ups.append(\n                nn.ConvTranspose2d(\n                    feature*2, feature, kernel_size=2, stride=2\n                )\n            )\n            self.ups.append(DoubleConv(feature*2, feature))\n\n\n        self.bottleneck = DoubleConv(features[-1], features[-1]*2)\n        self.final_conv = nn.Conv2d(features[0], out_channels, kernel_size=1)\n\n    def forward(self, x):\n        skip_connections = []\n        for down in self.downs:\n            x = down(x)\n            skip_connections.append(x)\n            x = self.pool(x)\n\n        x = self.bottleneck(x)\n        skip_connections = skip_connections[::-1]\n\n        for idx in range(0, len(self.ups), 2):\n            x = self.ups[idx](x)\n            skip_connection = skip_connections[idx//2]\n\n            if x.shape != skip_connection.shape:\n                x = TF.resize(x, size=skip_connection.shape[2:])\n\n            concat_skip = torch.cat((skip_connection, x), dim=1)\n            x = self.ups[idx+1](concat_skip)\n\n        return self.final_conv(x)\n\ndef test():\n    x = torch.randn((3,1,160,160))\n    model = UNET(in_channels=1, out_channels=1)\n    preds = model(x)\n    print(preds.shape)\n    print(x.shape)\n    \ntest()","metadata":{"execution":{"iopub.status.busy":"2024-02-07T15:53:44.025586Z","iopub.execute_input":"2024-02-07T15:53:44.025949Z","iopub.status.idle":"2024-02-07T15:53:45.323716Z","shell.execute_reply.started":"2024-02-07T15:53:44.025919Z","shell.execute_reply":"2024-02-07T15:53:45.322599Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Unzipping Data","metadata":{}},{"cell_type":"code","source":"import os","metadata":{"execution":{"iopub.status.busy":"2024-02-07T15:53:45.325996Z","iopub.execute_input":"2024-02-07T15:53:45.326625Z","iopub.status.idle":"2024-02-07T15:53:45.331100Z","shell.execute_reply.started":"2024-02-07T15:53:45.326585Z","shell.execute_reply":"2024-02-07T15:53:45.330089Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.makedirs('/kaggle/working/TrainPhotos')\nos.makedirs('/kaggle/working/ValidPhotos')","metadata":{"execution":{"iopub.status.busy":"2024-02-07T15:53:45.332221Z","iopub.execute_input":"2024-02-07T15:53:45.332534Z","iopub.status.idle":"2024-02-07T15:53:45.342895Z","shell.execute_reply.started":"2024-02-07T15:53:45.332508Z","shell.execute_reply":"2024-02-07T15:53:45.342023Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### For Train Dataset","metadata":{}},{"cell_type":"code","source":"path_to_zip_file = \"/kaggle/input/carvana-image-masking-challenge/train.zip\"\ndirectory_to_extract_to = \"/kaggle/working/TrainPhotos\"\n\nimport zipfile\nwith zipfile.ZipFile(path_to_zip_file, 'r') as zip_ref:\n  zip_ref.extractall(directory_to_extract_to)","metadata":{"execution":{"iopub.status.busy":"2024-02-07T15:53:45.344791Z","iopub.execute_input":"2024-02-07T15:53:45.345033Z","iopub.status.idle":"2024-02-07T15:53:49.788194Z","shell.execute_reply.started":"2024-02-07T15:53:45.345012Z","shell.execute_reply":"2024-02-07T15:53:49.787434Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path_to_zip_file = \"/kaggle/input/carvana-image-masking-challenge/train_masks.zip\"\ndirectory_to_extract_to = \"/kaggle/working/TrainPhotos\"\n\nimport zipfile\nwith zipfile.ZipFile(path_to_zip_file, 'r') as zip_ref:\n  zip_ref.extractall(directory_to_extract_to)","metadata":{"execution":{"iopub.status.busy":"2024-02-07T15:53:49.789361Z","iopub.execute_input":"2024-02-07T15:53:49.789681Z","iopub.status.idle":"2024-02-07T15:53:50.423200Z","shell.execute_reply.started":"2024-02-07T15:53:49.789655Z","shell.execute_reply":"2024-02-07T15:53:50.422274Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### For Valid Dataset","metadata":{}},{"cell_type":"code","source":"os.makedirs('/kaggle/working/ValidPhotos/valid')\nos.makedirs('/kaggle/working/ValidPhotos/valid_masks')","metadata":{"execution":{"iopub.status.busy":"2024-02-07T15:53:50.424303Z","iopub.execute_input":"2024-02-07T15:53:50.424673Z","iopub.status.idle":"2024-02-07T15:53:50.429283Z","shell.execute_reply.started":"2024-02-07T15:53:50.424645Z","shell.execute_reply":"2024-02-07T15:53:50.428328Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Prepare Data for Training","metadata":{}},{"cell_type":"code","source":"from PIL import Image\nimport os\n\n# TrainPhotos ve TrainPhotos/train_masks klasörlerinin yolu\ntrain_photos_path = \"/kaggle/working/TrainPhotos/train\"\ntrain_masks_path = \"/kaggle/working/TrainPhotos/train_masks\"\n\n# ValidPhotos ve ValidPhotos/valid_masks klasörlerinin yolu\nvalid_photos_path = \"/kaggle/working/ValidPhotos/valid\"\nvalid_masks_path = \"/kaggle/working/ValidPhotos/valid_masks\"\n\n\n# TrainPhotos klasöründeki dosyaları listele\nphotos = os.listdir(train_photos_path)\n\n# Yüzde 20'sini seç\nvalid_count = int(len(photos) * 0.2)\nvalid_photos = photos[:valid_count]\n\n# Seçilen fotoğrafları ValidPhotos/valid ve ValidPhotos/valid_masks klasörlerine taşı ve .gif formatından .jpg formatına dönüştür\nfor photo in valid_photos:\n    # Resim dosyasını taşı ve .gif formatından .jpg formatına dönüştür\n    im = Image.open(os.path.join(train_photos_path, photo))\n    im = im.convert(\"RGB\")\n    jpg_path = os.path.join(valid_photos_path, os.path.splitext(photo)[0] + \".jpg\")\n    im.save(jpg_path)\n    \n    # Mask dosyasını bul\n    mask_name = os.path.splitext(photo)[0] + '_mask.gif'\n    mask_path = os.path.join(train_masks_path, mask_name)\n    \n    # Mask dosyasını taşı ve .gif formatından .jpg formatına dönüştür\n    mask_im = Image.open(mask_path)\n    mask_im = mask_im.convert(\"RGB\")\n    jpg_mask_path = os.path.join(valid_masks_path, os.path.splitext(mask_name)[0] + \".gif\")\n    mask_im.save(jpg_mask_path)","metadata":{"execution":{"iopub.status.busy":"2024-02-07T15:53:50.430578Z","iopub.execute_input":"2024-02-07T15:53:50.430848Z","iopub.status.idle":"2024-02-07T15:57:03.616717Z","shell.execute_reply.started":"2024-02-07T15:53:50.430815Z","shell.execute_reply":"2024-02-07T15:57:03.615580Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Dataset File","metadata":{}},{"cell_type":"code","source":"from torch.utils.data import Dataset\nimport numpy as np","metadata":{"execution":{"iopub.status.busy":"2024-02-07T15:57:03.617941Z","iopub.execute_input":"2024-02-07T15:57:03.618225Z","iopub.status.idle":"2024-02-07T15:57:03.622575Z","shell.execute_reply.started":"2024-02-07T15:57:03.618200Z","shell.execute_reply":"2024-02-07T15:57:03.621729Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CarvanaDataset(Dataset):\n    def __init__(self, image_dir, mask_dir, transform=None):\n        self.image_dir = image_dir\n        self.mask_dir = mask_dir\n        self.transform = transform\n        self.images = os.listdir(image_dir)\n\n    def __len__(self):\n        return len(self.images)\n\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, mask","metadata":{"execution":{"iopub.status.busy":"2024-02-07T15:57:03.623844Z","iopub.execute_input":"2024-02-07T15:57:03.624108Z","iopub.status.idle":"2024-02-07T15:57:03.634735Z","shell.execute_reply.started":"2024-02-07T15:57:03.624085Z","shell.execute_reply":"2024-02-07T15:57:03.633947Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Utils File","metadata":{}},{"cell_type":"code","source":"from torch.utils.data import DataLoader\nimport torchvision","metadata":{"execution":{"iopub.status.busy":"2024-02-07T18:09:49.432482Z","iopub.execute_input":"2024-02-07T18:09:49.433584Z","iopub.status.idle":"2024-02-07T18:09:49.438632Z","shell.execute_reply.started":"2024-02-07T18:09:49.433511Z","shell.execute_reply":"2024-02-07T18:09:49.437623Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.mkdir(\"resultPhotos\")","metadata":{"execution":{"iopub.status.busy":"2024-02-07T17:45:11.831006Z","iopub.execute_input":"2024-02-07T17:45:11.831372Z","iopub.status.idle":"2024-02-07T17:45:11.866691Z","shell.execute_reply.started":"2024-02-07T17:45:11.831338Z","shell.execute_reply":"2024-02-07T17:45:11.865188Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def save_checkpoint(state, filename=\"my_checkpoint.pth.tar\"):\n    print(\"=> Saving checkpoint\")\n    torch.save(state, filename)\n    \ndef load_checkpoint(chekcpoint, model):\n    print(\"=> Loading checkpoint\")\n    model.load_state_dict(checkpoint[\"state_dict\"])\n    \ndef get_loaders(\n    train_dir,\n    train_maskdir,\n    val_dir,\n    val_maskdir,\n    batch_size,\n    train_transform,\n    val_transform,\n    num_workers=4,\n    pin_memory=True,\n):\n    train_ds = CarvanaDataset(\n        image_dir = train_dir,\n        mask_dir = train_maskdir,\n        transform = train_transform,\n    )\n    \n    train_loader = DataLoader(\n        train_ds,\n        batch_size = batch_size,\n        num_workers=num_workers,\n        pin_memory=pin_memory,\n        shuffle=True\n    )\n    \n    \n    val_ds = CarvanaDataset(\n        image_dir = val_dir,\n        mask_dir = val_maskdir,\n        transform = val_transform\n    )\n    \n    val_loader = DataLoader(\n        val_ds,\n        batch_size = batch_size,\n        num_workers=num_workers,\n        pin_memory=pin_memory,\n        shuffle=False,\n    )\n    \n    return train_loader, val_loader\n\n\ndef check_accuracy(loader, model, device=\"cuda\"):\n    num_correct = 0\n    num_pixels = 0\n    dice_score = 0\n    model.eval()\n    \n    with torch.no_grad():\n        for x, y in loader:\n            x = x.to(device)\n            y = y.to(device).unsqueeze(1)\n            preds = torch.sigmoid(model(x))\n            preds = (preds > 0.5).float()\n            num_correct += (preds == y).sum()\n            num_pixels += torch.numel(preds)\n            dice_score += (2*(preds * y).sum()) / (\n                (preds + y).sum() + 1e-8\n            )\n            \n    print(\"Accuracy: \",num_correct/num_pixels)\n    print(\"Dice Score: \",dice_score/len(loader))\n    \n    model.train()\n    \ndef save_predictions_as_imgs(\n    loader, model, folder=\"resultPhotos/\", device=\"cuda\"\n):\n    model.eval()\n    for idx, (x, y) in enumerate(loader):\n        x = x.to(device=device)\n        with torch.no_grad():\n            preds = torch.sigmoid(model(x))\n            preds = (preds > 0.5).float()\n        torchvision.utils.save_image(\n            preds, f\"{folder}/pred_{idx}.png\"\n        )\n        torchvision.utils.save_image(y.unsqueeze(1), f\"{folder}\")","metadata":{"execution":{"iopub.status.busy":"2024-02-07T17:45:13.864335Z","iopub.execute_input":"2024-02-07T17:45:13.864717Z","iopub.status.idle":"2024-02-07T17:45:13.880015Z","shell.execute_reply.started":"2024-02-07T17:45:13.864689Z","shell.execute_reply":"2024-02-07T17:45:13.878816Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Train File","metadata":{}},{"cell_type":"code","source":"import torch\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\nfrom tqdm import tqdm\nimport torch.nn as nn\nimport torch.optim as optim\n\nLEARNING_RATE = 1e-4\nDEVICE = \"cuda\" if torch.cuda.is_available() else \"cpu\"\nBATCH_SIZE = 32\nNUM_EPOCHS = 10\nNUM_WORKERS = 2\nIMAGE_HEIGHT = 160\nIMAGE_WIDTH = 240\nPIN_MEMORY = True\nLOAD_MODEL = True\nTRAIN_IMG_DIR = \"/kaggle/working/TrainPhotos/train\"\nTRAIN_MASK_DIR = \"/kaggle/working/TrainPhotos/train_masks\"\nVAL_IMG_DIR = \"/kaggle/working/ValidPhotos/valid\"\nVAL_MASK_DIR = \"/kaggle/working/ValidPhotos/valid_masks\"","metadata":{"execution":{"iopub.status.busy":"2024-02-07T17:35:50.254470Z","iopub.execute_input":"2024-02-07T17:35:50.254894Z","iopub.status.idle":"2024-02-07T17:35:50.262561Z","shell.execute_reply.started":"2024-02-07T17:35:50.254856Z","shell.execute_reply":"2024-02-07T17:35:50.261453Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_fn(loader, model, optimizer, loss_fn, scaler):\n    loop = tqdm(loader)\n    \n    for batch_idx, (data, targets) in enumerate(loop):\n        data = data.to(device=DEVICE)\n        targets = targets.float().unsqueeze(1).to(device=DEVICE)\n        \n        # forward\n        with torch.cuda.amp.autocast():\n            predictions = model(data)\n            loss = loss_fn(predictions, targets)\n            \n        # bacward\n        optimizer.zero_grad()\n        scaler.scale(loss).backward()\n        scaler.step(optimizer)\n        scaler.update()\n        \n        # update tqdm loop\n        loop.set_postfix(loss=loss.item())\n\ndef main():\n    train_transform = A.Compose(\n    [\n        A.Resize(height=IMAGE_HEIGHT, width=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    ],\n    )\n    \n    val_transform = A.Compose(\n    [\n        A.Resize(height=IMAGE_HEIGHT, width=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    ],\n    )\n    \n    model = UNET(in_channels=3, out_channels=1).to(DEVICE)\n    loss_fn = nn.BCEWithLogitsLoss()\n    optimizer = optim.Adam(model.parameters(), lr = LEARNING_RATE)\n    \n    train_loader, val_loader = get_loaders(\n        TRAIN_IMG_DIR,\n        TRAIN_MASK_DIR,\n        VAL_IMG_DIR,\n        VAL_MASK_DIR,\n        BATCH_SIZE,\n        train_transform,\n        val_transform,\n        NUM_WORKERS,\n        PIN_MEMORY,\n    )\n    \n    \"\"\"if LOAD_MODEL:\n        load_checkpoint(torch.load(\"my_checkpoint.pth.tar\"), model)\"\"\"\n    \n    scaler = torch.cuda.amp.GradScaler()\n    for epoch in range(NUM_EPOCHS):\n        train_fn(train_loader, model, optimizer, loss_fn, scaler)\n        \n        # save model\n        checkpoint = {\n            \"state_dict\":model.state_dict(),\n            \"optimizer\":optimizer.state_dict(),\n        }\n        save_checkpoint(checkpoint)\n        \n        # check accuracy\n        check_accuracy(val_loader, model, device=DEVICE)\n        \n        # print some examples\n        \"\"\"save_predictions_as_imgs(\n            val_loader, model, folder=\"resultPhotos/\", device=DEVICE\n        )\"\"\"","metadata":{"execution":{"iopub.status.busy":"2024-02-07T18:35:11.283215Z","iopub.execute_input":"2024-02-07T18:35:11.283605Z","iopub.status.idle":"2024-02-07T18:35:11.297953Z","shell.execute_reply.started":"2024-02-07T18:35:11.283574Z","shell.execute_reply":"2024-02-07T18:35:11.296966Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"main()","metadata":{"execution":{"iopub.status.busy":"2024-02-07T18:35:12.839299Z","iopub.execute_input":"2024-02-07T18:35:12.839684Z","iopub.status.idle":"2024-02-07T18:37:15.147949Z","shell.execute_reply.started":"2024-02-07T18:35:12.839656Z","shell.execute_reply":"2024-02-07T18:37:15.146475Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}