{"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":"!cp -r ../input/swin-mmdetection/* ./\n!cp ../input/swin-weights/swin_base_patch4_window12_384_22k.pth ./\n\n!pip install ./src/mmdet-2.11.0/mmdet-2.11.0/\n!pip install ./src/mmpycocotools-12.0.3/mmpycocotools-12.0.3/\n!pip install ./src/addict-2.4.0-py3-none-any.whl\n!pip install ./src/yapf-0.30.0-py2.py3-none-any.whl\n!pip install ./src/mmcv_full-1.2.6-cp37-cp37m-manylinux1_x86_64.whl\n!pip install ./src/timm-0.4.5-py3-none-any.whl","metadata":{"execution":{"iopub.status.busy":"2021-06-07T12:47:48.850573Z","iopub.execute_input":"2021-06-07T12:47:48.851086Z","iopub.status.idle":"2021-06-07T12:49:07.472876Z","shell.execute_reply.started":"2021-06-07T12:47:48.850977Z","shell.execute_reply":"2021-06-07T12:49:07.471861Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport json\nimport pickle\nimport zlib\nimport base64\nimport typing as t\nimport numpy as np\nimport pandas as pd\n\n# PyTorch\nimport torch\n\n# MMdetection\nimport mmcv\nfrom mmcv import Config\nfrom mmcv.parallel import MMDataParallel\nfrom mmdet.datasets import build_dataloader, build_dataset\nfrom mmdet.apis import single_gpu_test\nfrom mmdet.models import build_detector\n\n# COCO\nfrom pycocotools import mask as mutils\nfrom pycocotools import _mask as coco_mask","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-06-07T12:49:24.784609Z","iopub.execute_input":"2021-06-07T12:49:24.784958Z","iopub.status.idle":"2021-06-07T12:49:28.927337Z","shell.execute_reply.started":"2021-06-07T12:49:24.784908Z","shell.execute_reply":"2021-06-07T12:49:28.926508Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### I - Helpers","metadata":{}},{"cell_type":"code","source":"# Helpers\n\ndef get_testing_annotations(df,\n                            image_id='ID',\n                            image_width='ImageWidth',\n                            image_height='ImageHeight',\n                            filename='test_annotations.json'):\n    custom_annotations = []\n    for idx, row in df.iterrows():\n        custom_annotation = {'filename': f'{row[image_id]}_green.png',\n                             'width': row[image_width],\n                             'height': row[image_height],\n                             'ann': {'bboxes': None, 'labels': None, 'masks': None}\n                            }\n        custom_annotations.append(custom_annotation)\n    with open(filename, 'w') as json_file:\n        json.dump(custom_annotations, json_file)\n    return custom_annotations\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 != np.bool:\n        mask_dtype_error = \"encode_binary_mask expects a binary mask\"\n        raise ValueError(f\"{mask_dtype_error}, received dtype == {mask.dtype}\")\n    mask = np.squeeze(mask)\n    if len(mask.shape) != 2:\n        mask_shape_error = \"encode_binary_mask expects a 2d mask\"\n        raise ValueError(f\"{mask_shape_error}, received shape == {mask.dtype}\")\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    # RLE encode mask --\n    encoded_mask = coco_mask.encode(mask_to_encode)[0][\"counts\"]\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\n","metadata":{"execution":{"iopub.status.busy":"2021-06-07T12:49:33.672061Z","iopub.execute_input":"2021-06-07T12:49:33.672393Z","iopub.status.idle":"2021-06-07T12:49:33.684072Z","shell.execute_reply.started":"2021-06-07T12:49:33.672362Z","shell.execute_reply":"2021-06-07T12:49:33.683022Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### II - Inference","metadata":{}},{"cell_type":"code","source":"df = pd.read_csv('../input/hpa-single-cell-image-classification/sample_submission.csv')\n# Build test annotations\ncustom_test_annotations = get_testing_annotations(df)\n\n# Build model config\nconfig_file = '../input/swin-mmdetection/configs/htc/htc+_swin_base_patch4_window12_1x_coco.py'\ncfg = Config.fromfile(config_file)\ncfg.data.samples_per_gpu = 1\n\n# Build testing dataset\ntest_dataset = build_dataset(cfg.data.test)\ntest_data_loader = build_dataloader(test_dataset,\n                                    cfg.data.samples_per_gpu,\n                                    cfg.data.workers_per_gpu,\n                                    # cfg.gpus will be ignored if distributed\n                                    # len(cfg.gpu_ids),\n                                    dist=False,\n                                    shuffle=False)\n# Build the detector\nmodel = build_detector(cfg.model, test_cfg=cfg.get('test_cfg'))\nmodel.CLASSES = test_dataset.CLASSES\nmodel = MMDataParallel(model, device_ids=[0])\nresults = single_gpu_test(model, test_data_loader, show=False, out_dir=None, show_score_thr=0.3)","metadata":{"execution":{"iopub.status.busy":"2021-06-07T12:49:37.173753Z","iopub.execute_input":"2021-06-07T12:49:37.174103Z","iopub.status.idle":"2021-06-07T13:12:20.760466Z","shell.execute_reply.started":"2021-06-07T12:49:37.17407Z","shell.execute_reply":"2021-06-07T13:12:20.759516Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!rm -rf ./*","metadata":{"execution":{"iopub.status.busy":"2021-06-07T13:12:25.475124Z","iopub.execute_input":"2021-06-07T13:12:25.475458Z","iopub.status.idle":"2021-06-07T13:12:25.985861Z","shell.execute_reply.started":"2021-06-07T13:12:25.475421Z","shell.execute_reply":"2021-06-07T13:12:25.984881Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### III - Generate submission file","metadata":{}},{"cell_type":"code","source":"%%time\n\nwith open('submission.csv', 'w') as submission_file:\n    print('ID,ImageWidth,ImageHeight,PredictionString', file=submission_file)\n    for i in range(len(custom_test_annotations)):\n        img_id = custom_test_annotations[i]['filename'].replace('.png', '')\n        prediction_strings = []\n        for class_id in range(19):\n            bounding_boxes = results[i][0][class_id]\n            segmentations = results[i][1][class_id]\n            for bounding_box, segmentation in zip(bounding_boxes, segmentations):\n                box, cnf = bounding_box[:4], bounding_box[4]\n                h, w = segmentation['size']\n                # convert coco format to kaggle format\n                mask = mutils.decode(segmentation).astype(bool)\n                rle = encode_binary_mask(mask).decode('ascii')\n                prediction_strings.append(f'{class_id} {cnf} {rle}')\n        print(f'{img_id},{w},{h},{\" \".join(prediction_strings)}', file=submission_file)","metadata":{"execution":{"iopub.status.busy":"2021-06-07T13:12:28.513214Z","iopub.execute_input":"2021-06-07T13:12:28.513619Z","iopub.status.idle":"2021-06-07T13:20:17.400902Z","shell.execute_reply.started":"2021-06-07T13:12:28.513581Z","shell.execute_reply":"2021-06-07T13:20:17.400177Z"},"trusted":true},"execution_count":null,"outputs":[]}]}