{"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":"# 1. generate coco format data","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19"}},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nfrom tqdm.notebook import tqdm\nimport json, itertools","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:28:19.425352Z","iopub.execute_input":"2021-11-26T06:28:19.425686Z","iopub.status.idle":"2021-11-26T06:28:19.498043Z","shell.execute_reply.started":"2021-11-26T06:28:19.425599Z","shell.execute_reply":"2021-11-26T06:28:19.497404Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#decode\ndef rle2mask(rle, shape):\n    s = rle.split()\n    start, length = [np.asarray(x, dtype = int) for x in (s[0::2], s[1::2])]\n    start -= 1\n    end = start + length\n    img = np.zeros(shape[0]*shape[1], dtype = np.uint8)\n    for l, h in zip(start, end):\n        img[l:h] = 1\n    return img.reshape(shape)\n\n#encode\ndef binarymask2rle(binary_mask):\n    rle = {'counts':[], 'size':list(binary_mask.shape)}\n    counts = rle.get('counts')\n    for i, (val, elements) in enumerate(itertools.groupby(binary_mask.ravel(order = 'F'))):\n        if i == 0 and val == 1:\n            counts.append(0)\n        counts.append(len(list(elements)))\n    return rle\n\n#coco_format\ndef gen_coco_data(train_df):\n    cat_ids = {name:id+1 for id, name in enumerate(train_df.cell_type.unique())}    \n    cats =[{'name':name, 'id':id} for name,id in cat_ids.items()]\n    images = [{'id':id, 'width':row.width, 'height':row.height, 'file_name':f'train/{id}.png'} for id,row in train_df.groupby('id').agg('first').iterrows()]\n    annotations=[]\n    for idx, row in tqdm(train_df.iterrows()):\n        mk = rle2mask(row.annotation, (row.height, row.width))\n        ys, xs = np.where(mk)\n        x1, x2 = min(xs), max(xs)\n        y1, y2 = min(ys), max(ys)\n        enc =binarymask2rle(mk)\n        seg = {\n            'segmentation':enc, \n            'bbox': [int(x1), int(y1), int(x2-x1+1), int(y2-y1+1)],\n            'area': int(np.sum(mk)),\n            'image_id':row.id, \n            'category_id':cat_ids[row.cell_type], \n            'iscrowd':0, \n            'id':idx\n        }\n        annotations.append(seg)\n    return {'categories':cats, 'images':images,'annotations':annotations}","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## run it on first three images for demonstration:\ntrain_df = pd.read_csv('../input/sartorius-cell-instance-segmentation/train.csv')\nall_ids = train_df.id.unique()\ntrain_sample = train_df[train_df.id.isin(all_ids)]\nroot = gen_coco_data(train_sample)\n\nwith open('annotations_sample.json', 'w', encoding='utf-8') as f:\n    json.dump(root, f, ensure_ascii=True, indent=4)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2. train with mmdet","metadata":{}},{"cell_type":"markdown","source":"*2.1. install mmcv and mmdet*","metadata":{}},{"cell_type":"code","source":"import datetime\nimport os\nimport re\nimport fnmatch\nfrom PIL import Image\nimport matplotlib.pyplot as plt\nimport random\n\n!pip install torch==1.7.0+cu101 torchvision==0.8.1+cu101 torchaudio==0.7.0 -f https://download.pytorch.org/whl/torch_stable.html\n!pip install mmcv-full -f https://download.openmmlab.com/mmcv/dist/cu101/torch1.7.0/index.html\n\n%cd ..\n!git clone https://github.com/open-mmlab/mmdetection.git\n%cd mmdetection\n!pip install -r requirements/build.txt\n!pip install -v -e . \n%cd ../working","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:28:28.491367Z","iopub.execute_input":"2021-11-26T06:28:28.491689Z","iopub.status.idle":"2021-11-26T06:31:28.09496Z","shell.execute_reply.started":"2021-11-26T06:28:28.49166Z","shell.execute_reply":"2021-11-26T06:31:28.094038Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"*\n\n\n\n\n\n*\n*2.2. copy cfg of task to mmdet/configs*","metadata":{}},{"cell_type":"code","source":"!cp -r /kaggle/input/sartorius-cfg /kaggle/mmdetection/configs/sartorius-cfg","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:31:32.21136Z","iopub.execute_input":"2021-11-26T06:31:32.211633Z","iopub.status.idle":"2021-11-26T06:31:32.881856Z","shell.execute_reply.started":"2021-11-26T06:31:32.211601Z","shell.execute_reply":"2021-11-26T06:31:32.880936Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls -l ../mmdetection/configs/sartorius-cfg/","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:31:34.996467Z","iopub.execute_input":"2021-11-26T06:31:34.99723Z","iopub.status.idle":"2021-11-26T06:31:35.650861Z","shell.execute_reply.started":"2021-11-26T06:31:34.99719Z","shell.execute_reply":"2021-11-26T06:31:35.650057Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#rm -rf /kaggle/mmdetection/configs/cell_seg_cfg","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%writefile /kaggle/mmdetection/configs/sartorius-cfg/mask_rcnn_r50_fpn_1x_coco.py\n\n_base_ = [\n    '../_base_/models/mask_rcnn_r50_fpn.py',\n    '../_base_/datasets/coco_instance.py',\n    '../_base_/schedules/schedule_1x.py', '../_base_/default_runtime.py'\n]\n\nmodel = dict(roi_head=dict(bbox_head=dict(num_classes=3), mask_head=dict(num_classes=3)))\n\n# dataset settings\ndataset_type = 'CocoDataset'\nclasses = ('shsy5y', 'astro', 'cort')\n\ndata_root = '/kaggle/input/'\nimg_norm_cfg = dict(\n    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)\ntrain_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='LoadAnnotations', with_bbox=True, with_mask=True),\n    dict(type='Resize', img_scale=(1333, 800), keep_ratio=True),\n    dict(type='RandomFlip', flip_ratio=0.5),\n    dict(type='Normalize', **img_norm_cfg),\n    dict(type='Pad', size_divisor=32),\n    dict(type='DefaultFormatBundle'),\n    dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels', 'gt_masks']),\n]\ntest_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(type='Normalize', **img_norm_cfg),\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=2,\n    workers_per_gpu=2,\n    train=dict(\n        type=dataset_type,\n        classes = classes,\n        ann_file=data_root + 'sartorius-cell-instance-segmentation-coco/annotations_train.json',\n        img_prefix=data_root + 'sartorius-cell-instance-segmentation/',\n        pipeline=train_pipeline),\n    val=dict(\n        type=dataset_type,\n        classes = classes,\n        ann_file=data_root + 'sartorius-cell-instance-segmentation-coco/annotations_val.json',\n        img_prefix=data_root + 'sartorius-cell-instance-segmentation/',\n        pipeline=test_pipeline),\n    test=dict(\n        type=dataset_type,\n        classes = classes,\n        ann_file=data_root + 'sartorius-cell-instance-segmentation-coco/annotations_val.json',\n        img_prefix=data_root + 'sartorius-cell-instance-segmentation/',\n        pipeline=test_pipeline))\n\nevaluation = dict(metric=['bbox', 'segm'])\n\noptimizer = dict(type='SGD', lr=0.005, momentum=0.9, weight_decay=0.0001)\n","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:39:42.775397Z","iopub.execute_input":"2021-11-26T06:39:42.775726Z","iopub.status.idle":"2021-11-26T06:39:42.78414Z","shell.execute_reply.started":"2021-11-26T06:39:42.77568Z","shell.execute_reply":"2021-11-26T06:39:42.783434Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"*\n\n\n*\n*2.3. start training*","metadata":{}},{"cell_type":"code","source":"conf_name = \"mask_rcnn_r50_fpn_1x_coco\"\nconfig = f'configs/sartorius-cfg/{conf_name}.py'\n# using --no-validate to avoid some errors for custom dataset metrics\nadditional_conf = '--cfg-options'\nadditional_conf  += f' work_dir=../working/mask_rcnn_r50_fpn_1x'\n#additional_conf  += f' data.train.ann_file = /kaggle/input/data-ann/ann/all_ann.json'\nadditional_conf += f' optimizer.lr=0.0025'\ncmd = f'bash -x tools/dist_train.sh {config} 1 {additional_conf}'\n!cd ../mmdetection;  {cmd}","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:39:46.568266Z","iopub.execute_input":"2021-11-26T06:39:46.568969Z","iopub.status.idle":"2021-11-26T08:48:18.527503Z","shell.execute_reply.started":"2021-11-26T06:39:46.568915Z","shell.execute_reply":"2021-11-26T08:48:18.526658Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}