{"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":"# **Weighted Cluster-DIoU-NMS**","metadata":{}},{"cell_type":"markdown","source":"### May help improve +0.2 LB score","metadata":{}},{"cell_type":"markdown","source":"# **Previous Notebooks**","metadata":{}},{"cell_type":"markdown","source":"https://www.kaggle.com/vexxingbanana/sartorius-coco-dataset-notebook\n\nhttps://www.kaggle.com/vexxingbanana/sartorius-mmdetection-training\n\nhttps://www.kaggle.com/vexxingbanana/mmdetection-neuron-inference","metadata":{}},{"cell_type":"markdown","source":"# **References**","metadata":{}},{"cell_type":"markdown","source":"https://www.kaggle.com/awsaf49/sartorius-mmdetection-infer\n\nhttps://github.com/Zzh-tju/CIoU","metadata":{}},{"cell_type":"markdown","source":"# **Install MMDetection**","metadata":{"papermill":{"duration":0.034808,"end_time":"2021-10-28T17:34:14.981619","exception":false,"start_time":"2021-10-28T17:34:14.946811","status":"completed"},"tags":[]}},{"cell_type":"code","source":"!pip install '/kaggle/input/pytorch-170-cuda-toolkit-110221/torch-1.7.0+cu110-cp37-cp37m-linux_x86_64.whl' --no-deps\n!pip install '/kaggle/input/pytorch-170-cuda-toolkit-110221/torchvision-0.8.1+cu110-cp37-cp37m-linux_x86_64.whl' --no-deps\n!pip install '/kaggle/input/pytorch-170-cuda-toolkit-110221/torchaudio-0.7.0-cp37-cp37m-linux_x86_64.whl' --no-deps","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","papermill":{"duration":127.55412,"end_time":"2021-10-28T17:36:22.571091","exception":false,"start_time":"2021-10-28T17:34:15.016971","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-12-07T08:09:56.611567Z","iopub.execute_input":"2021-12-07T08:09:56.612049Z","iopub.status.idle":"2021-12-07T08:11:58.79887Z","shell.execute_reply.started":"2021-12-07T08:09:56.611966Z","shell.execute_reply":"2021-12-07T08:11:58.797789Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install '/kaggle/input/mmdetectionv2140/addict-2.4.0-py3-none-any.whl' --no-deps\n!pip install '/kaggle/input/mmdetectionv2140/yapf-0.31.0-py2.py3-none-any.whl' --no-deps\n!pip install '/kaggle/input/mmdetectionv2140/terminal-0.4.0-py3-none-any.whl' --no-deps\n!pip install '/kaggle/input/mmdetectionv2140/terminaltables-3.1.0-py3-none-any.whl' --no-deps\n!pip install '/kaggle/input/mmdetectionv2140/mmcv_full-1_3_8-cu110-torch1_7_0/mmcv_full-1.3.8-cp37-cp37m-manylinux1_x86_64.whl' --no-deps\n!pip install '/kaggle/input/mmdetectionv2140/pycocotools-2.0.2/pycocotools-2.0.2' --no-deps\n!pip install '/kaggle/input/mmdetectionv2140/mmpycocotools-12.0.3/mmpycocotools-12.0.3' --no-deps\n\n!rm -rf mmdetection\n\n!cp -r ../input/edited-mmdetection /kaggle/working/\n!mv /kaggle/working/edited-mmdetection /kaggle/working/mmdetection\n%cd /kaggle/working/mmdetection","metadata":{"papermill":{"duration":222.21755,"end_time":"2021-10-28T17:40:04.826612","exception":false,"start_time":"2021-10-28T17:36:22.609062","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-12-07T08:11:58.801156Z","iopub.execute_input":"2021-12-07T08:11:58.80144Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%writefile /kaggle/working/mmdetection/mmdet/core/post_processing/bbox_nms.py\n\nimport torch\nfrom mmcv.ops.nms import batched_nms\n\nfrom mmdet.core.bbox.iou_calculators import bbox_overlaps\n\ndef intersect(box_a, box_b):\n\n    n = box_a.size(0)\n    A = box_a.size(1)\n    B = box_b.size(1)\n    max_xy = torch.min(box_a[:, :, 2:].unsqueeze(2).expand(n, A, B, 2),\n                       box_b[:, :, 2:].unsqueeze(1).expand(n, A, B, 2))\n    min_xy = torch.max(box_a[:, :, :2].unsqueeze(2).expand(n, A, B, 2),\n                       box_b[:, :, :2].unsqueeze(1).expand(n, A, B, 2))\n    inter = torch.clamp((max_xy - min_xy), min=0)\n    return inter[:, :, :, 0] * inter[:, :, :, 1]\n\ndef diou(box_a, box_b, beta=1.0, iscrowd:bool=False):\n    use_batch = True\n    if box_a.dim() == 2:\n        use_batch = False\n        box_a = box_a[None, ...]\n        box_b = box_b[None, ...]\n\n    inter = intersect(box_a, box_b)\n    area_a = ((box_a[:, :, 2]-box_a[:, :, 0]) *\n              (box_a[:, :, 3]-box_a[:, :, 1])).unsqueeze(2).expand_as(inter)  # [A,B]\n    area_b = ((box_b[:, :, 2]-box_b[:, :, 0]) *\n              (box_b[:, :, 3]-box_b[:, :, 1])).unsqueeze(1).expand_as(inter)  # [A,B]\n    union = area_a + area_b - inter\n    x1 = ((box_a[:, :, 2]+box_a[:, :, 0]) / 2).unsqueeze(2).expand_as(inter)\n    y1 = ((box_a[:, :, 3]+box_a[:, :, 1]) / 2).unsqueeze(2).expand_as(inter)\n    x2 = ((box_b[:, :, 2]+box_b[:, :, 0]) / 2).unsqueeze(1).expand_as(inter)\n    y2 = ((box_b[:, :, 3]+box_b[:, :, 1]) / 2).unsqueeze(1).expand_as(inter)\n\n    t1 = box_a[:, :, 1].unsqueeze(2).expand_as(inter)\n    b1 = box_a[:, :, 3].unsqueeze(2).expand_as(inter)\n    l1 = box_a[:, :, 0].unsqueeze(2).expand_as(inter)\n    r1 = box_a[:, :, 2].unsqueeze(2).expand_as(inter)\n\n    t2 = box_b[:, :, 1].unsqueeze(1).expand_as(inter)\n    b2 = box_b[:, :, 3].unsqueeze(1).expand_as(inter)\n    l2 = box_b[:, :, 0].unsqueeze(1).expand_as(inter)\n    r2 = box_b[:, :, 2].unsqueeze(1).expand_as(inter)\n    cr = torch.max(r1, r2)\n    cl = torch.min(l1, l2)\n    ct = torch.min(t1, t2)\n    cb = torch.max(b1, b2)\n    D = (((x2 - x1)**2 + (y2 - y1)**2) / ((cr-cl)**2 + (cb-ct)**2 + 1e-7))\n    out = inter / area_a if iscrowd else inter / union - D ** beta\n    return out if use_batch else out.squeeze(0)\n\ndef multiclass_nms(multi_bboxes,\n                   multi_scores,\n                   score_thr,\n                   nms_cfg,\n                   max_num=-1,\n                   score_factors=None,\n                   return_inds=False):\n    \"\"\"NMS for multi-class bboxes.\n\n    Args:\n        multi_bboxes (Tensor): shape (n, #class*4) or (n, 4)\n        multi_scores (Tensor): shape (n, #class), where the last column\n            contains scores of the background class, but this will be ignored.\n        score_thr (float): bbox threshold, bboxes with scores lower than it\n            will not be considered.\n        nms_thr (float): NMS IoU threshold\n        max_num (int, optional): if there are more than max_num bboxes after\n            NMS, only top max_num will be kept. Default to -1.\n        score_factors (Tensor, optional): The factors multiplied to scores\n            before applying NMS. Default to None.\n        return_inds (bool, optional): Whether return the indices of kept\n            bboxes. Default to False.\n\n    Returns:\n        tuple: (dets, labels, indices (optional)), tensors of shape (k, 5),\n            (k), and (k). Dets are boxes with scores. Labels are 0-based.\n    \"\"\"\n    iou_thr = nms_cfg['iou_threshold']\n    num_classes = multi_scores.size(1) - 1\n    # exclude background category\n    if multi_bboxes.shape[1] > 4:\n        bboxes = multi_bboxes.view(multi_scores.size(0), -1, 4)\n    else:\n        bboxes = multi_bboxes[:, None].expand(\n            multi_scores.size(0), num_classes, 4)\n\n    scores = multi_scores[:, :-1]\n\n    labels = torch.arange(num_classes, dtype=torch.long).cuda()\n    labels = labels.view(1, -1).expand_as(scores)\n\n    bboxes = bboxes.reshape(-1, 4)\n    scores = scores.reshape(-1)\n    labels = labels.reshape(-1)\n\n    if not torch.onnx.is_in_onnx_export():\n        # NonZero not supported  in TensorRT\n        # remove low scoring boxes\n        valid_mask = scores > score_thr\n    # multiply score_factor after threshold to preserve more bboxes, improve\n    # mAP by 1% for YOLOv3\n    if score_factors is not None:\n        # expand the shape to match original shape of score\n        score_factors = score_factors.view(-1, 1).expand(\n            multi_scores.size(0), num_classes)\n        score_factors = score_factors.reshape(-1)\n        scores = scores * score_factors\n\n    if not torch.onnx.is_in_onnx_export():\n        # NonZero not supported  in TensorRT\n        inds = valid_mask.nonzero(as_tuple=False).squeeze(1)\n        bboxes, scores, labels = bboxes[inds], scores[inds], labels[inds]\n    else:\n        # TensorRT NMS plugin has invalid output filled with -1\n        # add dummy data to make detection output correct.\n        bboxes = torch.cat([bboxes, bboxes.new_zeros(1, 4)], dim=0)\n        scores = torch.cat([scores, scores.new_zeros(1)], dim=0)\n        labels = torch.cat([labels, labels.new_zeros(1)], dim=0)\n\n    if bboxes.numel() == 0:\n        if torch.onnx.is_in_onnx_export():\n            raise RuntimeError('[ONNX Error] Can not record NMS '\n                               'as it has not been executed this time')\n        dets = torch.cat([bboxes, scores[:, None]], -1)\n        if return_inds:\n            return dets, labels, inds\n        else:\n            return dets, labels\n    \n    # Weighted Cluster-DIoU-NMS\n    scores, idx = scores.sort(0, descending=True)\n    bboxes = bboxes[idx]\n    labels = labels[idx]\n    inds = inds[idx]\n    box = bboxes + labels.unsqueeze(1).expand_as(bboxes)*4000\n\n    diou_matrix = diou(box, box, 0.8)    # DIoU matrix\n    iou = (diou_matrix+0).triu_(diagonal=1) \n    B = iou\n    for i in range(999):\n        A=B\n        maxA = A.max(dim=0)[0]\n        E = (maxA <= iou_thr).float().unsqueeze(1).expand_as(A)\n        B=iou.mul(E)\n        if A.equal(B)==True:\n            break\n    B=torch.triu(diou_matrix).mul(E)\n    keep = (maxA <= iou_thr)\n    weights = (torch.exp(-(1-(B*(B>0.7).float()))**2 / 0.025)) * (scores.reshape((1,len(scores))))\n    #weights = (B*(B>0.7).float()) * (scores.reshape((1,len(scores))))\n    bboxes = torch.mm(weights, bboxes).float() / weights.sum(1, keepdim=True)\n\n        # Only keep the top max_num highest scores across all classes\n    if max_num > 0:\n        scores = scores[keep][:max_num]\n        labels = labels[keep][:max_num]\n        bboxes = bboxes[keep][:max_num]\n    dets = torch.cat([bboxes, scores[:, None]], dim=1)\n    \n    if return_inds:\n        return dets, labels, inds[keep]\n    else:\n        return dets, labels","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install -e .","metadata":{"execution":{"iopub.status.idle":"2021-12-07T08:15:25.78794Z","shell.execute_reply.started":"2021-12-07T08:14:52.451646Z","shell.execute_reply":"2021-12-07T08:15:25.787107Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Import Libraries**","metadata":{"papermill":{"duration":0.098388,"end_time":"2021-10-28T17:40:04.980758","exception":false,"start_time":"2021-10-28T17:40:04.88237","status":"completed"},"tags":[]}},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torchvision.transforms as transforms\nimport torch.nn.functional as F\nimport sklearn\nimport torchvision\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.preprocessing import LabelEncoder\nimport numpy as np\nimport cupy as cp\nimport gc\nimport pandas as pd\nimport os\nimport matplotlib.pyplot as plt\nimport PIL\nimport json\nfrom PIL import Image, ImageEnhance\nimport albumentations as A\nimport mmdet\nimport mmcv\nfrom albumentations.pytorch import ToTensorV2\nimport seaborn as sns\nimport glob\nfrom pathlib import Path\nimport pycocotools\nfrom pycocotools import mask\nimport numpy.random\nimport random\nimport cv2\nimport re\nimport shutil\nfrom mmdet.datasets import build_dataset\nfrom mmdet.models import build_detector\nfrom mmdet.apis import train_detector\nfrom mmdet.apis import inference_detector, init_detector, show_result_pyplot, set_random_seed","metadata":{"papermill":{"duration":28.752894,"end_time":"2021-10-28T17:40:33.786328","exception":false,"start_time":"2021-10-28T17:40:05.033434","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-12-07T08:15:25.789307Z","iopub.execute_input":"2021-12-07T08:15:25.789556Z","iopub.status.idle":"2021-12-07T08:15:50.269446Z","shell.execute_reply.started":"2021-12-07T08:15:25.78953Z","shell.execute_reply":"2021-12-07T08:15:50.268508Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%cd ..","metadata":{"papermill":{"duration":0.077806,"end_time":"2021-10-28T17:40:33.91703","exception":false,"start_time":"2021-10-28T17:40:33.839224","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-12-07T08:15:50.271305Z","iopub.execute_input":"2021-12-07T08:15:50.271582Z","iopub.status.idle":"2021-12-07T08:15:50.278184Z","shell.execute_reply.started":"2021-12-07T08:15:50.27155Z","shell.execute_reply":"2021-12-07T08:15:50.277326Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Helper Functions**","metadata":{"papermill":{"duration":0.052766,"end_time":"2021-10-28T17:40:34.030284","exception":false,"start_time":"2021-10-28T17:40:33.977518","status":"completed"},"tags":[]}},{"cell_type":"code","source":"IMG_WIDTH = 704\nIMG_HEIGHT = 520","metadata":{"papermill":{"duration":0.060207,"end_time":"2021-10-28T17:40:34.143033","exception":false,"start_time":"2021-10-28T17:40:34.082826","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-12-07T08:15:50.279596Z","iopub.execute_input":"2021-12-07T08:15:50.279936Z","iopub.status.idle":"2021-12-07T08:15:50.287837Z","shell.execute_reply.started":"2021-12-07T08:15:50.279901Z","shell.execute_reply":"2021-12-07T08:15:50.28711Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def rle_decode(mask_rle, shape):\n    '''\n    mask_rle: run-length as string formated (start length)\n    shape: (height,width) of array to return \n    Returns numpy array, 1 - mask, 0 - background\n\n    '''\n    s = mask_rle.split()\n    starts, lengths = [np.asarray(x, dtype=int) for x in (s[0:][::2], s[1:][::2])]\n    starts -= 1\n    ends = starts + lengths\n    img = np.zeros(shape[0]*shape[1], dtype=np.uint8)\n    for lo, hi in zip(starts, ends):\n        img[lo:hi] = 1\n    return img.reshape(shape)\n\ndef rle_encode(img):\n    '''\n    img: numpy array, 1 - mask, 0 - background\n    Returns run length as string formated\n    '''\n    pixels = img.flatten()\n    pixels = np.concatenate([[0], pixels, [0]])\n    runs = np.where(pixels[1:] != pixels[:-1])[0] + 1\n    runs[1::2] -= runs[::2]\n    return ' '.join(str(x) for x in runs)","metadata":{"papermill":{"duration":0.066347,"end_time":"2021-10-28T17:40:34.262446","exception":false,"start_time":"2021-10-28T17:40:34.196099","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-12-07T08:15:50.288854Z","iopub.execute_input":"2021-12-07T08:15:50.289595Z","iopub.status.idle":"2021-12-07T08:15:50.298107Z","shell.execute_reply.started":"2021-12-07T08:15:50.289558Z","shell.execute_reply":"2021-12-07T08:15:50.297428Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def rle_encoding(x):\n    dots = np.where(x.flatten() == 1)[0]\n    run_lengths = []\n    prev = -2\n    for b in dots:\n        if (b>prev+1): run_lengths.extend((b + 1, 0))\n        run_lengths[-1] += 1\n        prev = b\n    return ' '.join(map(str, run_lengths))","metadata":{"papermill":{"duration":0.063943,"end_time":"2021-10-28T17:40:34.378563","exception":false,"start_time":"2021-10-28T17:40:34.31462","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-12-07T08:15:50.299338Z","iopub.execute_input":"2021-12-07T08:15:50.299577Z","iopub.status.idle":"2021-12-07T08:15:50.307846Z","shell.execute_reply.started":"2021-12-07T08:15:50.299545Z","shell.execute_reply":"2021-12-07T08:15:50.307178Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_mask_from_result(result):\n    d = {True : 1, False : 0}\n    u,inv = np.unique(result,return_inverse = True)\n    mk = cp.array([d[x] for x in u])[inv].reshape(result.shape)\n#     print(mk.shape)\n    return mk","metadata":{"papermill":{"duration":0.062139,"end_time":"2021-10-28T17:40:34.493003","exception":false,"start_time":"2021-10-28T17:40:34.430864","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-12-07T08:15:50.310422Z","iopub.execute_input":"2021-12-07T08:15:50.31069Z","iopub.status.idle":"2021-12-07T08:15:50.319393Z","shell.execute_reply.started":"2021-12-07T08:15:50.310662Z","shell.execute_reply":"2021-12-07T08:15:50.318611Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def does_overlap(mask, other_masks):\n    for other_mask in other_masks:\n        if np.sum(np.logical_and(mask, other_mask)) > 0:\n            return True\n    return False\n\n\ndef remove_overlapping_pixels(mask, other_masks):\n    for other_mask in other_masks:\n        if np.sum(np.logical_and(mask, other_mask)) > 0:\n            print(\"Overlap detected\")\n            mask[np.logical_and(mask, other_mask)] = 0\n    return mask","metadata":{"papermill":{"duration":0.063539,"end_time":"2021-10-28T17:40:34.610553","exception":false,"start_time":"2021-10-28T17:40:34.547014","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-12-07T08:15:50.320706Z","iopub.execute_input":"2021-12-07T08:15:50.320994Z","iopub.status.idle":"2021-12-07T08:15:50.328338Z","shell.execute_reply.started":"2021-12-07T08:15:50.320958Z","shell.execute_reply":"2021-12-07T08:15:50.327675Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_img_and_mask(img_path, annotation, width, height):\n    \"\"\" Capture the relevant image array as well as the image mask \"\"\"\n    img_mask = np.zeros((height, width), dtype=np.uint8)\n    for i, annot in enumerate(annotation): \n        img_mask = np.where(rle_decode(annot, (height, width))!=0, i, img_mask)\n    img = cv2.imread(img_path)[..., ::-1]\n    return img[..., 0], img_mask\n\ndef plot_img_and_mask(img, mask, invert_img=True, boost_contrast=True):\n    \"\"\" Function to take an image and the corresponding mask and plot\n    \n    Args:\n        img (np.arr): 1 channel np arr representing the image of cellular structures\n        mask (np.arr): 1 channel np arr representing the instance masks (incrementing by one)\n        invert_img (bool, optional): Whether or not to invert the base image\n        boost_contrast (bool, optional): Whether or not to boost contrast of the base image\n        \n    Returns:\n        None; Plots the two arrays and overlays them to create a merged image\n    \"\"\"\n    plt.figure(figsize=(20,10))\n    \n    plt.subplot(1,3,1)\n    _img = np.tile(np.expand_dims(img, axis=-1), 3)\n    \n    # Flip black-->white ... white-->black\n    if invert_img:\n        _img = _img.max()-_img\n        \n    if boost_contrast:\n        _img = np.asarray(ImageEnhance.Contrast(Image.fromarray(_img)).enhance(16))\n        \n    plt.imshow(_img)\n    plt.axis(False)\n    plt.title(\"Cell Image\", fontweight=\"bold\")\n    \n    plt.subplot(1,3,2)\n    _mask = np.zeros_like(_img)\n    _mask[..., 0] = mask\n    plt.imshow(mask, cmap='rainbow')\n    plt.axis(False)\n    plt.title(\"Instance Segmentation Mask\", fontweight=\"bold\")\n    \n    merged = cv2.addWeighted(_img, 0.75, np.clip(_mask, 0, 1)*255, 0.25, 0.0,)\n    plt.subplot(1,3,3)\n    plt.imshow(merged)\n    plt.axis(False)\n    plt.title(\"Cell Image w/ Instance Segmentation Mask Overlay\", fontweight=\"bold\")\n    \n    plt.tight_layout()\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2021-12-07T08:15:50.329608Z","iopub.execute_input":"2021-12-07T08:15:50.329868Z","iopub.status.idle":"2021-12-07T08:15:50.341593Z","shell.execute_reply.started":"2021-12-07T08:15:50.329833Z","shell.execute_reply":"2021-12-07T08:15:50.340771Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Model**","metadata":{"papermill":{"duration":0.053488,"end_time":"2021-10-28T17:40:34.718633","exception":false,"start_time":"2021-10-28T17:40:34.665145","status":"completed"},"tags":[]}},{"cell_type":"code","source":"from mmcv import Config\n# cfg = Config.fromfile('/kaggle/working/mmdetection/configs/cascade_rcnn/cascade_mask_rcnn_x101_64x4d_fpn_20e_coco.py')\ncfg = Config.fromfile('/kaggle/working/mmdetection/configs/cascade_rcnn/cascade_mask_rcnn_r50_fpn_20e_coco.py')","metadata":{"papermill":{"duration":0.083816,"end_time":"2021-10-28T17:40:34.857025","exception":false,"start_time":"2021-10-28T17:40:34.773209","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-12-07T08:15:50.343Z","iopub.execute_input":"2021-12-07T08:15:50.343342Z","iopub.status.idle":"2021-12-07T08:15:50.379401Z","shell.execute_reply.started":"2021-12-07T08:15:50.343306Z","shell.execute_reply":"2021-12-07T08:15:50.378719Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for head in cfg.model.roi_head.bbox_head:\n    head.num_classes = 3\n    \ncfg.model.roi_head.mask_head.num_classes=3\n\ncfg.test_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(\n        type='MultiScaleFlipAug',\n        img_scale=(1333, 800),\n        flip=False,\n        transforms=[\n            dict(type='Resize', keep_ratio=True),\n            dict(type='RandomFlip'),\n            dict(\n                type='Normalize',\n                mean=[128, 128, 128],\n                std=[11.58, 11.58, 11.58],\n                to_rgb=True),\n            dict(type='Pad', size_divisor=32),\n            dict(type='ImageToTensor', keys=['img']),\n            dict(type='Collect', keys=['img'])\n        ])\n]\n\n# cfg.data.test.pipeline[1].transforms[2] = dict(\n#                                             type='Normalize',\n#                                             mean=[128, 128, 128],\n#                                             std=[11.58, 11.58, 11.58],\n#                                             to_rgb=True)\n\ncfg.data.test.pipeline = cfg.test_pipeline\n\ncfg.model.test_cfg.rcnn.max_per_img = 300\n\n# cfg.load_from = '../input/cascade-mask-rcnn-mmdet/cascade_mask_rcnn_x101_64x4d_fpn_20e_coco_20200512_161033-bdb5126a.pth'\n\ncfg.work_dir = '/kaggle/working/model_output'\n\ncfg.data.samples_per_gpu = 2\ncfg.data.workers_per_gpu = 2\n\ncfg.img_norm_cfg = dict(  \n    mean=[128, 128, 128],  \n    std=[11.58, 11.58, 11.58],  \n    to_rgb=True)\n\ncfg.seed = 0\nset_random_seed(0, deterministic=False)\ncfg.gpu_ids = range(1)\ncfg.fp16 = dict(loss_scale=512.0)\nmeta = dict()\nmeta['config'] = cfg.pretty_text\n\nprint(f'Config:\\n{cfg.pretty_text}')","metadata":{"papermill":{"duration":0.784288,"end_time":"2021-10-28T17:40:35.695074","exception":false,"start_time":"2021-10-28T17:40:34.910786","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-12-07T08:15:50.380595Z","iopub.execute_input":"2021-12-07T08:15:50.380829Z","iopub.status.idle":"2021-12-07T08:15:51.552013Z","shell.execute_reply.started":"2021-12-07T08:15:50.380794Z","shell.execute_reply":"2021-12-07T08:15:51.551317Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Inference**","metadata":{"papermill":{"duration":0.0544,"end_time":"2021-10-28T17:40:35.805148","exception":false,"start_time":"2021-10-28T17:40:35.750748","status":"completed"},"tags":[]}},{"cell_type":"code","source":"confidence_thresholds = {0: 0.25, 1: 0.55, 2: 0.35}","metadata":{"execution":{"iopub.status.busy":"2021-12-07T08:15:51.553007Z","iopub.execute_input":"2021-12-07T08:15:51.553212Z","iopub.status.idle":"2021-12-07T08:15:51.557642Z","shell.execute_reply.started":"2021-12-07T08:15:51.553187Z","shell.execute_reply":"2021-12-07T08:15:51.556933Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"segms = []\nfiles = []","metadata":{"papermill":{"duration":0.063514,"end_time":"2021-10-28T17:40:36.292327","exception":false,"start_time":"2021-10-28T17:40:36.228813","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-12-07T08:15:51.55891Z","iopub.execute_input":"2021-12-07T08:15:51.559708Z","iopub.status.idle":"2021-12-07T08:15:51.566715Z","shell.execute_reply.started":"2021-12-07T08:15:51.55967Z","shell.execute_reply":"2021-12-07T08:15:51.565976Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = init_detector(cfg, '../input/mmdetection-neuron-training/finetune_output/epoch_3.pth')\nfor file in sorted(os.listdir('../input/sartorius-cell-instance-segmentation/test')):\n    img = mmcv.imread('../input/sartorius-cell-instance-segmentation/test/' + file)\n    result = inference_detector(model, img)\n    show_result_pyplot(model, img, result)\n    previous_masks = []\n    for i, classe in enumerate(result[0]):\n        if classe.shape != (0, 5):\n            bbs = classe\n            sgs = result[1][i]\n            for bb, sg in zip(bbs,sgs):\n                box = bb[:4]\n                cnf = bb[4]\n                if cnf >= confidence_thresholds[i]:\n                    mask = get_mask_from_result(sg)\n                    mask = remove_overlapping_pixels(mask, previous_masks)\n                    previous_masks.append(mask)\n\n    for mk in previous_masks:\n            rle_mask = rle_encoding(mk)\n            segms.append(rle_mask)\n            files.append(str(file.split('.')[0]))","metadata":{"papermill":{"duration":54.072416,"end_time":"2021-10-28T17:41:30.419105","exception":false,"start_time":"2021-10-28T17:40:36.346689","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-12-07T08:15:51.567997Z","iopub.execute_input":"2021-12-07T08:15:51.568793Z","iopub.status.idle":"2021-12-07T08:16:06.314978Z","shell.execute_reply.started":"2021-12-07T08:15:51.568755Z","shell.execute_reply":"2021-12-07T08:16:06.314125Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"indexes = []\nfor i, segm in enumerate(segms):\n    if segm == '':\n        indexes.append(i)","metadata":{"execution":{"iopub.status.busy":"2021-12-07T08:16:06.316343Z","iopub.execute_input":"2021-12-07T08:16:06.316591Z","iopub.status.idle":"2021-12-07T08:16:06.320245Z","shell.execute_reply.started":"2021-12-07T08:16:06.316556Z","shell.execute_reply":"2021-12-07T08:16:06.319387Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for element in sorted(indexes, reverse = True):\n    del segms[element]\n    del files[element]","metadata":{"execution":{"iopub.status.busy":"2021-12-07T08:16:06.321526Z","iopub.execute_input":"2021-12-07T08:16:06.321926Z","iopub.status.idle":"2021-12-07T08:16:06.330469Z","shell.execute_reply.started":"2021-12-07T08:16:06.321898Z","shell.execute_reply":"2021-12-07T08:16:06.329711Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"files = pd.Series(files, name='id')\npreds = pd.Series(segms, name='predicted')","metadata":{"papermill":{"duration":0.111268,"end_time":"2021-10-28T17:41:31.473362","exception":false,"start_time":"2021-10-28T17:41:31.362094","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-12-07T08:16:06.331172Z","iopub.execute_input":"2021-12-07T08:16:06.331373Z","iopub.status.idle":"2021-12-07T08:16:06.346763Z","shell.execute_reply.started":"2021-12-07T08:16:06.331351Z","shell.execute_reply":"2021-12-07T08:16:06.34605Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds","metadata":{"execution":{"iopub.status.busy":"2021-12-07T08:16:06.348494Z","iopub.execute_input":"2021-12-07T08:16:06.348707Z","iopub.status.idle":"2021-12-07T08:16:06.358611Z","shell.execute_reply.started":"2021-12-07T08:16:06.348684Z","shell.execute_reply":"2021-12-07T08:16:06.357932Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df = pd.concat([files, preds], axis=1)","metadata":{"papermill":{"duration":0.103799,"end_time":"2021-10-28T17:41:32.152958","exception":false,"start_time":"2021-10-28T17:41:32.049159","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-12-07T08:16:06.360217Z","iopub.execute_input":"2021-12-07T08:16:06.360461Z","iopub.status.idle":"2021-12-07T08:16:06.368716Z","shell.execute_reply.started":"2021-12-07T08:16:06.360422Z","shell.execute_reply":"2021-12-07T08:16:06.367952Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df.to_csv('submission.csv', index=False)","metadata":{"papermill":{"duration":0.108025,"end_time":"2021-10-28T17:41:32.837992","exception":false,"start_time":"2021-10-28T17:41:32.729967","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-12-07T08:16:06.369894Z","iopub.execute_input":"2021-12-07T08:16:06.370331Z","iopub.status.idle":"2021-12-07T08:16:06.380979Z","shell.execute_reply.started":"2021-12-07T08:16:06.370294Z","shell.execute_reply":"2021-12-07T08:16:06.38031Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df","metadata":{"papermill":{"duration":0.128241,"end_time":"2021-10-28T17:41:33.057781","exception":false,"start_time":"2021-10-28T17:41:32.92954","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-12-07T08:16:06.38283Z","iopub.execute_input":"2021-12-07T08:16:06.383088Z","iopub.status.idle":"2021-12-07T08:16:06.400511Z","shell.execute_reply.started":"2021-12-07T08:16:06.383063Z","shell.execute_reply":"2021-12-07T08:16:06.399662Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"shutil.rmtree('/kaggle/working/mmdetection')","metadata":{"papermill":{"duration":0.169468,"end_time":"2021-10-28T17:41:35.314035","exception":false,"start_time":"2021-10-28T17:41:35.144567","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-12-07T08:16:06.40154Z","iopub.execute_input":"2021-12-07T08:16:06.401748Z","iopub.status.idle":"2021-12-07T08:16:06.463969Z","shell.execute_reply.started":"2021-12-07T08:16:06.401718Z","shell.execute_reply":"2021-12-07T08:16:06.463044Z"},"trusted":true},"execution_count":null,"outputs":[]}]}