{"cells":[{"metadata":{},"cell_type":"markdown","source":"## Install packages"},{"metadata":{"trusted":true},"cell_type":"code","source":"! pip install ../input/mmdetectionv260/addict-2.4.0-py3-none-any.whl\n! pip install ../input/mmdetectionv260/mmcv_full-latesttorch1.6.0cu102-cp37-cp37m-manylinux1_x86_64.whl\n! pip install ../input/mmdetectionv260/mmpycocotools-12.0.3-cp37-cp37m-linux_x86_64.whl\n! pip install ../input/mmdetection-package/mmdet-2.7.0-py3-none-any.whl","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"! pip install ../input/mmdetection-package/torch-1.6.0-cp37-cp37m-linux_x86_64.whl","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#! pip install ../input/mmdetection-package/albumentations-0.5.2-py3-none-any.whl","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"! cp -r ../input/mmdetection-package/mmdetection/mmdetection/ ./mmdetection","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"! cp -r ../input/mmdetection-wheat-models/attention_stage1/faster_rcnn_r50_fpn_attention_0010_dcn_albu_1x4_1x_bWheat_kaggle.py ./config.py\n! cp -r ../input/mmdetection-wheat-models/attention_stage1/epoch_12.pth ./model.pth","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"CONFIG_FILE = './config.py'\nCHECKPOINT_PATH = './model.pth'\nTEST_IMG_DIR = '../input/global-wheat-detection/test'","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Import packages"},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\nimport json\nimport pandas as pd\nimport numpy as np\nimport cv2\n\nfrom tqdm import tqdm\n\nimport torch\nimport mmcv\nfrom mmdet.apis import init_detector, inference_detector","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Pseudo labeling"},{"metadata":{},"cell_type":"markdown","source":"### Create test annotations"},{"metadata":{"trusted":true},"cell_type":"code","source":"TEST_ANN_FILE = './annotation_test.json'\n\nanns = []\nfor img_name in tqdm(os.listdir(TEST_IMG_DIR)):\n    if not img_name.endswith('.jpg'):\n        continue\n    anns.append(dict(filename=img_name, boxes=[]))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"images = []\nannotations = []\nobj_count = 0\nfor idx, v in tqdm(enumerate(anns)):\n    filename = v['filename']\n    img_path = os.path.join(TEST_IMG_DIR, filename)\n    height, width = mmcv.imread(img_path).shape[:2]\n\n    images.append(dict(\n        id=idx,\n        file_name=filename,\n        height=height,\n        width=width))\n\n    for box in v['boxes']:\n        data_anno = dict(\n            image_id=idx,\n            id=obj_count,\n            category_id=int(box['label']),\n            bbox=[box['left'], box['top'], box['width'], box['height']],\n            area=box['width'] * box['height'],\n            iscrowd=0)\n\n        annotations.append(data_anno)\n        obj_count += 1\n\ncoco_format_json = dict(\n    images=images,\n    annotations=annotations,\n    categories=[dict(id=0, name='wheat_head')])\nmmcv.dump(coco_format_json, TEST_ANN_FILE)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Modify test config"},{"metadata":{"trusted":true},"cell_type":"code","source":"test_config = './test_config.py'\ncfg = mmcv.Config.fromfile(CONFIG_FILE)\ncfg.data.test.ann_file = TEST_ANN_FILE\n\nwith open(test_config, 'w') as f:\n    f.write(cfg.pretty_text)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"! python ./mmdetection/tools/test.py {test_config} {CHECKPOINT_PATH} --format-only --eval-options jsonfile_prefix=./result","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"with open('./result.bbox.json', 'r') as f1, open(TEST_ANN_FILE, 'r') as f2:\n    result_info = json.load(f1)\n    annotations_info = json.load(f2)\n    \n    for i, ann in tqdm(enumerate(result_info)):\n        if ann['score'] < 0.5:\n            continue\n        annotation = ann\n        annotation['id'] = i\n        annotation['area'] = ann['bbox'][2] * ann['bbox'][3]\n        annotation['iscrowd'] = 0\n        annotations_info['annotations'].append(annotation)\n    \n    mmcv.dump(annotations_info, './annotation_new.json')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Train with pseudo label"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_config = './train_config.py'\ncfg = mmcv.Config.fromfile(CONFIG_FILE)\ncfg.data.samples_per_gpu = 8\ncfg.data.workers_per_gpu = 4\ncfg.data.train.ann_file = './annotation_new.json'\ncfg.data.train.img_prefix = TEST_IMG_DIR\ncfg.data.train.pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(\n        type='Albu',\n        transforms=cfg.albu_train_transforms,\n        bbox_params=dict(\n            type='BboxParams',\n            format='pascal_voc',\n            label_fields=['gt_labels'],\n            min_visibility=0.3,\n            filter_lost_elements=True),\n        keymap=dict(\n            img='image',\n            gt_bboxes='bboxes'),\n        update_pad_shape=False,\n        skip_img_without_anno=True),\n    dict(type='Resize', img_scale=(1024, 1024), keep_ratio=True), # Change scale\n    dict(type='RandomFlip', flip_ratio=0.5),\n    dict(type='Normalize', **cfg.img_norm_cfg),\n    dict(type='Pad', size_divisor=32),\n    dict(type='DefaultFormatBundle'),\n    dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels']),\n]\ncfg.optimizer = dict(type='SGD', lr=0.005, momentum=0.9, weight_decay=0.0001)\ncfg.lr_config = dict(\n    policy='fixed',\n    warmup=None\n)\ncfg.total_epochs = 2\ncfg.model.pretrained = None\ncfg.load_from = CHECKPOINT_PATH\ncfg.log_config = dict(\n    interval=1,\n    hooks=[\n        dict(type='TextLoggerHook')\n    ])\n\nwith open(train_config, 'w') as f:\n    f.write(cfg.pretty_text)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"! python ./mmdetection/tools/train.py {train_config} --no-validate --work-dir ./pseudo","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"! ls ./pseudo","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Make prediction"},{"metadata":{"trusted":true},"cell_type":"code","source":"def format_prediction_string(boxes, scores):\n    pred_strings = []\n    for j in zip(scores, boxes):\n        pred_strings.append(\"{0:.4f} {1} {2} {3} {4}\".format(j[0], j[1][0], j[1][1], j[1][2], j[1][3]))\n    return \" \".join(pred_strings)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"device = 'cuda:0' if torch.cuda.is_available() else 'cpu'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"config = mmcv.Config.fromfile(CONFIG_FILE)\nconfig.model.pretrained = None\nconfig.data.test.pipeline[1]['img_scale'] = [(1280, 1280), (1408, 1408)]\n\nmodel = init_detector(config, './pseudo/epoch_1.pth', device=device)\nmodel.eval()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"results = []\nscore_threshold = 0.3\nwith torch.no_grad():\n    for img_name in tqdm(os.listdir(TEST_IMG_DIR)):\n        img_pth = os.path.join(TEST_IMG_DIR, img_name)\n        image = mmcv.imread(img_pth)\n        \n        # Predict with original image\n        result = inference_detector(model, image)\n        boxes = result[0][:, :4]\n        scores = result[0][:, 4]\n        if len(boxes) > 0:\n            boxes[:, 2] = boxes[:, 2] - boxes[:, 0]\n            boxes[:, 3] = boxes[:, 3] - boxes[:, 1]\n        \n        # Remove prediction with score under threshold\n        boxes = boxes[scores >= score_threshold]\n        scores = scores[scores >= score_threshold]\n\n        result = {\n            'image_id': img_name[:-4],\n            'PredictionString': format_prediction_string(boxes, scores)\n        }\n\n        results.append(result)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nsize = 300\nidx =-1\nfont = cv2.FONT_HERSHEY_SIMPLEX \nimage = cv2.imread(img_pth, cv2.IMREAD_COLOR)\nfontScale = 1\ncolor = (255, 0, 0)\n\nthickness = 2\nfor b, s in zip(boxes, scores):\n    b = [int(a) for a in b]\n    image = cv2.rectangle(image, (b[0],b[1]), (b[0]+b[2],b[1]+b[3]), (255,0,0), 1) \n    image = cv2.putText(image, '{:.2}'.format(s), (b[0]+np.random.randint(20),b[1]), font,  \n                   fontScale, color, thickness, cv2.LINE_AA)\nplt.figure(figsize=[20,20])\nplt.imshow(image[:,:,::-1])\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df = pd.DataFrame(results, columns=['image_id', 'PredictionString'])\ntest_df.to_csv('submission.csv', index=False)\ntest_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","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}