{"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":19989,"databundleVersionId":1160143,"sourceType":"competition"},{"sourceId":1219292,"sourceType":"datasetVersion","datasetId":648709},{"sourceId":4053053,"sourceType":"datasetVersion","datasetId":2398033},{"sourceId":8881406,"sourceType":"datasetVersion","datasetId":5321136,"isSourceIdPinned":true}],"dockerImageVersionId":30732,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!python -m pip install --no-index --find-links=/kaggle/input/omegaconf222py3 omegaconf","metadata":{"execution":{"iopub.status.busy":"2024-07-05T05:15:35.197336Z","iopub.execute_input":"2024-07-05T05:15:35.197736Z","iopub.status.idle":"2024-07-05T05:15:52.355394Z","shell.execute_reply.started":"2024-07-05T05:15:35.197703Z","shell.execute_reply":"2024-07-05T05:15:52.354091Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data loading","metadata":{}},{"cell_type":"code","source":"import os \nimport pandas as pd\nimport numpy as np","metadata":{"execution":{"iopub.status.busy":"2024-07-05T05:16:02.596498Z","iopub.execute_input":"2024-07-05T05:16:02.596934Z","iopub.status.idle":"2024-07-05T05:16:03.077263Z","shell.execute_reply.started":"2024-07-05T05:16:02.596895Z","shell.execute_reply":"2024-07-05T05:16:03.076072Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"root = '/kaggle/input/global-wheat-detection'\nclasses = ['background', 'wheat']\nclass_to_idx_dict = dict(zip(classes, range(len(classes))))","metadata":{"execution":{"iopub.status.busy":"2024-07-05T05:16:03.259308Z","iopub.execute_input":"2024-07-05T05:16:03.259828Z","iopub.status.idle":"2024-07-05T05:16:03.265598Z","shell.execute_reply.started":"2024-07-05T05:16:03.259794Z","shell.execute_reply":"2024-07-05T05:16:03.264294Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df = pd.read_csv('/kaggle/input/global-wheat-detection/sample_submission.csv')\ndisplay(submission_df)","metadata":{"execution":{"iopub.status.busy":"2024-07-05T05:16:03.806466Z","iopub.execute_input":"2024-07-05T05:16:03.806901Z","iopub.status.idle":"2024-07-05T05:16:03.848722Z","shell.execute_reply.started":"2024-07-05T05:16:03.806850Z","shell.execute_reply":"2024-07-05T05:16:03.847596Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_image_df = submission_df.copy(deep=True)\ntest_image_df['image_path'] = root + \"/test/\" + test_image_df['image_id'] + \".jpg\"\ndisplay(test_image_df)","metadata":{"execution":{"iopub.status.busy":"2024-07-05T05:16:04.694259Z","iopub.execute_input":"2024-07-05T05:16:04.694663Z","iopub.status.idle":"2024-07-05T05:16:04.710381Z","shell.execute_reply.started":"2024-07-05T05:16:04.694632Z","shell.execute_reply":"2024-07-05T05:16:04.709021Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_image_df.to_csv('/kaggle/working/test_image.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2024-07-05T05:16:05.235020Z","iopub.execute_input":"2024-07-05T05:16:05.235425Z","iopub.status.idle":"2024-07-05T05:16:05.245967Z","shell.execute_reply.started":"2024-07-05T05:16:05.235391Z","shell.execute_reply":"2024-07-05T05:16:05.244649Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Libraries","metadata":{}},{"cell_type":"code","source":"# Standard libraries\nimport sys\nsys.path.insert(0, \"../input/weightedboxesfusion\")\nimport math\nimport os\nimport random\nimport time\nimport urllib.request\nfrom functools import partial\nfrom urllib.error import HTTPError\nfrom types import SimpleNamespace\nimport collections\nfrom omegaconf import DictConfig, OmegaConf\nfrom typing import Any, Dict, List, Union\nimport importlib\n\n# Plotting\nimport matplotlib\nimport matplotlib.pyplot as plt\nimport matplotlib_inline.backend_inline\nimport seaborn as sns\n\nfrom mpl_toolkits.axes_grid1 import ImageGrid\nfrom PIL import Image\n\n# Libraries for ML\nimport numpy as np\nimport pandas as pd\nimport sklearn\nfrom sklearn.model_selection import KFold, GroupKFold, train_test_split\n\n# PyTorch\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.optim as optim\nimport torch.utils.data as data\nfrom torch.utils.data import random_split, Dataset, DataLoader, Subset\nfrom torchvision.transforms import v2\nimport torchmetrics\n\n# Torchvision\nimport torchvision\nfrom torchvision import transforms\nfrom tqdm.notebook import tqdm\nimport timm\n\nimport cv2\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\nfrom ensemble_boxes import *","metadata":{"execution":{"iopub.status.busy":"2024-07-05T05:16:06.266408Z","iopub.execute_input":"2024-07-05T05:16:06.266796Z","iopub.status.idle":"2024-07-05T05:16:17.931877Z","shell.execute_reply.started":"2024-07-05T05:16:06.266765Z","shell.execute_reply":"2024-07-05T05:16:17.930758Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Configuration","metadata":{}},{"cell_type":"code","source":"checkpoint_path = '/kaggle/input/wheat-fasterrcnn/fasterrcnn_resnet50_fpn.pth'\n","metadata":{"execution":{"iopub.status.busy":"2024-07-05T05:16:20.987707Z","iopub.execute_input":"2024-07-05T05:16:20.988563Z","iopub.status.idle":"2024-07-05T05:16:20.998431Z","shell.execute_reply.started":"2024-07-05T05:16:20.988501Z","shell.execute_reply":"2024-07-05T05:16:20.996640Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dict_cfg = {'general': {'workspace': 'kaggle', 'project_name': 'wheat'},\n       'training': {'lr': 0.002, 'metric': 'val_map', 'first_run': True,\n                    'seed': 42, 'debug': False, 'mode': 'max', 'save_dir': '/kaggle/working',\n                    'save_name': '${general.project_name}', 'pretrained': False, 'pretrained_fname': ''},\n       'optimizer': {'class_name': 'torch.optim.AdamW', 'params': {'lr': '${training.lr}'}},\n       'scheduler': {'class_name': 'torch.optim.lr_scheduler.ReduceLROnPlateau', 'step': 'epoch', 'monitor': '${training.metric}',\n                     'params': {'mode': '${training.mode}', 'factor': 0.8, 'patience': 1}},\n       'model': {\n           'train':{\n                   'backbone': {'class_name': 'torchvision.models.detection.fasterrcnn_resnet50_fpn_v2','params': {'weights': 'COCO_V1'}},\n           'head': {'class_name': 'torchvision.models.detection.faster_rcnn.FastRCNNPredictor', 'params': {'num_classes': 2}}\n           },\n           'test':{\n               'backbone': {'class_name': 'torchvision.models.detection.fasterrcnn_resnet50_fpn_v2','params': {'weights_backbone': None}},\n           'head': {'class_name': 'torchvision.models.detection.faster_rcnn.FastRCNNPredictor', 'params': {'num_classes': 2}}\n           }\n           \n       },\n       'data': {\n           'full_image_path': '/kaggle/working/full_image.csv',\n           'full_target_path': '/kaggle/working/full_target.csv',\n           'test_image_path': '/kaggle/working/test_image.csv',\n           'num_workers': 4, 'batch_size': 4, \n           'img_h': 512, 'img_w': 512\n       },\n       'augmentation': {\n           'train': {\n               'class_name': 'albumentations.Compose',\n               'params':{\n                   'transforms': [\n#                        {'class_name': 'albumentations.RandomSizedCrop', 'params': {'min_max_height': [800, 800], 'height': 1024, 'width': 1024, 'p': 0.5}},\n                       {'class_name': 'albumentations.OneOf', 'params': {\n                           'transforms': [\n                               {'class_name': 'albumentations.HueSaturationValue', 'params': {'hue_shift_limit': 0.2, 'sat_shift_limit': 0.2, 'val_shift_limit': 0.2, 'p': 0.9}},\n                               {'class_name': 'albumentations.RandomBrightnessContrast', 'params': {'brightness_limit': 0.2, 'contrast_limit': 0.2, 'p': 0.9}}\n                            ],'p': 0.9}\n                       },\n                       {'class_name': 'albumentations.ToGray', 'params': {'p': 0.1}},\n                       {'class_name': 'albumentations.HorizontalFlip', 'params': {'p': 0.5}},\n                       {'class_name': 'albumentations.VerticalFlip', 'params': {'p': 0.5}},\n                       {'class_name': 'albumentations.Resize', 'params': {'height': '${data.img_h}', 'width': '${data.img_w}', 'p': 1.0}},\n                       {'class_name': 'albumentations.pytorch.transforms.ToTensorV2', 'params': {'p': 1.0}}\n                   ],\n                   'bbox_params': {'format': 'pascal_voc', 'min_area': 0, 'min_visibility': 0, 'label_fields': ['labels']}},\n            },\n            'valid': {\n               'class_name': 'albumentations.Compose',\n               'params':{\n                   'transforms': [\n                       {'class_name': 'albumentations.Resize', 'params': {'height': '${data.img_h}', 'width': '${data.img_w}', 'p': 1.0}},\n                       {'class_name': 'albumentations.pytorch.transforms.ToTensorV2', 'params': {'p': 1.0}}\n                   ],\n                   'bbox_params': {'format': 'pascal_voc', 'min_area': 0, 'min_visibility': 0, 'label_fields': ['labels']}},\n            },\n           'test': {\n               'class_name': 'albumentations.Compose',\n               'params':{\n                   'transforms': [\n                       {'class_name': 'albumentations.Resize', 'params': {'height': '${data.img_h}', 'width': '${data.img_w}', 'p': 1.0}},\n                       {'class_name': 'albumentations.pytorch.transforms.ToTensorV2', 'params': {'p': 1.0}}\n                   ]},\n            },\n       },\n      'metrics':[\n          {'class_name': 'torchmetrics.detection.mean_ap.MeanAveragePrecision', 'params': {'iou_thresholds': torch.linspace(0.5, 0.75, round((0.75 - 0.5) / 0.05) + 1).tolist(), 'average': 'macro'}}\n      ]}","metadata":{"execution":{"iopub.status.busy":"2024-07-05T05:16:21.438351Z","iopub.execute_input":"2024-07-05T05:16:21.438794Z","iopub.status.idle":"2024-07-05T05:16:21.474456Z","shell.execute_reply.started":"2024-07-05T05:16:21.438731Z","shell.execute_reply":"2024-07-05T05:16:21.473051Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dict_cfg['trainer'] = {'accelerator': 'auto', 'devices': 1, 'max_epochs': 15, 'log_every_n_steps': 50, 'precision': '16-mixed'}\n\ndict_cfg['loggers'] = [\n    {'class_name': 'lightning.pytorch.loggers.CSVLogger', \n     'params': {'save_dir': os.path.join('${training.save_dir}', '${training.save_name}'), 'name': 'logs', 'version': 'version_0'}},\n    {'class_name': 'lightning.pytorch.loggers.TensorBoardLogger',\n     'params': {'save_dir': os.path.join('${training.save_dir}', '${training.save_name}'), 'name': 'logs', 'version': 'version_0'}}\n]\n\ndict_cfg['callbacks'] = [{'class_name': 'lightning.pytorch.callbacks.ModelCheckpoint',\n                    'params': {'mode': '${training.mode}', 'monitor': '${training.metric}', 'verbose': True, 'save_last': True, 'save_top_k': 3}}]","metadata":{"execution":{"iopub.status.busy":"2024-07-05T05:16:21.923287Z","iopub.execute_input":"2024-07-05T05:16:21.923697Z","iopub.status.idle":"2024-07-05T05:16:21.932336Z","shell.execute_reply.started":"2024-07-05T05:16:21.923664Z","shell.execute_reply":"2024-07-05T05:16:21.930837Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cfg = OmegaConf.create(dict_cfg)\nprint(OmegaConf.to_yaml(cfg))","metadata":{"execution":{"iopub.status.busy":"2024-07-05T05:16:22.306483Z","iopub.execute_input":"2024-07-05T05:16:22.306906Z","iopub.status.idle":"2024-07-05T05:16:22.355777Z","shell.execute_reply.started":"2024-07-05T05:16:22.306870Z","shell.execute_reply":"2024-07-05T05:16:22.354588Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Utils","metadata":{}},{"cell_type":"code","source":"BOX_COLOR = (255, 0, 0) # Red\nTEXT_COLOR = (255, 255, 255) # White\n\ndef draw_bbox(img, bbox, class_name, color=BOX_COLOR, thickness=2):\n    \"\"\"Visualizes a single bounding box on the image\"\"\"\n    x_min, y_min, x_max, y_max = bbox.astype('int')\n    cv2.rectangle(img, (x_min, y_min), (x_max, y_max), color=color, thickness=thickness)\n\n    ((text_width, text_height), _) = cv2.getTextSize(class_name, cv2.FONT_HERSHEY_SIMPLEX, 0.35, 1)\n    cv2.rectangle(img, (x_min, y_min - int(1.3 * text_height)), (x_min + text_width, y_min), BOX_COLOR, -1)\n    cv2.putText(\n        img,\n        text=class_name,\n        org=(x_min, y_min - int(0.3 * text_height)),\n        fontFace=cv2.FONT_HERSHEY_SIMPLEX,\n        fontScale=0.35,\n        color=TEXT_COLOR,\n        lineType=cv2.LINE_AA,\n    )\n    return img\n\ndef draw_bboxes(image, bboxes, labels, classes):\n    for bbox, label in zip(bboxes, labels):\n        class_name = classes[label]\n        image = draw_bbox(image, bbox, class_name)\n    return image\n\ndef load_obj(obj_path: str, default_obj_path: str = \"\") -> Any:\n    \"\"\"Extract an object from a given path.\n        Args:\n            obj_path: Path to an object to be extracted, including the object name.\n            default_obj_path: Default object path.\n        Returns:\n            Extracted object.\n        Raises:\n            AttributeError: When the object does not have the given named attribute.\n    \"\"\"\n    obj_path_list = obj_path.rsplit(\".\", 1)\n    obj_path = obj_path_list.pop(0) if len(obj_path_list) > 1 else default_obj_path\n    obj_name = obj_path_list[0]\n    module_obj = importlib.import_module(obj_path)\n    if not hasattr(module_obj, obj_name):\n        raise AttributeError(\n            f\"Object `{obj_name}` cannot be loaded from `{obj_path}`.\"\n        )\n    return getattr(module_obj, obj_name)","metadata":{"execution":{"iopub.status.busy":"2024-07-05T05:16:36.874657Z","iopub.execute_input":"2024-07-05T05:16:36.875130Z","iopub.status.idle":"2024-07-05T05:16:36.889733Z","shell.execute_reply.started":"2024-07-05T05:16:36.875092Z","shell.execute_reply":"2024-07-05T05:16:36.888606Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def seed_worker(worker_id):\n    worker_seed = torch.initial_seed() % 2**32\n    np.random.seed(worker_seed)\n    random.seed(worker_seed)\n    \ndef plot_random_images(dataset, n_rows=2, n_cols=5, test=False):\n    fig = plt.figure(1, figsize=(n_rows*10, n_cols*10))\n    grid = ImageGrid(fig, 111, nrows_ncols=(n_rows, n_cols), axes_pad=(0.05, 0.5))\n    \n    for (plot_idx, dataset_idx) in enumerate(random.sample(range(len(dataset)), k=(n_rows*n_cols))):\n        if test:\n            image = dataset.get_raw_item(dataset_idx)      \n        else:\n            image, target = dataset.get_raw_item(dataset_idx)\n            image = draw_bboxes(image, target['boxes'], target['labels'], classes)\n        grid[plot_idx].imshow(image)\n        grid[plot_idx].set_axis_off()\n        grid[plot_idx].set_title(f\"H: {image.shape[0]}, W: {image.shape[1]}\")\n    \n    fig.tight_layout()\n    fig.show()","metadata":{"execution":{"iopub.status.busy":"2024-07-05T05:16:37.327934Z","iopub.execute_input":"2024-07-05T05:16:37.328359Z","iopub.status.idle":"2024-07-05T05:16:37.339583Z","shell.execute_reply.started":"2024-07-05T05:16:37.328327Z","shell.execute_reply":"2024-07-05T05:16:37.338146Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_value(value_cfg: Union[Dict, List, Any]):\n    if type(value_cfg) == dict:\n        keys = list(value_cfg.keys())\n        if keys == ['class_name', 'params']:\n            return load_obj(value_cfg['class_name'])(**load_value(value_cfg['params']))\n        else:\n            return {k: load_value(v) for k, v in value_cfg.items()}\n    elif type(value_cfg) == list:\n        a= [load_value(v) for v in value_cfg]\n        return a\n    else:\n        return value_cfg ","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Dataset","metadata":{}},{"cell_type":"code","source":"class TestWheatDataset(Dataset):\n\n    def __init__(self, image_df, transform=None):\n        self.image_df = image_df.copy(deep=True)\n        self.transform = transform\n\n    def __len__(self):\n        return self.image_df.shape[0]\n    \n    def get_raw_item(self, idx):\n        image_id = self.image_df.loc[idx, 'image_id']\n        image = cv2.imread(self.image_df.loc[idx, \"image_path\"])\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype('float32')\n        image /= 255.0\n        return image, image_id\n    \n    def __getitem__(self, idx):\n        image, image_id = self.get_raw_item(idx)\n        if self.transform:\n            transformed = self.transform(\n                image=image\n            )\n            image = transformed['image']\n        return image, image_id         ","metadata":{"execution":{"iopub.status.busy":"2024-07-05T05:16:38.297647Z","iopub.execute_input":"2024-07-05T05:16:38.298053Z","iopub.status.idle":"2024-07-05T05:16:38.308230Z","shell.execute_reply.started":"2024-07-05T05:16:38.298022Z","shell.execute_reply":"2024-07-05T05:16:38.306756Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Augmentation","metadata":{}},{"cell_type":"code","source":"def get_transform(augmentation_cfg):\n    augmentation_cfg = OmegaConf.to_container(augmentation_cfg, resolve=True)\n    transform = load_obj(augmentation_cfg['class_name'])(**load_value(augmentation_cfg['params']))\n    return transform","metadata":{"execution":{"iopub.status.busy":"2024-07-05T05:16:42.217922Z","iopub.execute_input":"2024-07-05T05:16:42.219042Z","iopub.status.idle":"2024-07-05T05:16:42.237952Z","shell.execute_reply.started":"2024-07-05T05:16:42.218999Z","shell.execute_reply":"2024-07-05T05:16:42.236375Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Dataset & DataLoader","metadata":{}},{"cell_type":"code","source":"test_image_df = pd.read_csv(cfg.data.test_image_path)\npredict_ds = TestWheatDataset(\n    image_df=test_image_df,\n    transform=get_transform(cfg.augmentation.test)\n)","metadata":{"execution":{"iopub.status.busy":"2024-07-05T05:16:44.232924Z","iopub.execute_input":"2024-07-05T05:16:44.233365Z","iopub.status.idle":"2024-07-05T05:16:44.243374Z","shell.execute_reply.started":"2024-07-05T05:16:44.233330Z","shell.execute_reply":"2024-07-05T05:16:44.242066Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def collate_fn(batch):\n    return tuple(zip(*batch))\n\npredict_dl = DataLoader(\n    predict_ds, batch_size=int(cfg.data.batch_size/2),\n    shuffle=False, drop_last=False,\n    num_workers=cfg.data.num_workers,\n    pin_memory=True,\n    worker_init_fn=seed_worker,\n    generator=torch.Generator().manual_seed(cfg.training.seed),\n    persistent_workers=True,\n    collate_fn=collate_fn\n)","metadata":{"execution":{"iopub.status.busy":"2024-07-05T05:16:44.772226Z","iopub.execute_input":"2024-07-05T05:16:44.772665Z","iopub.status.idle":"2024-07-05T05:16:44.780465Z","shell.execute_reply.started":"2024-07-05T05:16:44.772632Z","shell.execute_reply":"2024-07-05T05:16:44.779063Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model","metadata":{}},{"cell_type":"code","source":"def create_detection_model(model_cfg):\n    backbone_cfg = OmegaConf.to_container(model_cfg.backbone, resolve=True)\n    model = load_obj(backbone_cfg['class_name'])(**load_value(backbone_cfg['params']))\n\n    # get number of input features for the classifier\n    in_features = model.roi_heads.box_predictor.cls_score.in_features\n\n    # replace the pre-trained head with a new one\n    head_cfg = OmegaConf.to_container(model_cfg.head, resolve=True)\n#     head_cfg['params']['in_channels'] = in_features\n    model.roi_heads.box_predictor = load_obj(head_cfg['class_name'])(in_features, **load_value(head_cfg['params']))\n    return model\n\ndef create_example_input(data_cfg):\n    return torch.zeros((3, data_cfg.img_h, data_cfg.img_w), dtype=torch.float32).unsqueeze(0)\n","metadata":{"execution":{"iopub.status.busy":"2024-07-05T05:16:45.821626Z","iopub.execute_input":"2024-07-05T05:16:45.822040Z","iopub.status.idle":"2024-07-05T05:16:45.829388Z","shell.execute_reply.started":"2024-07-05T05:16:45.822009Z","shell.execute_reply":"2024-07-05T05:16:45.828050Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\nmodel = create_detection_model(cfg.model.test)\nmodel.to(device)\nmodel.load_state_dict(torch.load(checkpoint_path, map_location=device))","metadata":{"execution":{"iopub.status.busy":"2024-07-05T05:16:49.570741Z","iopub.execute_input":"2024-07-05T05:16:49.571168Z","iopub.status.idle":"2024-07-05T05:16:53.304016Z","shell.execute_reply.started":"2024-07-05T05:16:49.571134Z","shell.execute_reply":"2024-07-05T05:16:53.302795Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Inference","metadata":{}},{"cell_type":"code","source":"def make_predictions(images, detection_threshold=0.22):\n    images = [image.to(device) for image in images]\n    predictions = []\n    prediction = []\n    with torch.no_grad():\n        a = 1\n        dets = model(images)\n        for i, image in enumerate(images):\n            boxes = dets[i]['boxes'].detach().cpu().numpy()\n            scores = dets[i]['scores'].detach().cpu().numpy()\n            labels = dets[i]['labels'].detach().cpu().numpy()\n            mask = scores >= detection_threshold\n\n            boxes = boxes[mask]\n            scores = scores[mask]\n            labels = labels[mask]\n            \n            prediction.append({\n                'boxes': boxes,\n                'scores': scores,\n                'labels': labels,\n            })\n    predictions.append(prediction)\n    return predictions\n\ndef run_wbf(predictions, image_index, image_size=512, iou_thr=0.44, skip_box_thr=0.43, weights=None):\n    boxes_list = [(prediction[image_index]['boxes']/(image_size-1)).tolist()  for prediction in predictions]\n    scores_list = [prediction[image_index]['scores'].tolist()  for prediction in predictions]\n    labels_list = [prediction[image_index]['labels'].tolist()  for prediction in predictions]\n    boxes, scores, labels = weighted_boxes_fusion(\n        boxes_list, scores_list, labels_list, \n        weights=weights, iou_thr=iou_thr, skip_box_thr=skip_box_thr\n    )\n    boxes = boxes*(image_size-1)\n    return boxes, scores, labels\n\ndef extract_detections(predictions, image_index):\n    boxes = [prediction[image_index]['boxes']  for prediction in predictions]\n    scores = [prediction[image_index]['scores']  for prediction in predictions]\n    labels = [prediction[image_index]['labels']  for prediction in predictions]\n    \n    return np.asarray(boxes).squeeze(0), np.asarray(scores).squeeze(0), np.asarray(labels).squeeze(0)","metadata":{"execution":{"iopub.status.busy":"2024-07-05T05:17:30.513676Z","iopub.execute_input":"2024-07-05T05:17:30.514099Z","iopub.status.idle":"2024-07-05T05:17:30.530088Z","shell.execute_reply.started":"2024-07-05T05:17:30.514066Z","shell.execute_reply":"2024-07-05T05:17:30.528827Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def format_prediction_string(boxes, scores):\n    pred_strings = []\n    for j in zip(scores, boxes):\n        pred_strings.append(\"{0:.4f} {1} {2} {3} {4}\".format(j[0], j[1][0], j[1][1], j[1][2], j[1][3]))\n\n    return \" \".join(pred_strings)","metadata":{"execution":{"iopub.status.busy":"2024-07-05T05:17:31.394563Z","iopub.execute_input":"2024-07-05T05:17:31.395741Z","iopub.status.idle":"2024-07-05T05:17:31.402290Z","shell.execute_reply.started":"2024-07-05T05:17:31.395688Z","shell.execute_reply":"2024-07-05T05:17:31.401041Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.eval()\nresults = []\n\nfor images, image_ids in predict_dl:\n    predictions = make_predictions(images)\n    for i, image in enumerate(images):\n        boxes, scores, labels = run_wbf(\n            predictions, image_index=i,\n            image_size=cfg.data.img_h\n        )\n        \n        boxes = (boxes*2).astype(np.int32).clip(min=0, max=1023)\n        labels = labels.astype(np.int32)\n        image_id = image_ids[i]\n        \n        boxes[:, 2] = boxes[:, 2] - boxes[:, 0]\n        boxes[:, 3] = boxes[:, 3] - boxes[:, 1]\n\n        result = {\n            'image_id': image_id,\n            'PredictionString': format_prediction_string(boxes, scores)\n        }\n        results.append(result)","metadata":{"execution":{"iopub.status.busy":"2024-07-05T05:17:35.427415Z","iopub.execute_input":"2024-07-05T05:17:35.427830Z","iopub.status.idle":"2024-07-05T05:18:45.903903Z","shell.execute_reply.started":"2024-07-05T05:17:35.427797Z","shell.execute_reply":"2024-07-05T05:18:45.902042Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df = pd.DataFrame(results, columns=['image_id', 'PredictionString'])\ntest_df.to_csv('submission.csv', index=False)\ntest_df.head()","metadata":{"execution":{"iopub.status.busy":"2024-07-05T05:19:30.796963Z","iopub.execute_input":"2024-07-05T05:19:30.797517Z","iopub.status.idle":"2024-07-05T05:19:30.825653Z","shell.execute_reply.started":"2024-07-05T05:19:30.797463Z","shell.execute_reply":"2024-07-05T05:19:30.824149Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictions = make_predictions(images)\n\ni = 1\nsample_image = images[i].permute(1,2,0).cpu().numpy()\n\nboxes, scores, labels = run_wbf(predictions, image_index=i)\nboxes = boxes.astype(np.int32).clip(min=0, max=511)\nlabels = labels.astype(np.int32)\nfig, ax = plt.subplots(1, 1, figsize=(16, 8))\n\nsample_image = draw_bboxes(sample_image, boxes, labels, classes)\n# for box in boxes:\n#     cv2.rectangle(sample, (box[0], box[1]), (box[2], box[3]), (1, 0, 0), 1)\n    \nax.set_axis_off()\nax.imshow(sample_image)\nfig.tight_layout()\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2024-07-05T05:19:34.153647Z","iopub.execute_input":"2024-07-05T05:19:34.154119Z","iopub.status.idle":"2024-07-05T05:19:49.485388Z","shell.execute_reply.started":"2024-07-05T05:19:34.154080Z","shell.execute_reply":"2024-07-05T05:19:49.483801Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# submission_df.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2024-07-03T08:09:00.691971Z","iopub.execute_input":"2024-07-03T08:09:00.692369Z","iopub.status.idle":"2024-07-03T08:09:00.699048Z","shell.execute_reply.started":"2024-07-03T08:09:00.692336Z","shell.execute_reply":"2024-07-03T08:09:00.697816Z"},"trusted":true},"execution_count":null,"outputs":[]}]}