{"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":"gpu","dataSources":[{"sourceId":52279,"databundleVersionId":5822112,"sourceType":"competition"},{"sourceId":5901549,"sourceType":"datasetVersion","datasetId":3389674},{"sourceId":8130104,"sourceType":"datasetVersion","datasetId":4804290}],"dockerImageVersionId":30683,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"### Lấy annotations từ json","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt","metadata":{"execution":{"iopub.status.busy":"2024-04-15T22:44:28.425499Z","iopub.execute_input":"2024-04-15T22:44:28.426113Z","iopub.status.idle":"2024-04-15T22:44:29.265739Z","shell.execute_reply.started":"2024-04-15T22:44:28.426080Z","shell.execute_reply":"2024-04-15T22:44:29.264939Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# df = pd.read_csv(\"/kaggle/input/hubmap-hacking-the-human-vasculature/tile_meta.csv\")\n# df = df[df[\"dataset\"] != 3] # chỉ lấy dataset 1 và 2\n# df.info()","metadata":{"execution":{"iopub.status.busy":"2024-04-15T22:44:29.267584Z","iopub.execute_input":"2024-04-15T22:44:29.267962Z","iopub.status.idle":"2024-04-15T22:44:29.271911Z","shell.execute_reply.started":"2024-04-15T22:44:29.267938Z","shell.execute_reply":"2024-04-15T22:44:29.270929Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# from sklearn.model_selection import train_test_split\n\n# df_train, df_valid = train_test_split(df, test_size=0.2, random_state=36)","metadata":{"execution":{"iopub.status.busy":"2024-04-15T22:44:29.272863Z","iopub.execute_input":"2024-04-15T22:44:29.273088Z","iopub.status.idle":"2024-04-15T22:44:29.281279Z","shell.execute_reply.started":"2024-04-15T22:44:29.273067Z","shell.execute_reply":"2024-04-15T22:44:29.280563Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Chuyển annotations sang định dạng COCO","metadata":{}},{"cell_type":"code","source":"# import json\n\n# jsonl_file_path = \"/kaggle/input/hubmap-hacking-the-human-vasculature/polygons.jsonl\"\n# data = []\n# with open(jsonl_file_path, \"r\") as file:\n#     for line in file:\n#         data.append(json.loads(line))","metadata":{"execution":{"iopub.status.busy":"2024-04-15T22:44:29.282250Z","iopub.execute_input":"2024-04-15T22:44:29.282492Z","iopub.status.idle":"2024-04-15T22:44:29.290889Z","shell.execute_reply.started":"2024-04-15T22:44:29.282470Z","shell.execute_reply":"2024-04-15T22:44:29.290137Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# from tqdm.notebook import tqdm\n\n# coco_data_template = {\"info\": {}, \"licenses\": [], \"categories\": [], \"images\": [], \"annotations\": []}\n\n# categories = []\n# for item in tqdm(data, dynamic_ncols=True):\n#     annotations = item[\"annotations\"]\n#     for annotation in annotations:\n#         annotation_type = annotation[\"type\"]\n#         if annotation_type not in categories:\n#             categories.append(annotation_type)\n#             coco_data_template[\"categories\"].append({\"id\": len(categories), \"name\": annotation_type})","metadata":{"execution":{"iopub.status.busy":"2024-04-15T22:44:29.293311Z","iopub.execute_input":"2024-04-15T22:44:29.293589Z","iopub.status.idle":"2024-04-15T22:44:29.299867Z","shell.execute_reply.started":"2024-04-15T22:44:29.293560Z","shell.execute_reply":"2024-04-15T22:44:29.299064Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# from copy import deepcopy\n\n# def polygon_to_segmentation(polygon):\n#     seg = [[]]\n#     for i in polygon:\n#         seg[0].append(i[0])\n#         seg[0].append(i[1])\n#     return seg\n\n# def to_coco_annotation(df, output_file_path):\n    \n#     coco_data = deepcopy(coco_data_template)\n    \n#     for image_id in tqdm(df[\"id\"], dynamic_ncols=True):\n\n#         image_info = {\"id\": image_id, \"file_name\": image_id + \".tif\", \"height\": 512, \"width\": 512}\n#         coco_data[\"images\"].append(image_info)\n\n#         masks = [i for i in data if i['id'] == image_id]\n#         if (len(masks) == 0):\n#             continue\n\n#         masks = masks[0]['annotations']\n#         masks = [i['coordinates'][0] for i in masks if i['type'] == 'blood_vessel']\n\n#         for mask in masks:\n\n#             ys, xs = np.array(mask)[:,1], np.array(mask)[:,0]\n\n#             x1, x2 = np.min(xs), np.max(xs)\n#             y1, y2 = np.min(ys), np.max(ys)\n\n#             category_id = 2 # blood_vessel\n\n#             segmentation = polygon_to_segmentation(mask)\n\n#             annotation_info = {\n#                 \"id\": len(coco_data[\"annotations\"]) + 1,\n#                 \"image_id\": image_id,\n#                 \"category_id\": category_id,\n#                 \"segmentation\": segmentation,\n#                 \"bbox\": [int(x1), int(y1), int(x2 - x1 + 1), int(y2 - y1 + 1)],\n#                 \"area\": int(np.sum(mask)),\n#                 \"iscrowd\": 0,\n#             }\n#             coco_data[\"annotations\"].append(annotation_info)\n\n#     with open(output_file_path, \"w\", encoding=\"utf-8\") as output_file:\n#         json.dump(coco_data, output_file, ensure_ascii=True, indent=4)","metadata":{"execution":{"iopub.status.busy":"2024-04-15T22:44:29.300848Z","iopub.execute_input":"2024-04-15T22:44:29.301166Z","iopub.status.idle":"2024-04-15T22:44:29.309635Z","shell.execute_reply.started":"2024-04-15T22:44:29.301145Z","shell.execute_reply":"2024-04-15T22:44:29.308787Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# to_coco_annotation(df_train, \"/kaggle/working/train_coco_annotations.json\")\n# to_coco_annotation(df_valid, \"/kaggle/working/valid_coco_annotations.json\")","metadata":{"execution":{"iopub.status.busy":"2024-04-15T22:44:29.310730Z","iopub.execute_input":"2024-04-15T22:44:29.311757Z","iopub.status.idle":"2024-04-15T22:44:29.321239Z","shell.execute_reply.started":"2024-04-15T22:44:29.311732Z","shell.execute_reply":"2024-04-15T22:44:29.320466Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Chuẩn bị dataset cho training","metadata":{}},{"cell_type":"code","source":"# %pip install pycocotools\n!pip install -q --no-deps /kaggle/input/pycocotools-206/wheels/*.whl","metadata":{"execution":{"iopub.status.busy":"2024-04-15T22:44:29.322308Z","iopub.execute_input":"2024-04-15T22:44:29.323012Z","iopub.status.idle":"2024-04-15T22:45:08.158177Z","shell.execute_reply.started":"2024-04-15T22:44:29.322982Z","shell.execute_reply":"2024-04-15T22:45:08.157070Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from pycocotools.coco import COCO\nfrom PIL import Image, ImageDraw","metadata":{"execution":{"iopub.status.busy":"2024-04-15T22:45:08.159585Z","iopub.execute_input":"2024-04-15T22:45:08.159920Z","iopub.status.idle":"2024-04-15T22:45:08.174241Z","shell.execute_reply.started":"2024-04-15T22:45:08.159891Z","shell.execute_reply":"2024-04-15T22:45:08.173405Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # https://christianjmills.com/posts/pytorch-train-mask-rcnn-tutorial/#training-dataset-class\n# def create_polygon_mask(image_size, vertices):\n#     \"\"\"\n#     Create a grayscale image with a white polygonal area on a black background.\n\n#     Parameters:\n#     - image_size (tuple): A tuple representing the dimensions (width, height) of the image.\n#     - vertices (list): A list of tuples, each containing the x, y coordinates of a vertex\n#                         of the polygon. Vertices should be in clockwise or counter-clockwise order.\n\n#     Returns:\n#     - PIL.Image.Image: A PIL Image object containing the polygonal mask.\n#     \"\"\"\n\n#     # Create a new black image with the given dimensions\n#     mask_img = Image.new('L', image_size, 0)\n    \n#     # Draw the polygon on the image. The area inside the polygon will be white (255).\n#     ImageDraw.Draw(mask_img, 'L').polygon(vertices, fill=(255))\n\n#     # Return the image with the drawn polygon\n#     return mask_img","metadata":{"execution":{"iopub.status.busy":"2024-04-15T22:45:08.175571Z","iopub.execute_input":"2024-04-15T22:45:08.176128Z","iopub.status.idle":"2024-04-15T22:45:08.382074Z","shell.execute_reply.started":"2024-04-15T22:45:08.176096Z","shell.execute_reply":"2024-04-15T22:45:08.381243Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch, torchvision\nimport torchvision.transforms.v2 as transforms\nimport cv2\nfrom torch.utils.data import Dataset\nfrom torchvision.tv_tensors import BoundingBoxes","metadata":{"execution":{"iopub.status.busy":"2024-04-15T22:45:08.383118Z","iopub.execute_input":"2024-04-15T22:45:08.383399Z","iopub.status.idle":"2024-04-15T22:45:14.384206Z","shell.execute_reply.started":"2024-04-15T22:45:08.383375Z","shell.execute_reply":"2024-04-15T22:45:14.383291Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# class COCOSegmentation(Dataset):\n#     def __init__(self, imgs_path, anno_path, transforms=None):\n#         super().__init__()\n#         self.imgs_path = imgs_path\n#         self.anno_path = anno_path\n#         self.transforms = transforms\n        \n#         self.coco_anno = COCO(anno_path)\n#         self.img_ids = self.coco_anno.getImgIds()\n    \n#     def __len__(self):\n#         return len(self.img_ids)\n\n#     def __getitem__(self, index):\n#         img_id = self.img_ids[index]\n#         annIds = self.coco_anno.getAnnIds(imgIds=[img_id])\n#         anns = self.coco_anno.loadAnns(annIds)\n        \n#         image = Image.open(self.imgs_path + '/' + img_id + '.tif').convert('RGB')\n        \n#         image_size = image.size\n        \n#         image = transforms.PILToTensor()(image)\n#         image = torch.as_tensor(image, dtype=torch.float32)\n        \n#         labels = torch.ones((len(anns),), dtype=torch.int64)\n       \n#         if len(anns):\n#             masks = [create_polygon_mask(image_size, ann['segmentation'][0]) for ann in anns]\n#             masks = [transforms.PILToTensor()(mask) / 255 for mask in masks]\n#             masks = torch.concat(masks)\n#         else:\n#             masks = torch.Tensor()\n        \n#         bboxes = torch.Tensor(BoundingBoxes(data=torchvision.ops.masks_to_boxes(masks), format='xyxy', canvas_size=image_size[::-1]))\n        \n#         target = {'masks': masks, 'boxes': bboxes, 'labels': labels}\n        \n#         if self.transforms:\n#             image, target = self.transforms(image, target)\n        \n#         return image, target","metadata":{"execution":{"iopub.status.busy":"2024-04-15T22:45:14.385411Z","iopub.execute_input":"2024-04-15T22:45:14.385854Z","iopub.status.idle":"2024-04-15T22:45:14.391176Z","shell.execute_reply.started":"2024-04-15T22:45:14.385827Z","shell.execute_reply":"2024-04-15T22:45:14.390346Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# train_dataset = COCOSegmentation(\n#     imgs_path = '/kaggle/input/hubmap-hacking-the-human-vasculature/train',\n#     anno_path = '/kaggle/working/train_coco_annotations.json',\n# )\n# valid_dataset = COCOSegmentation(\n#     imgs_path = '/kaggle/input/hubmap-hacking-the-human-vasculature/train',\n#     anno_path = '/kaggle/working/valid_coco_annotations.json',\n# )","metadata":{"execution":{"iopub.status.busy":"2024-04-15T22:45:14.392137Z","iopub.execute_input":"2024-04-15T22:45:14.392396Z","iopub.status.idle":"2024-04-15T22:45:14.403850Z","shell.execute_reply.started":"2024-04-15T22:45:14.392374Z","shell.execute_reply":"2024-04-15T22:45:14.403146Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Fine-tune model","metadata":{}},{"cell_type":"code","source":"from torchvision.models.detection.faster_rcnn import FastRCNNPredictor\nimport random","metadata":{"execution":{"iopub.status.busy":"2024-04-15T22:45:14.407507Z","iopub.execute_input":"2024-04-15T22:45:14.407887Z","iopub.status.idle":"2024-04-15T22:45:14.413407Z","shell.execute_reply.started":"2024-04-15T22:45:14.407858Z","shell.execute_reply":"2024-04-15T22:45:14.412493Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# def get_sample_data(dataset, batch_size):\n#     images = []\n#     targets = []\n#     while len(images) < batch_size:\n#         idx = random.randint(0, len(dataset) - 1)\n#         image, target = train_dataset[idx]\n#         if target['masks'].shape[0] == 0:\n#             continue\n#         images.append(image)\n#         targets.append(target)\n#     images = torch.stack([torch.as_tensor(image) for image in images], 0)\n#     return images, targets","metadata":{"execution":{"iopub.status.busy":"2024-04-15T22:45:14.414539Z","iopub.execute_input":"2024-04-15T22:45:14.414896Z","iopub.status.idle":"2024-04-15T22:45:14.425568Z","shell.execute_reply.started":"2024-04-15T22:45:14.414867Z","shell.execute_reply":"2024-04-15T22:45:14.424819Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"torch.cuda.empty_cache()\ndevice = torch.device('cuda')\nmodel = torchvision.models.detection.maskrcnn_resnet50_fpn_v2(pretrained=False)  # load an instance segmentation model pre-trained pre-trained on COCO\nin_features = model.roi_heads.box_predictor.cls_score.in_features  # get number of input features for the classifier\nmodel.roi_heads.box_predictor = FastRCNNPredictor(in_features,num_classes=2)  # replace the pre-trained head with a new one\nmodel.to(device)# move model to the right devic\noptimizer = torch.optim.AdamW(params=model.parameters(), lr=1e-5)","metadata":{"execution":{"iopub.status.busy":"2024-04-15T22:45:14.426475Z","iopub.execute_input":"2024-04-15T22:45:14.426765Z","iopub.status.idle":"2024-04-15T22:45:15.616958Z","shell.execute_reply.started":"2024-04-15T22:45:14.426743Z","shell.execute_reply":"2024-04-15T22:45:15.615830Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.load_state_dict(torch.load('/kaggle/input/maskrcnn-dataset/last_epoch_3.pth'))","metadata":{"execution":{"iopub.status.busy":"2024-04-15T22:45:15.618206Z","iopub.execute_input":"2024-04-15T22:45:15.618584Z","iopub.status.idle":"2024-04-15T22:45:17.308163Z","shell.execute_reply.started":"2024-04-15T22:45:15.618546Z","shell.execute_reply":"2024-04-15T22:45:17.307081Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import gc\n# import torch\n\n# # Assuming `obj` is the object consuming GPU memory\n# images = None\n# targets = None\n# losses = None\n\n# # Collect garbage\n# gc.collect()\n\n# # Empty PyTorch cache\n# torch.cuda.empty_cache()","metadata":{"execution":{"iopub.status.busy":"2024-04-15T22:45:17.309692Z","iopub.execute_input":"2024-04-15T22:45:17.310489Z","iopub.status.idle":"2024-04-15T22:45:17.315111Z","shell.execute_reply.started":"2024-04-15T22:45:17.310447Z","shell.execute_reply":"2024-04-15T22:45:17.314119Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import gc\n\n# model.train()\n\n# num_epochs = 2000\n\n# for epoch in tqdm(range(num_epochs)):\n    \n#     gc.collect()\n#     torch.cuda.empty_cache()\n    \n#     images, targets = get_sample_data(train_dataset, 8)\n    \n#     images = list(image.to(device) for image in images)\n#     targets = [{k: v.to(device) for k, v in t.items()} for t in targets]\n\n#     optimizer.zero_grad()\n#     loss_dict = model(images, targets)\n\n#     losses = sum(loss for loss in loss_dict.values())\n#     losses.backward()\n#     optimizer.step()\n    \n#     print(epoch, 'loss:', losses.item())","metadata":{"execution":{"iopub.status.busy":"2024-04-15T22:45:17.316395Z","iopub.execute_input":"2024-04-15T22:45:17.316711Z","iopub.status.idle":"2024-04-15T22:45:17.340621Z","shell.execute_reply.started":"2024-04-15T22:45:17.316683Z","shell.execute_reply":"2024-04-15T22:45:17.339761Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# torch.save(model.state_dict(), \"last_epoch.pth\")","metadata":{"execution":{"iopub.status.busy":"2024-04-15T22:45:17.342091Z","iopub.execute_input":"2024-04-15T22:45:17.342487Z","iopub.status.idle":"2024-04-15T22:45:17.350204Z","shell.execute_reply.started":"2024-04-15T22:45:17.342451Z","shell.execute_reply":"2024-04-15T22:45:17.349286Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Tính Score","metadata":{}},{"cell_type":"code","source":"# def computeIoUForMask(pred, ground_truth):\n#     intersect = pred & ground_truth\n        \n#     union = pred | ground_truth\n    \n#     return intersect.sum() / union.sum()","metadata":{"execution":{"iopub.status.busy":"2024-04-15T22:45:17.351402Z","iopub.execute_input":"2024-04-15T22:45:17.352113Z","iopub.status.idle":"2024-04-15T22:45:17.363382Z","shell.execute_reply.started":"2024-04-15T22:45:17.352076Z","shell.execute_reply":"2024-04-15T22:45:17.362471Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# torch.cuda.empty_cache()\n\n# from pathlib import Path\n\n# model.eval()\n\n# dataDir = \"/kaggle/input/hubmap-hacking-the-human-vasculature/train\"\n# annFile = Path(\"/kaggle/working/valid_coco_annotations.json\")\n\n# coco = COCO(annFile)\n# imgIds = coco.getImgIds()\n\n# masks = []\n\n# object_cnt = 0\n# for imgId in tqdm(imgIds):\n#     ground_truths = []\n    \n#     image = coco.loadImgs([imgId])\n#     annIds = coco.getAnnIds(imgIds=[imgId])\n#     anns = coco.loadAnns(annIds)\n    \n#     object_cnt += len(anns)\n    \n#     for ann in anns:\n#         gt_mask = coco.annToMask(ann)\n#         ground_truths.append(gt_mask)\n    \n#     image = Image.open(dataDir + '/' + imgId + '.tif').convert('RGB')\n#     image = transforms.PILToTensor()(image)\n#     image = torch.as_tensor(image, dtype=torch.float32).to(device)\n    \n#     with torch.no_grad():\n#         pred = model([image])[0]\n    \n#     pred_scores = pred['scores']\n#     pred_masks = pred['masks']\n#     pred_masks = pred_masks.cpu().detach().numpy()\n    \n#     for pred_score, pred_mask in zip(pred_scores, pred_masks):\n#         bestIoU = 0\n#         for ground_truth in ground_truths:\n#             IoU = computeIoUForMask(pred_mask > 0.8, ground_truth == 1)\n#             if IoU > bestIoU:\n#                 bestIoU = IoU\n#         pred_ann = 1 if bestIoU >= 0.75 else 0\n            \n#         mask = {\"score\" : pred_score, \"ann\" : pred_ann}\n#         masks.append(mask)\n        \n# masks.sort(key=lambda x : x['score'], reverse=True)","metadata":{"execution":{"iopub.status.busy":"2024-04-15T22:45:17.364769Z","iopub.execute_input":"2024-04-15T22:45:17.365182Z","iopub.status.idle":"2024-04-15T22:45:17.374246Z","shell.execute_reply.started":"2024-04-15T22:45:17.365146Z","shell.execute_reply":"2024-04-15T22:45:17.373198Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# precision = []\n# recall = []\n\n# tp = 0\n# fp = 0\n\n# for mask in masks:\n#     tp += mask['ann']\n#     fp += 1 - mask['ann']\n#     precision.append(tp / (tp + fp))\n#     recall.append(tp / object_cnt)\n    \n# torch.trapezoid(torch.tensor(precision), torch.tensor(recall))","metadata":{"execution":{"iopub.status.busy":"2024-04-15T22:45:17.375619Z","iopub.execute_input":"2024-04-15T22:45:17.376072Z","iopub.status.idle":"2024-04-15T22:45:17.384589Z","shell.execute_reply.started":"2024-04-15T22:45:17.376037Z","shell.execute_reply":"2024-04-15T22:45:17.383691Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Nộp bài","metadata":{}},{"cell_type":"code","source":"import glob\nfrom collections import defaultdict\nimport typing as t\nfrom skimage.morphology import binary_dilation\nfrom pycocotools import _mask as coco_mask\nimport zlib\nimport base64","metadata":{"execution":{"iopub.status.busy":"2024-04-15T22:45:17.385780Z","iopub.execute_input":"2024-04-15T22:45:17.386107Z","iopub.status.idle":"2024-04-15T22:45:18.069647Z","shell.execute_reply.started":"2024-04-15T22:45:17.386071Z","shell.execute_reply":"2024-04-15T22:45:18.068895Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def encode_binary_mask(mask: np.ndarray) -> t.Text:\n  \"\"\"Converts a binary mask into OID challenge encoding ascii text.\"\"\"\n\n  # check input mask --\n  if mask.dtype != np.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":"2024-04-15T22:45:18.070711Z","iopub.execute_input":"2024-04-15T22:45:18.071130Z","iopub.status.idle":"2024-04-15T22:45:18.078590Z","shell.execute_reply.started":"2024-04-15T22:45:18.071095Z","shell.execute_reply":"2024-04-15T22:45:18.077631Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.eval()\n\nall_imgs = glob.glob('/kaggle/input/hubmap-hacking-the-human-vasculature/test/*.tif')\ndict_df = defaultdict(list)\n\nfor img_path in all_imgs:\n    \n    pred_string = ''\n\n    image = Image.open(img_path).convert('RGB')\n    image = transforms.PILToTensor()(image)\n    image = torch.as_tensor(image, dtype=torch.float32).to(device)\n    \n    pred = model([image])[0]\n    \n    # extract blood vessel masks for multi class models\n    # indxs = (result.pred_instances.labels == class_id_blood_vessel)\n    pred_scores = pred['scores'].cpu().detach().numpy()\n    pred_masks = pred['masks'].cpu().detach().numpy()\n    # dilation\n    # https://www.kaggle.com/code/itsuki9180/hubmap-inference\n    # https://www.kaggle.com/competitions/hubmap-hacking-the-human-vasculature/discussion/416901\n    pred_masks = [binary_dilation(m) for m in pred_masks]\n    \n    # masks -> string\n    pred_strings = \" \".join([\n        f\"0 {score_tmp} {encode_binary_mask(mask_tmp).decode()}\"\n        for score_tmp, mask_tmp in zip(pred_scores, pred_masks)\n    ])\n\n    dict_df[\"id\"].append(img_path.split('/')[-1][:-4])\n    dict_df[\"height\"].append(512)\n    dict_df[\"width\"].append(512)\n    dict_df[\"prediction_string\"].append(pred_strings)\n\ndf_sub = pd.DataFrame(dict_df)\ndf_sub.to_csv(\"submission.csv\", index=False)\ndf_sub.head()","metadata":{"execution":{"iopub.status.busy":"2024-04-15T22:45:18.079700Z","iopub.execute_input":"2024-04-15T22:45:18.079974Z","iopub.status.idle":"2024-04-15T22:45:20.344595Z","shell.execute_reply.started":"2024-04-15T22:45:18.079950Z","shell.execute_reply":"2024-04-15T22:45:20.343076Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!cat submission.csv","metadata":{"execution":{"iopub.status.busy":"2024-04-15T22:45:20.346189Z","iopub.execute_input":"2024-04-15T22:45:20.346616Z","iopub.status.idle":"2024-04-15T22:45:21.374927Z","shell.execute_reply.started":"2024-04-15T22:45:20.346573Z","shell.execute_reply":"2024-04-15T22:45:21.373941Z"},"trusted":true},"execution_count":null,"outputs":[]}]}