{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"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\n\n!pip install --no-index --no-deps /kaggle/input/pycocotools-206/wheels/pycocotools-2.0.6-cp310-cp310-linux_x86_64.whl\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    print(dirname)\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-06-14T10:54:17.435179Z","iopub.execute_input":"2023-06-14T10:54:17.435528Z","iopub.status.idle":"2023-06-14T10:54:25.650986Z","shell.execute_reply.started":"2023-06-14T10:54:17.435498Z","shell.execute_reply":"2023-06-14T10:54:25.648654Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from glob import glob\nimport json\nfrom torch.utils.data import Dataset, DataLoader\n# from torchmetrics import AveragePrecision\nimport torch\nimport torch.nn as nn\nimport torchvision\nfrom PIL import Image\nfrom tqdm import tqdm as tqdm\nimport torch.nn.functional as F\nimport matplotlib.pyplot as plt\n# import segmentation_models_pytorch as smp\n# from segmentation_models_pytorch import utils as utils\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\nimport cv2\nimport random","metadata":{"execution":{"iopub.status.busy":"2023-06-14T10:54:25.658738Z","iopub.execute_input":"2023-06-14T10:54:25.662805Z","iopub.status.idle":"2023-06-14T10:54:31.335737Z","shell.execute_reply.started":"2023-06-14T10:54:25.662763Z","shell.execute_reply":"2023-06-14T10:54:31.334820Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 1) Class for extracting the pandas files and the function for training augmentation","metadata":{}},{"cell_type":"code","source":"class DataFrameConversion:\n    def get_pd_df(self, path):\n        return pd.read_csv(path)\n    \n    def get_json_df(self, path):\n        data = []\n        with open(path, 'r') as file:\n            for line in file:\n                item = json.loads(line)\n                data.append(item)\n        json_df = pd.DataFrame(data)\n        return json_df\n    \n########################################################################################################### \n\ndef training_augmentation():\n    train_transform = [\n        A.Resize(width = 512 , height = 512) , \n        A.Normalize(\n            mean = [0 , 0 , 0] , \n            std = [1 , 1 , 1] , \n            max_pixel_value = 255\n        ) , \n        ToTensorV2()\n    ]\n    return A.Compose(train_transform)\n\n###########################################################################################################\n\n# df_conv = DataFrameConversion()\n\n# tile_meta = df_conv.get_pd_df('/kaggle/input/hubmap-hacking-the-human-vasculature/tile_meta.csv')\n# wsi_meta = df_conv.get_pd_df('/kaggle/input/hubmap-hacking-the-human-vasculature/wsi_meta.csv')\n# polygons = df_conv.get_json_df('/kaggle/input/hubmap-hacking-the-human-vasculature/polygons.jsonl')          ","metadata":{"execution":{"iopub.status.busy":"2023-06-14T10:54:34.827405Z","iopub.execute_input":"2023-06-14T10:54:34.827792Z","iopub.status.idle":"2023-06-14T10:54:34.837379Z","shell.execute_reply.started":"2023-06-14T10:54:34.827761Z","shell.execute_reply":"2023-06-14T10:54:34.836374Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2) Classes for Training Dataset","metadata":{}},{"cell_type":"markdown","source":"**BLOOD VESSEL DATASET**","metadata":{}},{"cell_type":"code","source":"class VesselDataset(Dataset):\n    def __init__(self, image_dir, mask_dir, transforms=None):\n        \n        with open(mask_dir, 'r') as f:\n            self.json_labels = [json.loads(line) for line in f]\n        self.image_dir = image_dir\n        self.transforms = transforms\n        \n        \n    def __getitem__(self, idx):\n        # for idx in json_labels, we look at the annotations\n        # get the image from the corresponding id in the json file and convert to a tensor\n        image_path = os.path.join(self.image_dir, f\"{self.json_labels[idx]['id']}.tif\")\n        image = Image.open(image_path)\n        image = np.array(image)\n        \n        mask = np.zeros((512,512), dtype=np.float32)\n        \n        for annotation in self.json_labels[idx]['annotations']:\n            if annotation['type']=='blood_vessel':\n                coords = annotation['coordinates']\n\n                c, r = np.array([coord[1] for coord in coords[0]]), np.asarray([coord[0] for coord in coords[0]])\n\n                mask[c, r] = 1\n        \n        if self.transforms:\n            augmentations = self.transforms(image=image, mask=mask)\n            image = augmentations['image']\n            mask = augmentations['mask']\n        \n        else:\n            image = torch.tensor(image, dtype=torch.float32, requires_grad=True).permute(2,0,1)\n            mask = torch.tensor(mask, dtype=torch.long)\n        return image, mask\n        \n    def __len__(self):\n        return 25 #len(self.json_labels)","metadata":{"execution":{"iopub.status.busy":"2023-06-14T10:54:43.117984Z","iopub.execute_input":"2023-06-14T10:54:43.118334Z","iopub.status.idle":"2023-06-14T10:54:43.130654Z","shell.execute_reply.started":"2023-06-14T10:54:43.118305Z","shell.execute_reply":"2023-06-14T10:54:43.129709Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**GLOMERULUS DATASET**","metadata":{}},{"cell_type":"code","source":"class GlomerulusDataset(Dataset):\n    def __init__(self, image_dir, mask_dir, transforms=None):\n        \n        with open(mask_dir, 'r') as f:\n            self.json_labels = [json.loads(line) for line in f]\n        self.image_dir = image_dir\n        self.transforms = transforms\n        \n        \n    def __getitem__(self, idx):\n        # for idx in json_labels, we look at the annotations\n        # get the image from the corresponding id in the json file and convert to a tensor\n        image_path = os.path.join(self.image_dir, f\"{self.json_labels[idx]['id']}.tif\")\n        image = Image.open(image_path)\n        image = np.array(image)\n        \n        mask = np.zeros((512,512), dtype=np.float32)\n        \n        for annotation in self.json_labels[idx]['annotations']:\n            if annotation['type']=='glomerulus':\n                coords = annotation['coordinates']\n\n                c, r = np.array([coord[1] for coord in coords[0]]), np.asarray([coord[0] for coord in coords[0]])\n\n                mask[c, r] = 1\n        \n        if self.transforms:\n            augmentations = self.transforms(image=image, mask=mask)\n            image = augmentations['image']\n            mask = augmentations['mask']\n        \n        else:\n            image = torch.tensor(image, dtype=torch.float32, requires_grad=True).permute(2,0,1)\n            mask = torch.tensor(mask, dtype=torch.long)\n        return image, mask\n        \n    def __len__(self):\n        return 25 #len(self.json_labels)","metadata":{"execution":{"iopub.status.busy":"2023-06-14T10:54:43.836135Z","iopub.execute_input":"2023-06-14T10:54:43.836815Z","iopub.status.idle":"2023-06-14T10:54:43.847206Z","shell.execute_reply.started":"2023-06-14T10:54:43.836780Z","shell.execute_reply":"2023-06-14T10:54:43.846146Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**UNSURE DATASET**","metadata":{}},{"cell_type":"code","source":"class UnsureDataset(Dataset):\n    def __init__(self, image_dir, mask_dir, transforms=None):\n        \n        with open(mask_dir, 'r') as f:\n            self.json_labels = [json.loads(line) for line in f]\n        self.image_dir = image_dir\n        self.transforms = transforms\n        \n        \n    def __getitem__(self, idx):\n        # for idx in json_labels, we look at the annotations\n        # get the image from the corresponding id in the json file and convert to a tensor\n        image_path = os.path.join(self.image_dir, f\"{self.json_labels[idx]['id']}.tif\")\n        image = Image.open(image_path)\n        image = np.array(image)\n        \n        mask = np.zeros((512,512), dtype=np.float32)\n        \n        for annotation in self.json_labels[idx]['annotations']:\n            if annotation['type']=='unsure':\n                coords = annotation['coordinates']\n\n                c, r = np.array([coord[1] for coord in coords[0]]), np.asarray([coord[0] for coord in coords[0]])\n\n                mask[c, r] = 1\n        \n        if self.transforms:\n            augmentations = self.transforms(image=image, mask=mask)\n            image = augmentations['image']\n            mask = augmentations['mask']\n        \n        else:\n            image = torch.tensor(image, dtype=torch.float32, requires_grad=True).permute(2,0,1)\n            mask = torch.tensor(mask, dtype=torch.long)\n        return image, mask\n        \n    def __len__(self):\n        return 25 #len(self.json_labels)","metadata":{"execution":{"iopub.status.busy":"2023-06-14T10:54:44.636438Z","iopub.execute_input":"2023-06-14T10:54:44.637999Z","iopub.status.idle":"2023-06-14T10:54:44.651481Z","shell.execute_reply.started":"2023-06-14T10:54:44.637955Z","shell.execute_reply":"2023-06-14T10:54:44.650407Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 3) Defining the UNet Architecture","metadata":{}},{"cell_type":"code","source":"class DoubleConv(nn.Module):\n    def __init__(self, in_channels, out_channels):\n        super(DoubleConv, self).__init__()\n        self.conv = nn.Sequential(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    def forward(self, x):\n        return self.conv(x)","metadata":{"execution":{"iopub.status.busy":"2023-06-14T10:54:45.212662Z","iopub.execute_input":"2023-06-14T10:54:45.213543Z","iopub.status.idle":"2023-06-14T10:54:45.220343Z","shell.execute_reply.started":"2023-06-14T10:54:45.213511Z","shell.execute_reply":"2023-06-14T10:54:45.219254Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class UNet(nn.Module):\n    def __init__(self, in_channels=3, out_channels=1, features=[32,64,128,256]):\n        super(UNet, self).__init__()\n        self.downs = nn.ModuleList()\n        self.ups = nn.ModuleList()\n        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)\n        \n        for feature in features:\n            self.downs.append(DoubleConv(in_channels, out_channels=feature))\n            in_channels = feature\n            \n        for feature in reversed(features):\n            self.ups.append(nn.ConvTranspose2d(feature*2, feature, kernel_size=2, stride=2))\n            self.ups.append(DoubleConv(feature*2, feature))\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        \n        skip_connections = skip_connections[::-1]\n        \n        for idx in range(0, len(self.ups), 2):  # self.ups has two layers: transpose and doubleconv compared to downs\n            x = self.ups[idx](x)  # up-sampling - ConvTranspose2d\n            skip_connection = skip_connections[idx//2]  # We do index/2 since we are incrementing by 2 on ups(0,2,4-> 0,1,2..)\n            \n            if x.shape != skip_connection.shape:\n                x = TF.resize(x, size=skip_connection.shape[2:]) # skip batch_size and number of channels\n            \n            concat_skip = torch.cat((skip_connection, x), dim=1) # concatenate along the dimension 1\n            x = self.ups[idx+1](concat_skip)  # passing through the double conv\n            \n        x = self.final_conv(x)\n        return torch.sigmoid(x)","metadata":{"execution":{"iopub.status.busy":"2023-06-14T10:54:46.163820Z","iopub.execute_input":"2023-06-14T10:54:46.164201Z","iopub.status.idle":"2023-06-14T10:54:46.176552Z","shell.execute_reply.started":"2023-06-14T10:54:46.164160Z","shell.execute_reply":"2023-06-14T10:54:46.175651Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 4) Defining the Tversky Loss Function","metadata":{}},{"cell_type":"code","source":"class TverskyLoss(nn.Module):\n    def __init__(self, alpha=1, beta=1, gamma=1, smooth=1e-5):\n        super(TverskyLoss, self).__init__()\n        self.alpha = alpha\n        self.beta = beta\n        self.gamma = gamma\n        self.smooth = 1e-5\n    \n    def forward(self, y_pred, y_true):\n        y_pred = y_pred.contiguous().view(-1)\n        y_true = y_true.contiguous().view(-1)\n\n        true_positive = torch.sum(y_pred * y_true)\n        false_positive = torch.sum(y_pred) - true_positive\n        false_negative = torch.sum(y_true) - true_positive\n\n\n        tversky_index = (true_positive+self.smooth)/(\n            (true_positive)+\n            (self.alpha*false_positive)+\n            (self.beta*false_negative)+\n            (self.smooth))\n\n        return 1 - tversky_index","metadata":{"execution":{"iopub.status.busy":"2023-06-14T10:54:47.001043Z","iopub.execute_input":"2023-06-14T10:54:47.002031Z","iopub.status.idle":"2023-06-14T10:54:47.010312Z","shell.execute_reply.started":"2023-06-14T10:54:47.001988Z","shell.execute_reply":"2023-06-14T10:54:47.009289Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 5) Hyperparameters","metadata":{}},{"cell_type":"code","source":"# Hyperparameters\nLEARNING_RATE = 1e-2\nDEVICE = \"cuda\" if torch.cuda.is_available else \"cpu\"\nBATCH_SIZE=1\nNUM_EPOCHS= 20\nNUM_WORKERS= 2\nIMAGE_HEIGHT = 512\nIMAGE_WIDTH = 512\nSHUFFLE = True","metadata":{"execution":{"iopub.status.busy":"2023-06-14T10:59:56.209605Z","iopub.execute_input":"2023-06-14T10:59:56.210309Z","iopub.status.idle":"2023-06-14T10:59:56.215582Z","shell.execute_reply.started":"2023-06-14T10:59:56.210274Z","shell.execute_reply":"2023-06-14T10:59:56.214375Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 6) Function for training","metadata":{}},{"cell_type":"code","source":"def train_fn(loader, model, optimizer, scaler):\n    loop = tqdm(loader)\n    \n    loss_fn = TverskyLoss(alpha=0.3, beta=0.7, smooth=1e-6)\n    \n    for batch_index, (inp, targets) in enumerate(loop):\n        inp = inp.to(device=DEVICE)\n        targets = targets.to(device=DEVICE)\n        \n        # forward\n        \n        predictions = model(inp)\n        loss = loss_fn(predictions, targets)\n        \n        optimizer.zero_grad()\n        \n        loss.backward()\n        \n        optimizer.step()\n        \n        loop.set_postfix(loss=loss.item())\n        \n    return loss\n    pass","metadata":{"execution":{"iopub.status.busy":"2023-06-14T10:54:49.366245Z","iopub.execute_input":"2023-06-14T10:54:49.366783Z","iopub.status.idle":"2023-06-14T10:54:49.375326Z","shell.execute_reply.started":"2023-06-14T10:54:49.366754Z","shell.execute_reply":"2023-06-14T10:54:49.374246Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 7) Main Function","metadata":{}},{"cell_type":"code","source":"def main():\n    TRAIN = '/kaggle/input/hubmap-hacking-the-human-vasculature/train'\n    MASKS = '/kaggle/input/hubmap-hacking-the-human-vasculature/polygons.jsonl'\n    vessel_dataset = VesselDataset(TRAIN, MASKS, training_augmentation())\n    glomerulus_dataset = GlomerulusDataset(TRAIN, MASKS, training_augmentation())\n    unsure_dataset = UnsureDataset(TRAIN, MASKS, training_augmentation())\n\n\n    vessel_model = UNet(in_channels=3, out_channels=1).to(DEVICE)\n    glomerulus_model = UNet(in_channels=3, out_channels=1).to(DEVICE)\n    unsure_model = UNet(in_channels=3, out_channels=1).to(DEVICE)\n\n\n    vessel_optimizer = torch.optim.Adam(vessel_model.parameters(), lr=LEARNING_RATE)\n    glomerulus_optimizer = torch.optim.Adam(glomerulus_model.parameters(), lr=LEARNING_RATE)\n    unsure_optimizer = torch.optim.Adam(unsure_model.parameters(), lr=LEARNING_RATE)\n    \n    vessel_scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(vessel_optimizer,\n                                                                  mode='min',\n                                                                  patience=1, \n                                                                  verbose=True)\n    glomerulus_scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(glomerulus_optimizer,\n                                                                      mode='min',\n                                                                      patience=2,\n                                                                      verbose=True)\n    unsure_scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(unsure_optimizer,\n                                                                  mode='min',\n                                                                  patience=2, \n                                                                  verbose=True)\n\n\n\n    scaler = torch.cuda.amp.GradScaler()\n\n    for epoch in range(NUM_EPOCHS):\n        \n        print(f\"EPOCH:{epoch+1}/{NUM_EPOCHS}\")\n        \n        vessel_loader = DataLoader(vessel_dataset, batch_size=BATCH_SIZE, shuffle=SHUFFLE)\n        glomerulus_loader = DataLoader(glomerulus_dataset, batch_size=BATCH_SIZE, shuffle=SHUFFLE)\n        unsure_loader = DataLoader(unsure_dataset, batch_size=BATCH_SIZE, shuffle=SHUFFLE)\n\n        vessel_loss = train_fn(vessel_loader, \n                 vessel_model, \n                 vessel_optimizer, \n                 scaler)\n        \n        glom_loss = train_fn(glomerulus_loader, \n                 glomerulus_model, \n                 glomerulus_optimizer, \n                 scaler)\n\n        unsure_loss = train_fn(unsure_loader, \n                 unsure_model, \n                 unsure_optimizer, \n                 scaler)\n        \n        vessel_scheduler.step(vessel_loss)\n        glomerulus_scheduler.step(glom_loss)\n        unsure_scheduler.step(unsure_loss)\n    return vessel_model, glomerulus_model, unsure_model","metadata":{"execution":{"iopub.status.busy":"2023-06-14T11:00:34.499062Z","iopub.execute_input":"2023-06-14T11:00:34.500110Z","iopub.status.idle":"2023-06-14T11:00:34.515069Z","shell.execute_reply.started":"2023-06-14T11:00:34.500065Z","shell.execute_reply":"2023-06-14T11:00:34.513828Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Function for getting tensor mask","metadata":{}},{"cell_type":"code","source":"def get_mask_tensor(image, vessel_model, glom_model, unsure_model):\n\n    transform = training_augmentation()(image=image)['image']\n    image = transform.unsqueeze(0).to(DEVICE)\n\n    vessel_output = vessel_model(image)\n    glomerulus_output = glom_model(image)\n    unsure_output = unsure_model(image)\n\n    vessel_output     = vessel_output.detach().cpu()\n    glomerulus_output = glomerulus_output.detach().cpu()\n    unsure_output     = unsure_output.detach().cpu()\n\n    vessel_output[vessel_output>0.7]=1\n    vessel_output[vessel_output<0.7]=0\n\n    glomerulus_output[glomerulus_output>0.7]=1\n    glomerulus_output[glomerulus_output<0.7]=0\n\n    unsure_output[unsure_output>0.7]=1\n    unsure_output[unsure_output<0.7]=0\n\n    output = vessel_output + glomerulus_output + unsure_output\n    output = output.squeeze(0)\n    output = output.squeeze(0)\n    return output","metadata":{"execution":{"iopub.status.busy":"2023-06-14T10:56:23.036174Z","iopub.execute_input":"2023-06-14T10:56:23.036529Z","iopub.status.idle":"2023-06-14T10:56:23.044358Z","shell.execute_reply.started":"2023-06-14T10:56:23.036498Z","shell.execute_reply":"2023-06-14T10:56:23.043177Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 8) Function for Encoding masks","metadata":{}},{"cell_type":"code","source":"import base64\nfrom pycocotools import _mask as coco_mask\nimport typing as t\nimport zlib\n\n\ndef encode_binary_mask(mask: np.ndarray) -> t.Text:\n    \"\"\"Converts a binary mask into OID challenge encoding ascii text.\"\"\"\n    # check input mask --\n    if mask.dtype != bool:\n        raise ValueError(\n            \"encode_binary_mask expects a binary mask, received dtype == %s\" %\n            mask.dtype)\n\n    mask = np.squeeze(mask)\n    if len(mask.shape) != 2:\n        raise ValueError(\n        \"encode_binary_mask expects a 2d mask, received shape == %s\" %\n        mask.shape)\n\n    # convert input mask to expected COCO API input --\n    mask_to_encode = mask.reshape(mask.shape[0], mask.shape[1], 1)\n    mask_to_encode = mask_to_encode.astype(np.uint8)\n    mask_to_encode = np.asfortranarray(mask_to_encode)\n\n    # RLE encode mask --\n    encoded_mask = coco_mask.encode(mask_to_encode)[0][\"counts\"]\n\n    # compress and base64 encoding --\n    binary_str = zlib.compress(encoded_mask, zlib.Z_BEST_COMPRESSION)\n    base64_str = base64.b64encode(binary_str)\n    return base64_str","metadata":{"execution":{"iopub.status.busy":"2023-06-14T10:56:29.139648Z","iopub.execute_input":"2023-06-14T10:56:29.140343Z","iopub.status.idle":"2023-06-14T10:56:29.148062Z","shell.execute_reply.started":"2023-06-14T10:56:29.140310Z","shell.execute_reply":"2023-06-14T10:56:29.146961Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 9) Function for pred strings","metadata":{}},{"cell_type":"code","source":"def get_pred_string(objs):\n\n    string = \"\"\n    size = (objs.size(0), objs.size(1))\n    for i, item in enumerate(objs):\n        mask = np.zeros(size, bool)\n        mask[item>0] = 1\n        encoded_mask = encode_binary_mask(mask).decode(\"utf-8\")\n\n        if i == 0:\n            string += f\"0 1.0 {encoded_mask}\"\n        else:\n            string += f\" 0 1.0 {encoded_mask}\"\n        \n    return string","metadata":{"execution":{"iopub.status.busy":"2023-06-14T10:56:31.238420Z","iopub.execute_input":"2023-06-14T10:56:31.238816Z","iopub.status.idle":"2023-06-14T10:56:31.245597Z","shell.execute_reply.started":"2023-06-14T10:56:31.238783Z","shell.execute_reply":"2023-06-14T10:56:31.244674Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 10) Writing a submission file","metadata":{}},{"cell_type":"code","source":"vessel_model, glom_model, unsure_model = main()\n\ntest_path = \"/kaggle/input/hubmap-hacking-the-human-vasculature/test/\"\nsubmission = pd.DataFrame()\n\nids = []\nh = []\nw = []\npred_strings = []\n    \nfor img_id in os.listdir(test_path):\n    curr_img = cv2.imread(test_path + img_id)\n\n    ## Get id, height, width\n    height, width, channels = curr_img.shape\n    ids.append(img_id.split(\".\")[0])\n    h.append(height)\n    w.append(width)\n    \n    ## Get prediction_string\n    curr_mask = get_mask_tensor(curr_img, vessel_model, glom_model, unsure_model)\n    pred_strings.append(get_pred_string(curr_mask))\n\nsubmission[\"id\"] = ids\nsubmission[\"height\"] = h\nsubmission[\"width\"] = w\nsubmission[\"prediction_string\"] = pred_strings\nsubmission.set_index(\"id\", inplace=True)\nsubmission","metadata":{"execution":{"iopub.status.busy":"2023-06-14T11:00:38.530041Z","iopub.execute_input":"2023-06-14T11:00:38.530395Z","iopub.status.idle":"2023-06-14T11:03:09.582631Z","shell.execute_reply.started":"2023-06-14T11:00:38.530365Z","shell.execute_reply":"2023-06-14T11:03:09.581654Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission.to_csv('submission.csv')","metadata":{"execution":{"iopub.status.busy":"2023-06-14T11:03:21.561453Z","iopub.execute_input":"2023-06-14T11:03:21.561857Z","iopub.status.idle":"2023-06-14T11:03:21.574818Z","shell.execute_reply.started":"2023-06-14T11:03:21.561823Z","shell.execute_reply":"2023-06-14T11:03:21.573951Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Uncomment the bits below to test out the functions","metadata":{}},{"cell_type":"code","source":"# x, y = train_dataset[0]\n# print(x.unique())\n\n###############################################################################################\n\n# def test():\n#     x = torch.randn((5, 3, 512, 512))\n#     model = UNet(in_channels=3, out_channels=3)\n#     preds=model(x)\n#     print(preds.shape, x.shape)\n#     return preds, x\n# preds, truth = test()\n\n###############################################################################################\n\n# model = UNet(in_channels=3, out_channels=3)\n\n\n###############################################################################################\n\n# optimizer = torch.optim.Adam(model.parameters(), lr=LEARNING_RATE)\n# for batch_index, (inp, targets) in enumerate(loop):\n#     print(inp.size())\n#     print(targets.size())\n#     output = torch.softmax(model(inp), dim=1)\n#     print(output.size())\n#     loss = calc_tversky_loss(output, targets, num_classes=4)\n#     print(loss)\n#     break\n\n###############################################################################################\n\n# def save_checkpoint(state, filename='/kaggle/working/model.pth'):\n#     print(\"=> Saving Checkpoint\")\n#     torch.save(state, filename)\n    \n# def load_checkpoint(checkpoint, model):\n#     print(\"=> Loading Checkpoint\")\n#     model.load_state_dict(checkpoint['state_dict'])\n\n###############################################################################################\n\n# TEST_PATH = '/kaggle/input/hubmap-hacking-the-human-vasculature/test'\n# test = LoadTestDataset(TEST_PATH, training_augmentation())\n# test_loader = DataLoader(test, batch_size=1, shuffle=False)\n# for image_id, transforms in tqdm(test_loader):\n#     image = transforms\n#     output = model(image)\n\n# vessel = torch.argmax(output, 1)\n# plt.imshow(blvessel)\n# blood = vessel.squeeze(0).numpy()\n# blvessel = blood == 1\n# glom = blood == 2\n# blvessel = blvessel*1\n# glom = glom * 1","metadata":{"execution":{"iopub.status.busy":"2023-06-07T10:54:27.822863Z","iopub.execute_input":"2023-06-07T10:54:27.823279Z","iopub.status.idle":"2023-06-07T10:58:34.165957Z","shell.execute_reply.started":"2023-06-07T10:54:27.823248Z","shell.execute_reply":"2023-06-07T10:58:34.164699Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# class GetDataset(Dataset):\n#     def __init__(self, image_dir, mask_dir, transforms=None):\n        \n#         with open(mask_dir, 'r') as f:\n#             self.json_labels = [json.loads(line) for line in f]\n#         self.image_dir = image_dir\n#         self.transforms = transforms\n        \n        \n#     def __getitem__(self, idx):\n#         # for idx in json_labels, we look at the annotations\n#         # get the image from the corresponding id in the json file and convert to a tensor\n#         image_path = os.path.join(self.image_dir, f\"{self.json_labels[idx]['id']}.tif\")\n#         image = Image.open(image_path)\n#         image = np.array(image)\n        \n#         mask = np.zeros((512,512), dtype=np.float32)\n        \n#         for annotation in self.json_labels[idx]['annotations']:\n#             if annotation['type']=='blood_vessel':\n#                 coords = annotation['coordinates']\n\n#                 c, r = np.array([coord[1] for coord in coords[0]]), np.asarray([coord[0] for coord in coords[0]])\n\n#                 mask[c, r] = 1\n                \n#             if annotation['type']=='glomerulus':\n#                 coords = annotation['coordinates']\n\n#                 c, r = np.array([coord[1] for coord in coords[0]]), np.asarray([coord[0] for coord in coords[0]])\n\n#                 mask[c, r] = 2\n                \n#             if annotation['type']=='unsure':\n#                 coords = annotation['coordinates']\n\n#                 c, r = np.array([coord[1] for coord in coords[0]]), np.asarray([coord[0] for coord in coords[0]])\n\n#                 mask[c, r] = 3\n        \n#         if self.transforms:\n#             augmentations = self.transforms(image=image, mask=mask)\n#             image = augmentations['image']\n#             mask = augmentations['mask']\n        \n#         else:\n#             image = torch.tensor(image, dtype=torch.float32, requires_grad=True).permute(2,0,1)\n#             mask = torch.tensor(mask, dtype=torch.long)\n#         return image, mask\n        \n#     def __len__(self):\n#         return len(self.json_labels)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# from matplotlib import cm\n# from PIL import ImageEnhance\n\n# y = output.squeeze(0)\n# y = y.squeeze(0)\n# im = Image.fromarray(np.uint8(cm.gist_earth(y)*255))\n# enhancer = ImageEnhance.Contrast(im)\n# factor = 300\n# im_out = enhancer.enhance(factor)\n# # im_out.save('/kaggle/working/test_out.png')\n# im_out","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# TEST_PATH = '/kaggle/input/hubmap-hacking-the-human-vasculature/test'\n# filenames = os.listdir(TEST_PATH)\n# TEST_PATH = os.path.join(TEST_PATH, filename)\n# print(TEST_PATH)\n# image = np.array(Image.open(TEST_PATH))\n# transform = training_augmentation()(image=image)['image']\n\n# image = transform.unsqueeze(0).to(DEVICE)\n# print(image.size())\n# image = transform.to(DEVICE)","metadata":{},"execution_count":null,"outputs":[]}]}