{"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":"gpu","dataSources":[{"sourceId":61446,"databundleVersionId":6962461,"sourceType":"competition"},{"sourceId":7033964,"sourceType":"datasetVersion","datasetId":4046138},{"sourceId":7033977,"sourceType":"datasetVersion","datasetId":4046111}],"dockerImageVersionId":30588,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"#!pip module -d path\n","metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"execution":{"iopub.status.busy":"2023-11-25T15:51:54.965318Z","iopub.execute_input":"2023-11-25T15:51:54.966142Z","iopub.status.idle":"2023-11-25T15:51:54.970977Z","shell.execute_reply.started":"2023-11-25T15:51:54.966101Z","shell.execute_reply":"2023-11-25T15:51:54.969916Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<div style=\"background-color:#FFF199; color:#19180F; font-size:15px; font-family:Verdana; padding:10px; border: 2px solid #19180F; border-radius:10px\"> \n📌 Importing libraries\n    </div>","metadata":{}},{"cell_type":"code","source":"import os\nos.chdir('/kaggle/input/segmentation-models-pytorch-whl-file/whl_files/pretrainedmodels-0.7.4/pretrainedmodels-0.7.4')\n!python setup.py install\nimport pretrainedmodels","metadata":{"_kg_hide-output":true,"_kg_hide-input":true,"execution":{"iopub.status.busy":"2023-11-25T15:51:55.482941Z","iopub.execute_input":"2023-11-25T15:51:55.483680Z","iopub.status.idle":"2023-11-25T15:52:01.495535Z","shell.execute_reply.started":"2023-11-25T15:51:55.483649Z","shell.execute_reply":"2023-11-25T15:52:01.494456Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.chdir('/kaggle/input/segmentation-models-pytorch-whl-file/whl_files/efficientnet_pytorch-0.7.1/efficientnet_pytorch-0.7.1')\n!python setup.py install\nimport efficientnet_pytorch","metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"execution":{"iopub.status.busy":"2023-11-25T15:52:01.497660Z","iopub.execute_input":"2023-11-25T15:52:01.498202Z","iopub.status.idle":"2023-11-25T15:52:04.240527Z","shell.execute_reply.started":"2023-11-25T15:52:01.498154Z","shell.execute_reply":"2023-11-25T15:52:04.239298Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install --no-index --find-links /kaggle/input/segmentation-models-pytorch-whl-file/whl_files/ segmentation-models-pytorch --no-deps\n","metadata":{"_kg_hide-output":true,"_kg_hide-input":true,"execution":{"iopub.status.busy":"2023-11-25T15:52:04.241982Z","iopub.execute_input":"2023-11-25T15:52:04.242319Z","iopub.status.idle":"2023-11-25T15:52:06.234890Z","shell.execute_reply.started":"2023-11-25T15:52:04.242290Z","shell.execute_reply":"2023-11-25T15:52:06.233752Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport shutil\nimport numpy as np\nimport pandas as pd\nfrom PIL import Image\nfrom sklearn.model_selection import train_test_split\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import transforms\nimport segmentation_models_pytorch as smp\nfrom tqdm import tqdm\nimport time\nimport glob","metadata":{"execution":{"iopub.status.busy":"2023-11-25T15:52:06.237490Z","iopub.execute_input":"2023-11-25T15:52:06.237849Z","iopub.status.idle":"2023-11-25T15:52:07.974036Z","shell.execute_reply.started":"2023-11-25T15:52:06.237819Z","shell.execute_reply":"2023-11-25T15:52:07.973053Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<div style=\"background-color:#FFF199; color:#19180F; font-size:15px; font-family:Verdana; padding:10px; border: 2px solid #19180F; border-radius:10px\"> \n📌 Setting seed for reproducibility\n    </div>","metadata":{}},{"cell_type":"code","source":"seed = 42\ntorch.manual_seed(seed)\ntorch.backends.cudnn.deterministic = True\ntorch.backends.cudnn.benchmark = False\nnp.random.seed(seed)\n","metadata":{"execution":{"iopub.status.busy":"2023-11-25T15:52:07.975619Z","iopub.execute_input":"2023-11-25T15:52:07.976032Z","iopub.status.idle":"2023-11-25T15:52:07.983418Z","shell.execute_reply.started":"2023-11-25T15:52:07.975995Z","shell.execute_reply":"2023-11-25T15:52:07.982331Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<div style=\"background-color:#FFF199; color:#19180F; font-size:15px; font-family:Verdana; padding:10px; border: 2px solid #19180F; border-radius:10px\"> \n📌 Setting device\n    </div>","metadata":{}},{"cell_type":"code","source":"device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n","metadata":{"execution":{"iopub.status.busy":"2023-11-25T15:52:07.984700Z","iopub.execute_input":"2023-11-25T15:52:07.985028Z","iopub.status.idle":"2023-11-25T15:52:08.035514Z","shell.execute_reply.started":"2023-11-25T15:52:07.984998Z","shell.execute_reply":"2023-11-25T15:52:08.034528Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<div style=\"background-color:#FFF199; color:#19180F; font-size:15px; font-family:Verdana; padding:10px; border: 2px solid #19180F; border-radius:10px\"> \n📌 Defining vessel dataset class\n    </div>","metadata":{}},{"cell_type":"code","source":"class VesselDataset(Dataset):\n    def __init__(self, data_folder, mode='train',transform=None):\n        self.data_folder = data_folder\n        self.transform = transform\n        self.mode = mode\n        self.images_folder = os.path.join(data_folder, 'images')\n        if self.mode == \"train\":\n            self.labels_folder = os.path.join(data_folder, 'labels')\n        self.image_files = os.listdir(self.images_folder)\n\n    def __len__(self):\n        return len(self.image_files)\n\n    def __getitem__(self, idx):\n        img_name = os.path.join(self.images_folder, self.image_files[idx])\n        if self.mode == \"train\":\n            label_name = os.path.join(self.labels_folder, self.image_files[idx])\n        \n        image = Image.open(img_name).convert('L')  # Convert to grayscale\n        if self.mode == \"train\":\n            label = Image.open(label_name).convert('L')\n\n        if self.transform:\n            image = self.transform(image)\n            if self.mode == \"train\":\n                label = self.transform(label)\n        if self.mode == \"train\":\n            return image, label\n        else:\n            return image\n","metadata":{"execution":{"iopub.status.busy":"2023-11-25T15:52:08.036858Z","iopub.execute_input":"2023-11-25T15:52:08.037551Z","iopub.status.idle":"2023-11-25T15:52:08.049003Z","shell.execute_reply.started":"2023-11-25T15:52:08.037516Z","shell.execute_reply":"2023-11-25T15:52:08.048046Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<div style=\"background-color:#FFF199; color:#19180F; font-size:15px; font-family:Verdana; padding:10px; border: 2px solid #19180F; border-radius:10px\"> \n📌 Defining transforms and train-val datasets\n    </div>","metadata":{}},{"cell_type":"code","source":"transform = transforms.Compose([\n    transforms.Resize((256, 256)),  \n    transforms.ToTensor(),\n])\n\ntrain_dataset = VesselDataset('/kaggle/input/blood-vessel-segmentation/train/kidney_1_dense', transform=transform)\ntrain_dataset += VesselDataset('/kaggle/input/blood-vessel-segmentation/train/kidney_1_voi', transform=transform)\ntrain_dataset += VesselDataset('/kaggle/input/blood-vessel-segmentation/train/kidney_3_sparse', transform=transform)\nval_dataset = VesselDataset('/kaggle/input/blood-vessel-segmentation/train/kidney_2', transform=transform)\n","metadata":{"execution":{"iopub.status.busy":"2023-11-25T15:52:08.050093Z","iopub.execute_input":"2023-11-25T15:52:08.050340Z","iopub.status.idle":"2023-11-25T15:52:08.074290Z","shell.execute_reply.started":"2023-11-25T15:52:08.050318Z","shell.execute_reply":"2023-11-25T15:52:08.073434Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<div style=\"background-color:#FFF199; color:#19180F; font-size:15px; font-family:Verdana; padding:10px; border: 2px solid #19180F; border-radius:10px\"> \n📌 Moving cached resnet encoder to root path\n    </div>","metadata":{}},{"cell_type":"code","source":"cache_path = '/root/.cache/torch/hub/checkpoints/'\nsource_path = '/kaggle/input/unet-model/resnet34-333f7ec4.pth'\nif not os.path.exists(cache_path):\n    os.makedirs(cache_path)\nshutil.copy(source_path, cache_path)\n","metadata":{"execution":{"iopub.status.busy":"2023-11-25T15:52:08.075568Z","iopub.execute_input":"2023-11-25T15:52:08.076295Z","iopub.status.idle":"2023-11-25T15:52:08.311420Z","shell.execute_reply.started":"2023-11-25T15:52:08.076256Z","shell.execute_reply":"2023-11-25T15:52:08.310436Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<div style=\"background-color:#FFF199; color:#19180F; font-size:15px; font-family:Verdana; padding:10px; border: 2px solid #19180F; border-radius:10px\"> \n📌 Defining Unet model and creating dataloaders for train and val split\n    </div>","metadata":{}},{"cell_type":"code","source":"model = smp.Unet(\n    encoder_name=\"resnet34\",  \n    encoder_weights=\"imagenet\",\n    in_channels=1,\n    classes=1,\n)\ncheckpoint_path = '/kaggle/input/unet-model/unet_checkpoint.pth'\n\nmodel.load_state_dict(torch.load(checkpoint_path))\n\ncriterion = nn.BCEWithLogitsLoss()\noptimizer = optim.Adam(model.parameters(), lr=0.001)\n\ntrain_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)\nval_loader = DataLoader(val_dataset, batch_size=64, shuffle=False)\n","metadata":{"execution":{"iopub.status.busy":"2023-11-25T15:52:08.314519Z","iopub.execute_input":"2023-11-25T15:52:08.314846Z","iopub.status.idle":"2023-11-25T15:52:10.594528Z","shell.execute_reply.started":"2023-11-25T15:52:08.314820Z","shell.execute_reply":"2023-11-25T15:52:10.593669Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<div style=\"background-color:#FFF199; color:#19180F; font-size:15px; font-family:Verdana; padding:10px; border: 2px solid #19180F; border-radius:10px\"> \n📌 Moving the model to device and training for 5 epochs\n    </div>","metadata":{}},{"cell_type":"code","source":"model.to(device)\n\nnum_epochs = 10\nfor epoch in range(num_epochs):\n    model.train()\n    for step, (images, labels) in tqdm(enumerate(train_loader), desc=f\"Epoch {epoch + 1}/{num_epochs}\"):\n        images, labels = images.to(device), labels.to(device)\n\n        optimizer.zero_grad()\n        outputs = model(images)\n        loss = criterion(outputs, labels)\n        loss.backward()\n        if step%1000==0:\n            print(\"Step-{},Loss-{}\".format(step,loss.item()))\n            \n        optimizer.step()\n        \n\n    # Validation loop\n    model.eval()\n    val_loss = 0.0\n    with torch.no_grad():\n        for images, labels in tqdm(val_loader, desc=f\"Validation - Epoch {epoch + 1}/{num_epochs}\"):\n            images, labels = images.to(device), labels.to(device)\n\n            outputs = model(images)\n            val_loss += criterion(outputs, labels)\n            \n    val_loss /= len(val_loader)\n\n    print(f\"Epoch {epoch + 1}/{num_epochs}, Loss: {loss.item():.4f}, Validation Loss: {val_loss:.4f}\")\n\n#torch.save(model.state_dict(), checkpoint_path)","metadata":{"execution":{"iopub.status.busy":"2023-11-25T16:13:47.476533Z","iopub.execute_input":"2023-11-25T16:13:47.476889Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<div style=\"background-color:#FFF199; color:#19180F; font-size:15px; font-family:Verdana; padding:10px; border: 2px solid #19180F; border-radius:10px\"> \n📌 RLE encode and decode helper functions\n    </div>","metadata":{}},{"cell_type":"code","source":"# ref.: https://www.kaggle.com/stainsby/fast-tested-rle\ndef rle_encode(mask):\n    pixel = mask.flatten()\n    pixel = np.concatenate([[0], pixel, [0]])\n    run = np.where(pixel[1:] != pixel[:-1])[0] + 1\n    run[1::2] -= run[::2]\n    rle = ' '.join(str(r) for r in run)\n    if rle == '':\n        rle = '1 0'\n    return rle\n\n ","metadata":{"execution":{"iopub.status.busy":"2023-11-25T15:53:36.188735Z","iopub.execute_input":"2023-11-25T15:53:36.189099Z","iopub.status.idle":"2023-11-25T15:53:36.195638Z","shell.execute_reply.started":"2023-11-25T15:53:36.189069Z","shell.execute_reply":"2023-11-25T15:53:36.194564Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<div style=\"background-color:#FFF199; color:#19180F; font-size:15px; font-family:Verdana; padding:10px; border: 2px solid #19180F; border-radius:10px\"> \n📌 Fetching test data folders and the image ids along with creating test dataloaders\n    </div>","metadata":{}},{"cell_type":"code","source":"submission_df = pd.read_csv('/kaggle/input/blood-vessel-segmentation/sample_submission.csv')\ntest_data_folders = glob.glob('/kaggle/input/blood-vessel-segmentation/test/*')\nimage_ids = []\n\n\ntest_dataset = VesselDataset(test_data_folders[0], transform=transform, mode=\"test\")\n\nfor folder in test_data_folders[1:]:\n    test_dataset += VesselDataset(folder, transform=transform, mode=\"test\")\n\ntest_loader = DataLoader(test_dataset, batch_size=4, shuffle=False)\n\ndef get_image_index(filename):\n    return int(filename.split('.')[0])\n\nfor folder in test_data_folders:\n    image_files = os.listdir(os.path.join(folder, 'images'))\n    image_files.sort()\n\n    folder_name = os.path.basename(folder)\n\n    for i, image_file in enumerate(image_files):\n        image_index = get_image_index(image_file)\n        image_id = f\"{folder_name}_{image_index}\"\n        image_ids.append(image_id)\n\n","metadata":{"execution":{"iopub.status.busy":"2023-11-25T15:53:44.002574Z","iopub.execute_input":"2023-11-25T15:53:44.003235Z","iopub.status.idle":"2023-11-25T15:53:44.019659Z","shell.execute_reply.started":"2023-11-25T15:53:44.003199Z","shell.execute_reply":"2023-11-25T15:53:44.018438Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<div style=\"background-color:#FFF199; color:#19180F; font-size:15px; font-family:Verdana; padding:10px; border: 2px solid #19180F; border-radius:10px\"> \n📌 Generating submission by predicting on test set\n    </div>","metadata":{}},{"cell_type":"code","source":"submission_data = []\n\nwith torch.no_grad():\n    for i, (images) in tqdm(enumerate(test_loader), desc=\"Generating Submission\"):\n        images = images.to(device)\n        outputs = model(images)\n        predictions = torch.sigmoid(outputs)\n\n        for j in range(predictions.shape[0]):\n            rle_mask = rle_encode(predictions[j].cpu().numpy() > 0.5)\n            submission_data.append({'id': image_ids[i * 4 + j], 'rle': rle_mask})\n\nsubmission_df = pd.DataFrame(submission_data)\n\nsubmission_df['id'] = submission_df['id'].apply(lambda x: x.replace('test/', '').replace('/images/', '_').replace('.tif', ''))\nsubmission_df['id'] = submission_df['id'].apply(lambda x: x.rsplit('_', 1)[0] + '_' + x.rsplit('_', 1)[1].zfill(4))\n\nsubmission_df.to_csv('/kaggle/working/submission.csv', index=False)\nsubmission_df\n","metadata":{"execution":{"iopub.status.busy":"2023-11-25T15:53:45.104792Z","iopub.execute_input":"2023-11-25T15:53:45.105167Z","iopub.status.idle":"2023-11-25T15:53:45.212655Z","shell.execute_reply.started":"2023-11-25T15:53:45.105136Z","shell.execute_reply":"2023-11-25T15:53:45.211609Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}