{"cells":[{"metadata":{},"cell_type":"markdown","source":"### **This is a baseline using mmdetection cascade rcnn.**\n#### I used the original image size but convert the dicom to jpg, this action may need over 30GB(bs3) memmory of your GPU, I used 2 Tesla A100(40GB).\n#### First you need to convert the dataset to coco format, all the converting codes you can find in my github: https://github.com/Klawens/dataset_prepare\n### If this works on your machine, you can get over 0.260, the codes I commented out should work, but I'm not sure, if you tested it, welcome to leave a comment."},{"metadata":{"trusted":true},"cell_type":"code","source":"fp16 = dict(loss_scale=512.)\nmodel = dict(\n    type='CascadeRCNN',\n    #pretrained='open-mmlab://resnext101_64x4d',\n    pretrained=None,\n    backbone=dict(\n        type='ResNeXt',\n        depth=101,\n        num_stages=4,\n        out_indices=(0, 1, 2, 3),\n        frozen_stages=1,\n        norm_cfg=dict(type='SyncBN', requires_grad=True),\n        # norm_cfg = dict(type='GN', num_groups=32, requires_grad=True),  # not working\n        norm_eval=True,\n        style='pytorch',\n        groups=64,\n        base_width=4,\n        # dcn=dict(type='DCNv2', deform_groups=1, fallback_on_stride=False),\n        # stage_with_dcn=(False, True, True, True)\n        ),\n    neck=dict(\n        type='FPN',\n        in_channels=[256, 512, 1024, 2048],\n        out_channels=256,\n        num_outs=5),\n    rpn_head=dict(\n        type='RPNHead',\n        in_channels=256,\n        feat_channels=256,\n        anchor_generator=dict(\n            type='AnchorGenerator',\n            scales=[8],\n            ratios=[0.5, 1.0, 2.0, 3.0, 5.0],\n            strides=[4, 8, 16, 32, 64]),\n        bbox_coder=dict(\n            type='DeltaXYWHBBoxCoder',\n            target_means=[0.0, 0.0, 0.0, 0.0],\n            target_stds=[1.0, 1.0, 1.0, 1.0]),\n        loss_cls=dict(\n            type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0),\n        loss_bbox=dict(\n            type='SmoothL1Loss', beta=0.1111111111111111, loss_weight=1.0)),\n        #reg_decoded_bbox=True,\n        #loss_bbox=dict(type='GIoULoss', loss_weight=5.0)),\n    roi_head=dict(\n        type='CascadeRoIHead',\n        num_stages=3,\n        stage_loss_weights=[1, 0.5, 0.25],\n        bbox_roi_extractor=dict(\n            type='SingleRoIExtractor',\n            roi_layer=dict(type='RoIAlign', output_size=7, sampling_ratio=0),\n            out_channels=256,\n            featmap_strides=[4, 8, 16, 32]),\n        bbox_head=[\n            dict(\n                type='Shared2FCBBoxHead',\n                in_channels=256,\n                fc_out_channels=1024,\n                roi_feat_size=7,\n                num_classes=14,\n                bbox_coder=dict(\n                    type='DeltaXYWHBBoxCoder',\n                    target_means=[0.0, 0.0, 0.0, 0.0],\n                    target_stds=[0.1, 0.1, 0.2, 0.2]),\n                reg_class_agnostic=True,\n                loss_cls=dict(\n                    type='CrossEntropyLoss',\n                    use_sigmoid=False,\n                    loss_weight=1.0),\n                loss_bbox=dict(type='SmoothL1Loss', beta=1.0,\n                               loss_weight=1.0)),\n                #reg_decoded_bbox=True,\n                #loss_bbox=dict(type='GIoULoss', loss_weight=5.0)),\n            dict(\n                type='Shared2FCBBoxHead',\n                in_channels=256,\n                fc_out_channels=1024,\n                roi_feat_size=7,\n                num_classes=14,\n                bbox_coder=dict(\n                    type='DeltaXYWHBBoxCoder',\n                    target_means=[0.0, 0.0, 0.0, 0.0],\n                    target_stds=[0.05, 0.05, 0.1, 0.1]),\n                reg_class_agnostic=True,\n                loss_cls=dict(\n                    type='CrossEntropyLoss',\n                    use_sigmoid=False,\n                    loss_weight=1.0),\n                loss_bbox=dict(type='SmoothL1Loss', beta=1.0,\n                               loss_weight=1.0)),\n                #reg_decoded_bbox=True,\n                #loss_bbox=dict(type='GIoULoss', loss_weight=5.0)),\n            dict(\n                type='Shared2FCBBoxHead',\n                in_channels=256,\n                fc_out_channels=1024,\n                roi_feat_size=7,\n                num_classes=14,\n                bbox_coder=dict(\n                    type='DeltaXYWHBBoxCoder',\n                    target_means=[0.0, 0.0, 0.0, 0.0],\n                    target_stds=[0.033, 0.033, 0.067, 0.067]),\n                reg_class_agnostic=True,\n                loss_cls=dict(\n                    type='CrossEntropyLoss',\n                    use_sigmoid=False,\n                    loss_weight=1.0),\n                loss_bbox=dict(type='SmoothL1Loss', beta=1.0, loss_weight=1.0))\n                #reg_decoded_bbox=True,\n                #loss_bbox=dict(type='GIoULoss', loss_weight=5.0))\n        ]))\ntrain_cfg = dict(\n    rpn=dict(\n        assigner=dict(\n            type='MaxIoUAssigner',\n            pos_iou_thr=0.7,\n            neg_iou_thr=0.3,\n            min_pos_iou=0.3,\n            match_low_quality=True,\n            ignore_iof_thr=-1),\n        sampler=dict(\n            type='RandomSampler',\n            num=256,\n            pos_fraction=0.5,\n            neg_pos_ub=-1,\n            add_gt_as_proposals=False),\n        allowed_border=0,\n        pos_weight=-1,\n        debug=False),\n    rpn_proposal=dict(\n        nms_across_levels=False,\n        nms_pre=2000,\n        nms_post=2000,\n        max_num=2000,\n        nms_thr=0.7,\n        min_bbox_size=0),\n    rcnn=[\n        dict(\n            assigner=dict(\n                type='MaxIoUAssigner',\n                pos_iou_thr=0.5,\n                neg_iou_thr=0.5,\n                min_pos_iou=0.5,\n                match_low_quality=False,\n                ignore_iof_thr=-1),\n            sampler=dict(\n                _delete_=True,\n                type='CombinedSampler',\n                num=512,\n                pos_fraction=0.25,\n                add_gt_as_proposals=True,\n                pos_sampler=dict(type='InstanceBalancedPosSampler'),\n                neg_sampler=dict(\n                    type='IoUBalancedNegSampler',\n                    floor_thr=-1,\n                    floor_fraction=0,\n                    num_bins=3)),\n                pos_weight=-1,\n                debug=False),\n        dict(\n            assigner=dict(\n                type='MaxIoUAssigner',\n                pos_iou_thr=0.6,\n                neg_iou_thr=0.6,\n                min_pos_iou=0.6,\n                match_low_quality=False,\n                ignore_iof_thr=-1),\n            sampler=dict(\n                _delete_=True,\n                type='CombinedSampler',\n                num=512,\n                pos_fraction=0.25,\n                add_gt_as_proposals=True,\n                pos_sampler=dict(type='InstanceBalancedPosSampler'),\n                neg_sampler=dict(\n                    type='IoUBalancedNegSampler',\n                    floor_thr=-1,\n                    floor_fraction=0,\n                    num_bins=3)),\n                pos_weight=-1,\n                debug=False),\n        dict(\n            assigner=dict(\n                type='MaxIoUAssigner',\n                pos_iou_thr=0.7,\n                neg_iou_thr=0.7,\n                min_pos_iou=0.7,\n                match_low_quality=False,\n                ignore_iof_thr=-1),\n            sampler=dict(\n                _delete_=True,\n                type='CombinedSampler',\n                num=512,\n                pos_fraction=0.25,\n                add_gt_as_proposals=True,\n                pos_sampler=dict(type='InstanceBalancedPosSampler'),\n                neg_sampler=dict(\n                    type='IoUBalancedNegSampler',\n                    floor_thr=-1,\n                    floor_fraction=0,\n                    num_bins=3)),\n                pos_weight=-1,\n                debug=False)\n    ])\ntest_cfg = dict(\n    rpn=dict(\n        nms_across_levels=False,\n        nms_pre=1000,\n        nms_post=1000,\n        max_num=1000,\n        nms_thr=0.7,\n        min_bbox_size=0),\n    rcnn=dict(\n        score_thr=0.01,\n        nms=dict(type='nms', iou_threshold=0.5),\n        max_per_img=300))\ndataset_type = 'CocoDataset'\ndata_root = 'data/'\nimg_norm_cfg = dict(\n    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)\nalbu_train_transforms = [\n    dict(type='RandomRotate90', p=0.5),\n    #dict(type='InvertImg', p=0.5),\n    ]\ntrain_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='LoadAnnotations', with_bbox=True, with_mask=False),\n    dict(type='Resize', img_scale=[(2200, 2200), (3000, 3000)], keep_ratio=True),\n    dict(type='RandomFlip', flip_ratio=0.5),\n    #dict(type='RandomFlip', flip_ratio=0.5, direction='horizontal'),\n    #dict(type='RandomFlip', flip_ratio=0.5, direction='vertical'),\n    #dict(type='BBoxJitter', min=0.9, max=1.1),\n    #dict(type='MixUp', p=0.5, lambd=0.5),\n    dict(\n        type='Normalize',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        to_rgb=True),\n    dict(\n        type='Albu',\n        transforms=albu_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=dict(img='image', gt_bboxes='bboxes'),\n        update_pad_shape=False,\n        skip_img_without_anno=True),\n    dict(type='Pad', size_divisor=32),\n    dict(type='DefaultFormatBundle'),\n    dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels'])\n]\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(\n        type='MultiScaleFlipAug',\n        img_scale=[(test), (youself)],\n        flip=False,\n        transforms=[\n            dict(type='Resize', keep_ratio=True),\n            dict(type='RandomFlip'),\n            dict(\n                type='Normalize',\n                mean=[123.675, 116.28, 103.53],\n                std=[58.395, 57.12, 57.375],\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]\ndata = dict(\n    samples_per_gpu=3,\t# 2 gpus, real batch_size=6\n    workers_per_gpu=6,\n    train=dict(\n        type='RepeatDataset',\n        times=3,\n        dataset=dict(\n            type='CocoDataset',\n            ann_file=data_root+'annotations/instances_train2017.json',\n            img_prefix=data_root+'images/train2017/',\n            pipeline=train_pipeline)),\n    val=dict(\n        type='CocoDataset',\n        ann_file=data_root+'annotations/ray_val.json',\n        img_prefix=data_root+'images/train2017/',\n        pipeline=test_pipeline),\n    test=dict(\n        type='CocoDataset',\n        ann_file=data_root+'annotations/instances_test2017.json',\n        img_prefix=data_root+'images/test2017/',\n        pipeline=test_pipeline))\nevaluation = dict(interval=1, metric='bbox')\noptimizer = dict(type='SGD', lr=0.015, momentum=0.9, weight_decay=0.0001)\noptimizer_config = dict(grad_clip=None)\nlr_config = dict(\n    policy='step',\n    warmup='linear',\n    warmup_iters=500,\n    warmup_ratio=0.001,\n    step=[8, 11])\ntotal_epochs = 12\ncheckpoint_config = dict(interval=1)\nlog_config = dict(interval=50, hooks=[dict(type='TextLoggerHook'),\n    dict(type='TensorboardLoggerHook')])\ndist_params = dict(backend='nccl')\nlog_level = 'INFO'\nload_from = None\n#load_from = '0.257.pth'\n#load_from = 'x101/epoch_12.pth'\nresume_from = None\nworkflow = [('train', 1)]\nwork_dir = './x101'\ngpu_ids = range(0, 1)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# MixUp code(mmdet/datasets/pipelines/transforms.py)\n@PIPELINES.register_module()\nclass MixUp(object):\n    def __init__(self, p=0.3, lambd=0.5):\n        self.lambd = lambd\n        self.p = p\n        self.img2 = None\n        self.boxes2 = None\n        self.labels2= None\n\n    def __call__(self, results):\n        img1, boxes1, labels1 = [\n            results[k] for k in ('img', 'gt_bboxes', 'gt_labels')\n        ]\n\n\n        if random.random() < self.p and self.img2 is not None and img1.shape[1]==self.img2.shape[1]:\n\n            height = max(img1.shape[0], self.img2.shape[0])\n            width = max(img1.shape[1], self.img2.shape[1])\n            mixup_image = np.zeros([height, width, 3], dtype='float32')\n            mixup_image[:img1.shape[0], :img1.shape[1], :] = img1.astype('float32') * self.lambd\n            mixup_image[:self.img2.shape[0], :self.img2.shape[1], :] += self.img2.astype('float32') * (1. - self.lambd)\n            mixup_image = mixup_image.astype('uint8')\n\n            mixup_boxes = np.vstack((boxes1, self.boxes2))\n            mixup_label = np.hstack((labels1,self.labels2))\n            results['img'] = mixup_image\n            results['gt_bboxes'] = mixup_boxes\n            results['gt_labels'] = mixup_label\n        else:\n            pass\n        \n        self.img2 = img1\n        self.boxes2 = boxes1\n        self.labels2 =  labels1\n        return results","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# BBoxJitter code, same place with above.\n@PIPELINES.register_module()\nclass BBoxJitter(object):\n    \"\"\"\n    bbox jitter\n    Args:\n        min (int, optional): min scale\n        max (int, optional): max scale\n        ## origin w scale\n    \"\"\"\n\n    def __init__(self, min=0, max=2):\n        self.min_scale = min\n        self.max_scale = max\n        self.count = 0\n        ic(\"USE BBOX_JITTER\")\n        ic(min, max)\n\n    def bbox_jitter(self, bboxes, img_shape):\n        \"\"\"Flip bboxes horizontally.\n        Args:\n            bboxes(ndarray): shape (..., 4*k)\n            img_shape(tuple): (height, width)\n        \"\"\"\n        assert bboxes.shape[-1] % 4 == 0\n        if len(bboxes) == 0:\n            return bboxes\n        jitter_bboxes = []\n        for box in bboxes:\n            w = box[2] - box[0]\n            h = box[3] - box[1]\n            center_x = (box[0] + box[2]) / 2\n            center_y = (box[1] + box[3]) / 2\n            scale = np.random.uniform(self.min_scale, self.max_scale)\n            w = w * scale / 2.\n            h = h * scale / 2.\n            xmin = center_x - w\n            ymin = center_y - h\n            xmax = center_x + w\n            ymax = center_y + h\n            box2 = np.array([xmin, ymin, xmax, ymax], dtype=np.float32)\n            jitter_bboxes.append(box2)\n        jitter_bboxes = np.array(jitter_bboxes, dtype=np.float32)\n        jitter_bboxes[:, 0::2] = np.clip(jitter_bboxes[:, 0::2], 0, img_shape[1] - 1)\n        jitter_bboxes[:, 1::2] = np.clip(jitter_bboxes[:, 1::2], 0, img_shape[0] - 1)\n        return jitter_bboxes\n\n    def __call__(self, results):\n        for key in results.get('bbox_fields', []):\n            results[key] = self.bbox_jitter(results[key],\n                                          results['img_shape'])\n        return results\n\n    def __repr__(self):\n        return self.__class__.__name__ + '(bbox_jitter={}-{})'.format(\n            self.min_scale, self.max_scale)","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}