{"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":"markdown","source":"# SIIM MMDetection train demo notebook","metadata":{}},{"cell_type":"markdown","source":"This notebook uses [MMDetection](https://github.com/open-mmlab/mmdetection) framework to identify opacity bounding boxes in the SIIM competition.","metadata":{}},{"cell_type":"markdown","source":"[This dataset](https://www.kaggle.com/xhlulu/siim-covid19-resized-to-512px-png) is used for the train process, so please upvote it.","metadata":{}},{"cell_type":"markdown","source":"## Install dependencies","metadata":{}},{"cell_type":"code","source":"!pip install ../input/mmdet2100/mmdetection-2.10.0/addict-2.4.0-py3-none-any.whl\n!pip install ../input/mmdet2100/mmdetection-2.10.0/yapf-0.31.0-py2.py3-none-any.whl\n!pip install ../input/pycocotools202/pycocotools-2.0.2-cp37-cp37m-linux_x86_64.whl\n!pip install ../input/mmcvfull134/mmcv_full-1.3.4-cp37-cp37m-manylinux1_x86_64.whl\n!pip install ../input/mmdetection2120/mmdetection-2.12.0 -f ./ --no-index\n!pip install ../input/ensemble-boxes-104/ensemble_boxes-1.0.4/ -f ./ --no-index","metadata":{"execution":{"iopub.status.busy":"2021-07-10T20:34:10.460042Z","iopub.execute_input":"2021-07-10T20:34:10.460325Z","iopub.status.idle":"2021-07-10T20:36:20.045862Z","shell.execute_reply.started":"2021-07-10T20:34:10.460256Z","shell.execute_reply":"2021-07-10T20:36:20.044967Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport shutil\nimport yaml\nimport time\nimport json\nimport cv2\nimport random\nimport numpy as np\nimport pandas as pd\nfrom glob import glob\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import GroupKFold, StratifiedKFold\nfrom tqdm.notebook import tqdm\nimport seaborn as sns\nimport torch\nfrom IPython.display import Image, clear_output\nfrom collections import Counter\nfrom ensemble_boxes import *\nimport copy\nimport os.path as osp\nimport mmcv\nimport mmdet\nimport numpy as np\nimport albumentations as A\nfrom mmdet.datasets.builder import DATASETS\nfrom mmdet.datasets.custom import CustomDataset\nfrom mmcv import Config\nfrom mmdet.apis import set_random_seed\nfrom mmdet.apis import inference_detector, init_detector, show_result_pyplot\nfrom mmdet.datasets import build_dataset\nfrom mmdet.models import build_detector\nfrom mmdet.apis import train_detector\nprint(mmdet.__version__)\nos.environ['CUDA_VISIBLE_DEVICES'] = '0'","metadata":{"execution":{"iopub.status.busy":"2021-07-10T20:36:20.049179Z","iopub.execute_input":"2021-07-10T20:36:20.049456Z","iopub.status.idle":"2021-07-10T20:36:39.435922Z","shell.execute_reply.started":"2021-07-10T20:36:20.049427Z","shell.execute_reply":"2021-07-10T20:36:39.435048Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"VER = 'v4_4'\nDEBUG = False\nPARAMS = {\n    'version': VER,\n    'folds': 5,\n    'val_fold': 4,\n    'img_size': 640,\n    'batch_size': 8,\n    'epochs': 16,\n    'seed': 2021,\n    'iou_th': .6,\n    'th': .4,\n    ### r50\n    'config': 'vfnet_r50_fpn_mdconv_c3-c5_mstrain_2x_coco.py',\n    'checkpoint': 'vfnet_r50_fpn_mdconv_c3-c5_mstrain_2x_coco_20201027pth-6879c318.pth',\n    ### r101\n    #'config': 'vfnet_r101_fpn_mdconv_c3-c5_mstrain_2x_coco.py',\n    #'checkpoint': 'vfnet_r101_fpn_mdconv_c3-c5_mstrain_2x_coco_20201027pth-7729adb5.pth',\n    'comments': ''\n}\nDATA_PATH = '/kaggle/input/siim-covid19-detection'\nIMGS_PATH = f'/kaggle/input/siim-covid19-resized-384512-and-640px/SIIM-COVID19-Resized/img_sz_{PARAMS[\"img_size\"]}'\n#'/kaggle/input/siim-covid19-resized-to-512px-png'\nCHKP_PATH = '/kaggle/input/mmdet-vfnet-pretrained'\nMDLS_PATH = f'/kaggle/working/models_mmdet_{VER}'\nif not os.path.exists(MDLS_PATH):\n    os.mkdir(MDLS_PATH)\nwith open(f'{MDLS_PATH}/params.json', 'w') as file:\n    json.dump(PARAMS, file)\n    \ndef seed_all(seed):\n    random.seed(seed)\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    np.random.seed(seed)\n\nseed_all(PARAMS['seed'])\nstart_time = time.time()","metadata":{"execution":{"iopub.status.busy":"2021-07-10T20:36:39.438144Z","iopub.execute_input":"2021-07-10T20:36:39.4385Z","iopub.status.idle":"2021-07-10T20:36:39.447589Z","shell.execute_reply.started":"2021-07-10T20:36:39.438461Z","shell.execute_reply":"2021-07-10T20:36:39.446758Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Data preprocess","metadata":{}},{"cell_type":"code","source":"train_df = pd.read_csv(f'{IMGS_PATH}/meta_sz_{PARAMS[\"img_size\"]}.csv')\ntrain_df = train_df[train_df.split == 'train']\ndel train_df['split']\nif DEBUG:\n    train_df = train_df.loc[:100]\ndf_train_img = pd.read_csv(f'{DATA_PATH}/train_image_level.csv')\ndf_train_sty = pd.read_csv(f'{DATA_PATH}/train_study_level.csv')\n\ntrain_df['id'] = train_df['image_id'].apply(lambda x: ''.join([x.split('/')[-1], '_image']))\ndf_train_sty['StudyInstanceUID'] = df_train_sty['id'].apply(lambda x: x.replace('_study', ''))\ndel df_train_sty['id']\ndf_train_img = df_train_img.merge(df_train_sty, on='StudyInstanceUID')\ntrain_df = df_train_img.merge(train_df, on='id')\ntrain_df['img'] = train_df['image_id'] + '.jpg'\nprint(train_df.shape)\ndisplay(train_df.head())","metadata":{"execution":{"iopub.status.busy":"2021-07-10T20:36:39.449208Z","iopub.execute_input":"2021-07-10T20:36:39.44977Z","iopub.status.idle":"2021-07-10T20:36:39.600977Z","shell.execute_reply.started":"2021-07-10T20:36:39.449735Z","shell.execute_reply":"2021-07-10T20:36:39.600231Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def bar_plot(train_df, variable):\n    var = train_df[variable]\n    varValue = var.value_counts()\n    plt.figure(figsize = (12, 3))\n    plt.bar(varValue.index, varValue)\n    plt.xticks(varValue.index, varValue.index.values)\n    plt.ylabel(\"Frequency\")\n    plt.title(variable)\n    plt.show()\n    print(\"{}: \\n{}\".format(variable, varValue))\n\ntrain_df['target'] = 'Negative for Pneumonia'\ntrain_df.loc[train_df['Typical Appearance']==1, 'target'] = 'Typical Appearance'\ntrain_df.loc[train_df['Indeterminate Appearance']==1, 'target'] = 'Indeterminate Appearance'\ntrain_df.loc[train_df['Atypical Appearance']==1, 'target'] = 'Atypical Appearance'\nbar_plot(train_df, 'target') ","metadata":{"execution":{"iopub.status.busy":"2021-07-10T20:36:39.603696Z","iopub.execute_input":"2021-07-10T20:36:39.603952Z","iopub.status.idle":"2021-07-10T20:36:39.755178Z","shell.execute_reply.started":"2021-07-10T20:36:39.603914Z","shell.execute_reply":"2021-07-10T20:36:39.754364Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = train_df[~train_df.boxes.isnull()] \ntrain_df.reset_index(inplace=True)\nclasses = [\n    'Typical Appearance', \n    'Indeterminate Appearance', \n    'Atypical Appearance'\n]\nprint('classes:\\n', classes,\n      '\\nclasses labels:\\n', np.unique(train_df[classes].values, axis=0))","metadata":{"execution":{"iopub.status.busy":"2021-07-10T20:36:39.756451Z","iopub.execute_input":"2021-07-10T20:36:39.756827Z","iopub.status.idle":"2021-07-10T20:36:39.775135Z","shell.execute_reply.started":"2021-07-10T20:36:39.756789Z","shell.execute_reply":"2021-07-10T20:36:39.774359Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label2color = {\n    '[1, 0, 0]': [255, 0, 0], # Typical Appearance\n    '[0, 1, 0]': [0, 255, 0], # Indeterminate Appearance\n    '[0, 0, 1]': [0, 0, 255], # Atypical Appearance\n}\nlabel2classes = {\n    '[1, 0, 0]': classes[0],\n    '[0, 1, 0]': classes[1],\n    '[0, 0, 1]': classes[2]\n}\n\ndef plot_img(img, size=(18, 18), title='', cmap='gray'):\n    plt.figure(figsize=size)\n    plt.imshow(img, cmap=cmap)\n    plt.suptitle(title)\n    plt.show()\n\ndef plot_imgs(imgs, cols=2, size=10, is_rgb=True, title='', cmap='gray', img_size=None):\n    rows = len(imgs) // cols + 1\n    fig = plt.figure(figsize=(cols * size, rows * size))\n    for i, img in enumerate(imgs):\n        if img_size is not None:\n            img = cv2.resize(img, img_size)\n        fig.add_subplot(rows, cols, i + 1)\n        plt.axis('off')\n        plt.imshow(img, cmap=cmap)\n    plt.suptitle(title)\n    plt.axis('off')\n    \ndef draw_bbox(img, box, label, color, thickness=3):   \n    alpha = .1\n    alpha_box = .4\n    overlay_bbox = img.copy()\n    overlay_text = img.copy()\n    output = img.copy()\n    text_width, text_height = cv2.getTextSize(label.upper(), cv2.FONT_HERSHEY_SIMPLEX, .6, 1)[0]\n    cv2.rectangle(overlay_bbox, \n                  (box[0], box[1]), \n                  (box[2], box[3]), \n                  color, -1)\n    cv2.addWeighted(overlay_bbox, alpha, output, 1 - alpha, 0, output)\n    cv2.rectangle(overlay_text, \n                  (box[0], box[1] - 7 - text_height), \n                  (box[0] + text_width + 2, box[1]),\n                  (0, 0, 0), -1)\n    cv2.addWeighted(overlay_text, alpha_box, output, 1 - alpha_box, 0, output)\n    cv2.rectangle(output, \n                  (box[0], box[1]), \n                  (box[2], box[3]),\n                  color, thickness)\n    cv2.putText(output, \n                label.upper(), \n                (box[0], box[1]-5),\n                cv2.FONT_HERSHEY_SIMPLEX, \n                .6, (255, 255, 255), 1, \n                cv2.LINE_AA)\n    return output","metadata":{"execution":{"iopub.status.busy":"2021-07-10T20:36:39.777798Z","iopub.execute_input":"2021-07-10T20:36:39.778056Z","iopub.status.idle":"2021-07-10T20:36:39.791711Z","shell.execute_reply.started":"2021-07-10T20:36:39.778031Z","shell.execute_reply":"2021-07-10T20:36:39.79084Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"imgs = []\nsample = train_df.sample(n=4)['img'].values\nfor img_name in sample:\n    ratio_x = PARAMS['img_size'] / train_df.loc[train_df['img'] == img_name, 'dim1'].values[0]\n    ratio_y = PARAMS['img_size'] / train_df.loc[train_df['img'] == img_name, 'dim0'].values[0]\n    boxes = train_df.loc[train_df['img'] == img_name, 'boxes'].values[0]\n    boxes = json.loads(boxes.replace('\\'', '\\\"'))\n    boxes = [[int(box['x'] * ratio_x), \n              int(box['y'] * ratio_y), \n              int((box['x'] + box['width']) * ratio_x), \n              int((box['y'] + box['height']) * ratio_y)]\n             for box in boxes]\n    img_labels = train_df.loc[train_df['img'] == img_name, classes].values[0]\n    img_labels = [str(img_labels.tolist())] * len(boxes)\n    img = cv2.imread(f'{IMGS_PATH}/train/{img_name}')\n    for label_id, box in zip(img_labels, boxes):\n        color = label2color[label_id]\n        img = draw_bbox(\n            img, \n            list(np.int_(box)), \n            label2classes[label_id], \n            label2color[label_id]\n        )\n    imgs.append(img)\nplot_imgs(imgs, size=8, cols=4, cmap=None)","metadata":{"execution":{"iopub.status.busy":"2021-07-10T20:36:39.794205Z","iopub.execute_input":"2021-07-10T20:36:39.794542Z","iopub.status.idle":"2021-07-10T20:36:40.489694Z","shell.execute_reply.started":"2021-07-10T20:36:39.794511Z","shell.execute_reply":"2021-07-10T20:36:40.485641Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"skf  = StratifiedKFold(n_splits=PARAMS['folds'])\ntrain_df['fold'] = -1\nfor fold, (train_idx, val_idx) in enumerate(skf.split(train_df, y=train_df.target)):\n    train_df.loc[val_idx, 'fold'] = fold","metadata":{"execution":{"iopub.status.busy":"2021-07-10T20:36:40.491298Z","iopub.execute_input":"2021-07-10T20:36:40.491658Z","iopub.status.idle":"2021-07-10T20:36:40.521238Z","shell.execute_reply.started":"2021-07-10T20:36:40.491618Z","shell.execute_reply":"2021-07-10T20:36:40.519924Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"split = PARAMS['val_fold']\nwith open(f'{MDLS_PATH}/train.txt', 'w') as file:\n    tr_ids = list(train_df[train_df['fold'] != split].img.unique())\n    print('train:', len(tr_ids))\n    file.write('\\n'.join(tr_ids))\nwith open(f'{MDLS_PATH}/val.txt', 'w') as file:\n    val_ids = list(train_df[train_df['fold'] == split].img.unique())\n    print('val:', len(val_ids))\n    file.write('\\n'.join(val_ids))","metadata":{"execution":{"iopub.status.busy":"2021-07-10T20:36:40.522908Z","iopub.execute_input":"2021-07-10T20:36:40.523303Z","iopub.status.idle":"2021-07-10T20:36:40.552166Z","shell.execute_reply.started":"2021-07-10T20:36:40.523252Z","shell.execute_reply":"2021-07-10T20:36:40.551248Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Training","metadata":{}},{"cell_type":"code","source":"@DATASETS.register_module()\nclass SIIMDataset(CustomDataset):\n    CLASSES = ('opacity', )\n    ANN_DF = train_df.copy()\n    def load_annotations(self, ann_file):\n        cat2label = {k: i for i, k in enumerate(self.CLASSES)}\n        image_list = mmcv.list_from_file(self.ann_file)\n        data_infos = []\n        for img_id in image_list:\n            img_anns = self.ANN_DF[self.ANN_DF.img == img_id]\n            filename = f'{self.img_prefix}/{img_anns[\"img\"].values[0]}'\n            data_info = dict(\n                filename=filename, \n                width=PARAMS['img_size'], \n                height=PARAMS['img_size']\n            )\n            ratio_x = PARAMS['img_size'] / img_anns['dim1'].values[0]\n            ratio_y = PARAMS['img_size'] / img_anns['dim0'].values[0]\n            boxes = img_anns['boxes'].values[0]\n            boxes = json.loads(boxes.replace('\\'', '\\\"'))\n            gt_bboxes = [\n                [int(box['x'] * ratio_x), \n                 int(box['y'] * ratio_y), \n                 int((box['x'] + box['width']) * ratio_x), \n                 int((box['y'] + box['height']) * ratio_y)]\n                for box in boxes]\n            img_labels = img_anns[classes].values[0]\n            gt_labels = [0] * len(boxes)\n            data_anno = dict(\n                bboxes=np.array(gt_bboxes, dtype=np.float32).reshape(-1, 4),\n                labels=np.array(gt_labels),\n            )\n            data_info.update(ann=data_anno)\n            data_infos.append(data_info)\n        return data_infos","metadata":{"execution":{"iopub.status.busy":"2021-07-10T20:36:40.556522Z","iopub.execute_input":"2021-07-10T20:36:40.557069Z","iopub.status.idle":"2021-07-10T20:36:40.574887Z","shell.execute_reply.started":"2021-07-10T20:36:40.557026Z","shell.execute_reply":"2021-07-10T20:36:40.573873Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_transforms = A.Compose([\n    A.OneOf([\n        A.RandomBrightness(limit=.2, p=1), \n        A.RandomContrast(limit=.2, p=1), \n        A.RandomGamma(p=1)\n    ], p=.5),\n    A.OneOf([\n        A.Blur(blur_limit=3, p=1),\n        A.MedianBlur(blur_limit=3, p=1)\n    ], p=.25),\n    A.OneOf([\n        A.GaussNoise(0.002, p=.5),\n        A.IAAAffine(p=.5),\n    ], p=.25),\n    A.VerticalFlip(p=.5),\n    A.HorizontalFlip(p=.5),\n    A.Transpose(p=.25),\n    A.RandomRotate90(p=.25),\n    A.Cutout(num_holes=10, max_h_size=20, max_w_size=20, p=.25),\n    A.ShiftScaleRotate(p=.5)\n])","metadata":{"execution":{"iopub.status.busy":"2021-07-10T20:36:40.578576Z","iopub.execute_input":"2021-07-10T20:36:40.578904Z","iopub.status.idle":"2021-07-10T20:36:40.591996Z","shell.execute_reply.started":"2021-07-10T20:36:40.578878Z","shell.execute_reply":"2021-07-10T20:36:40.590493Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cfg = Config.fromfile(f'../input/mmdetection2120/mmdetection-2.12.0/configs/vfnet/{PARAMS[\"config\"]}')\ncfg.load_from = f'{CHKP_PATH}/{PARAMS[\"checkpoint\"]}'\ncfg.model.bbox_head.num_classes = 1\ncfg.dump(f'{MDLS_PATH}/init_config.py')\ncfg.train_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(\n        type='Resize',\n        img_scale=[(1333, 640), (1333, 672), (1333, 704), (1333, 736),\n                   (1333, 768), (1333, 800)],\n        multiscale_mode='value',\n        keep_ratio=True),\n    ########################################\n    # Note that this key is part of bbox_params. \n    # Their difference is format='pascal_voc' means [x1, y1, x2, y2] style box encoding, \n    # while format='coco' means [x, y, w, h].\n    dict(\n        type='Albu',\n        transforms=train_transforms,\n        bbox_params=dict(\n            type='BboxParams',\n            format='pascal_voc',\n            label_fields=['gt_labels'],\n            min_visibility=0.0,\n            filter_lost_elements=True),\n        keymap={\n            'img': 'image',\n            'gt_bboxes': 'bboxes'},\n        update_pad_shape=False,\n        skip_img_without_anno=True),\n    #########################################\n    dict(\n        type='Normalize',\n        mean=[103.53, 116.28, 123.675],\n        std=[1.0, 1.0, 1.0],\n        to_rgb=False),\n    dict(type='Pad', size_divisor=32),\n    dict(type='DefaultFormatBundle'),\n    dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels'])\n]\ncfg.dataset_type = 'SIIMDataset'\ncfg.data_root = f'{IMGS_PATH}/train'\ncfg.data.test.type = 'SIIMDataset'\ncfg.data.test.data_root = IMGS_PATH\ncfg.data.test.ann_file = f'{MDLS_PATH}/train.txt'\ncfg.data.test.img_prefix = ''\ncfg.data.train.type = 'SIIMDataset'\ncfg.data.train.data_root = f'{IMGS_PATH}/train'\ncfg.data.train.ann_file = f'{MDLS_PATH}/train.txt'\ncfg.data.train.img_prefix = ''\ncfg.data.val.type = 'SIIMDataset'\ncfg.data.val.data_root = f'{IMGS_PATH}/train'\ncfg.data.val.ann_file = f'{MDLS_PATH}/val.txt'\ncfg.data.val.img_prefix = ''\ncfg.work_dir = MDLS_PATH\ncfg.optimizer.lr = .02 / (8 * 16 / PARAMS['batch_size'])\ncfg.log_config.interval = 128\ncfg.runner.max_epochs = PARAMS['epochs']\ncfg.checkpoint_config.interval = 1\ncfg.evaluation = dict(\n    interval=1, \n    start=2,\n    metric='mAP', \n    save_best='mAP')\ncfg.seed = PARAMS['seed']\nset_random_seed(0, deterministic=False)\ncfg.gpu_ids = range(1)\ncfg.data.samples_per_gpu = PARAMS['batch_size']\ncfg.data.workers_per_gpu = 2\ncfg.workflow = [('train', 1)]\ncfg.dump(f'{MDLS_PATH}/train_config.py')\nprint(f'Config:\\n{cfg.pretty_text}')\n\nelapsed_time = time.time() - start_time\nprint(f'time elapsed: {elapsed_time // 60:.0f} min {elapsed_time % 60:.0f} sec')","metadata":{"execution":{"iopub.status.busy":"2021-07-10T20:36:40.594151Z","iopub.execute_input":"2021-07-10T20:36:40.59458Z","iopub.status.idle":"2021-07-10T20:36:45.345192Z","shell.execute_reply.started":"2021-07-10T20:36:40.594543Z","shell.execute_reply":"2021-07-10T20:36:45.344248Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"datasets = [build_dataset(cfg.data.train)]\nif len(cfg.workflow) == 2:\n    datasets.append(build_dataset(cfg.data.val))\nmodel = build_detector(\n    cfg.model, \n    train_cfg=cfg.get('train_cfg'), \n    test_cfg=cfg.get('test_cfg')\n)\nmodel.CLASSES = datasets[0].CLASSES\nmmcv.mkdir_or_exist(osp.abspath(cfg.work_dir))\ntrain_detector(model, datasets, cfg, distributed=False, validate=True)\n\nelapsed_time = time.time() - start_time\nprint(f'time elapsed: {elapsed_time // 60:.0f} min {elapsed_time % 60:.0f} sec')","metadata":{"execution":{"iopub.status.busy":"2021-07-10T20:36:45.349779Z","iopub.execute_input":"2021-07-10T20:36:45.352544Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Inference demo","metadata":{}},{"cell_type":"code","source":"checkpoint = f'{MDLS_PATH}/epoch_{PARAMS[\"epochs\"]}.pth'\ncfg = f'{MDLS_PATH}/init_config.py'\nmodel_test = init_detector(cfg, checkpoint, device='cuda:0')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"imgs = []\nsplit = PARAMS['val_fold']\nsample = train_df[train_df['fold'] != split].sample(n=4)['img'].values\nfor img_name in sample:\n    ratio_x = PARAMS['img_size'] / train_df.loc[train_df['img'] == img_name, 'dim1'].values[0]\n    ratio_y = PARAMS['img_size'] / train_df.loc[train_df['img'] == img_name, 'dim0'].values[0]\n    boxes = train_df.loc[train_df['img'] == img_name, 'boxes'].values[0]\n    boxes = json.loads(boxes.replace('\\'', '\\\"'))\n    boxes = [[int(box['x'] * ratio_x), \n              int(box['y'] * ratio_y), \n              int((box['x'] + box['width']) * ratio_x), \n              int((box['y'] + box['height']) * ratio_y)]\n             for box in boxes]\n    img_labels = train_df.loc[train_df['img'] == img_name, classes].values[0]\n    img_labels = [str(img_labels.tolist())] * len(boxes)\n    img = cv2.imread(f'{IMGS_PATH}/train/{img_name}')\n    for label_id, box in zip(img_labels, boxes):\n        color = label2color[label_id]\n        img = draw_bbox(\n            img, \n            list(np.int_(box)), \n            label2classes[label_id], \n            label2color[label_id]\n        )\n    result = inference_detector(model_test, img)\n    boxes_list = [list(x[:, :4] / PARAMS['img_size']) for x in result if x.shape[0] != 0]\n    boxes_list =  [item for sublist in boxes_list for item in sublist]\n    scores_list = [x[:, 4].tolist() for x in result if x.shape[0] != 0]\n    scores_list =  [item for sublist in scores_list for item in sublist]\n    labels_list = [[i] * x.shape[0] for i, x in enumerate(result) if x.shape[0] != 0]\n    labels_list =  [item for sublist in labels_list for item in sublist]\n    boxes, scores, box_labels = nms(\n        boxes=[boxes_list], \n        scores=[scores_list], \n        labels=[labels_list], \n        weights=None,\n        iou_thr=PARAMS['iou_th']\n    )\n    boxes *= PARAMS['img_size']\n    for label_id, box, score in zip(box_labels, boxes, scores):\n        if score >= PARAMS['th']:\n            color = [255, 255, 255]\n            img = draw_bbox(\n                img, \n                list(np.int_(box)), \n                'predict', \n                color\n            )\n    imgs.append(img)\nplot_imgs(imgs, size=8, cols=4, cmap=None)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"elapsed_time = time.time() - start_time\nprint(f'time elapsed: {elapsed_time // 60:.0f} min {elapsed_time % 60:.0f} sec')","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}