{"cells":[{"metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"!pip install --no-deps '../input/timm-package/timm-0.1.26-py3-none-any.whl' > /dev/null\n!pip install --no-deps '../input/pycocotools/pycocotools-2.0-cp37-cp37m-linux_x86_64.whl' > /dev/null","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"import sys\nsys.path.insert(0, \"../input/timm-efficientdet-pytorch\")\nsys.path.insert(0, \"../input/omegaconf\")\nsys.path.insert(0, \"../input/weightedboxesfusion\")\n\nimport os\nfrom ensemble_boxes import *\nimport torch\nimport random\nimport numpy as np\nimport pandas as pd\nfrom glob import glob\nfrom torch.utils.data import Dataset,DataLoader\nimport albumentations as A\nfrom albumentations.pytorch.transforms import ToTensorV2\nimport cv2\nimport gc\nfrom tqdm import tqdm\nfrom matplotlib import pyplot as plt\nfrom effdet import get_efficientdet_config, EfficientDet, DetBenchEval\nfrom effdet.efficientdet import HeadNet\nfrom sklearn.model_selection import StratifiedKFold\nfrom skopt import gp_minimize, forest_minimize\nfrom skopt.utils import use_named_args\nfrom skopt.plots import plot_objective, plot_evaluations, plot_convergence, plot_regret\nfrom skopt.space import Categorical, Integer, Real\n\nSEED = 42\n\ndef seed_everything(seed):\n    random.seed(seed)\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = True\n\nseed_everything(SEED)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#USE_OPTIMIZE = len(glob(f'../input/global-wheat-detection/test/*.jpg')) == 10\nUSE_OPTIMIZE = True # used for fast inference in submission\nUSE_TTA = True","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def load_net(checkpoint_path):\n    config = get_efficientdet_config('tf_efficientdet_d5')\n    net = EfficientDet(config, pretrained_backbone=False)\n\n    config.num_classes = 1\n    config.image_size = 512\n    net.class_net = HeadNet(config, num_outputs=config.num_classes, norm_kwargs=dict(eps=.001, momentum=.01))\n\n    checkpoint = torch.load(checkpoint_path)\n    net.load_state_dict(checkpoint[\"model_state_dict\"])\n\n    del checkpoint\n    gc.collect()\n\n    net = DetBenchEval(net, config)\n    net.eval();\n    return net.cuda()\n\nif USE_OPTIMIZE:\n    models = [\n        load_net('../input/effdet-fold0/best-checkpoint-023epoch.bin'),\n        load_net('../input/effdet-fold1/best-checkpoint-017epoch.bin')]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# WBF","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"best_final_score = 0.7202\nbest_iou_thr = 0.460\nbest_skip_box_thr = 0.394","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Inference with best barams","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def TTAImage(image, index):\n    image1 = image.copy()\n    if index==0: \n        rotated_image = cv2.rotate(image1, cv2.ROTATE_90_CLOCKWISE)\n        return rotated_image\n    elif index==1:\n        rotated_image2 = cv2.rotate(image1, cv2.ROTATE_90_CLOCKWISE)\n        rotated_image2 = cv2.rotate(rotated_image2, cv2.ROTATE_90_CLOCKWISE)\n        return rotated_image2\n    elif index==2:\n        rotated_image3 = cv2.rotate(image1, cv2.ROTATE_90_CLOCKWISE)\n        rotated_image3 = cv2.rotate(rotated_image3, cv2.ROTATE_90_CLOCKWISE)\n        rotated_image3 = cv2.rotate(rotated_image3, cv2.ROTATE_90_CLOCKWISE)\n        return rotated_image3\n    elif index == 3:\n        return image1\n    \ndef rotBoxes90(boxes, im_w, im_h):\n    ret_boxes =[]\n    for box in boxes:\n        x1, y1, x2, y2 = box\n        x1, y1, x2, y2 = x1-im_w//2, im_h//2 - y1, x2-im_w//2, im_h//2 - y2\n        x1, y1, x2, y2 = y1, -x1, y2, -x2\n        x1, y1, x2, y2 = int(x1+im_w//2), int(im_h//2 - y1), int(x2+im_w//2), int(im_h//2 - y2)\n        x1a, y1a, x2a, y2a = min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2)\n        ret_boxes.append([x1a, y1a, x2a, y2a])\n    return np.array(ret_boxes)","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"DATA_ROOT_PATH = '../input/global-wheat-detection/test'\n\nclass TestDatasetRetriever(Dataset):\n\n    def __init__(self, image_ids, transforms=None):\n        super().__init__()\n        self.image_ids = image_ids\n        self.transforms = transforms\n\n    def __getitem__(self, index: int):\n        image_id = self.image_ids[index]\n        image = cv2.imread(f'{DATA_ROOT_PATH}/{image_id}.jpg', cv2.IMREAD_COLOR)\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        #image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32)\n        #image /= 255.0\n        if self.transforms:\n            sample = {'image': image}\n            sample = self.transforms(**sample)\n            image = sample['image']\n        return image, image_id\n\n    def __len__(self) -> int:\n        return self.image_ids.shape[0]\n\ndef get_valid_transforms():\n    return A.Compose(\n        [\n            A.Resize(height=512, width=512, p=1.0),\n            #ToTensorV2(p=1.0),\n        ], \n        p=1.0, \n    )\n\ndataset = TestDatasetRetriever(\n    image_ids=np.array([path.split('/')[-1][:-4] for path in glob(f'{DATA_ROOT_PATH}/*.jpg')]),\n    transforms=get_valid_transforms()\n)\n\ndef collate_fn(batch):\n    return tuple(zip(*batch))\n\ndata_loader = DataLoader(\n    dataset,\n    batch_size=1,\n    shuffle=False,\n    num_workers=4,\n    drop_last=False,\n    collate_fn=collate_fn\n)\n\ndef make_predictions(\n    images, \n    score_threshold=0.25,\n):\n    predictions = []\n    for fold_number, net in enumerate(models):\n        with torch.no_grad():\n            det = net(images, torch.tensor([1]*images.shape[0]).float().cuda())\n            result = []\n            for i in range(images.shape[0]):\n                boxes = det[i].detach().cpu().numpy()[:,:4]    \n                scores = det[i].detach().cpu().numpy()[:,4]\n                indexes = np.where(scores > score_threshold)[0]\n                boxes = boxes[indexes]\n                boxes[:, 2] = boxes[:, 2] + boxes[:, 0]\n                boxes[:, 3] = boxes[:, 3] + boxes[:, 1]\n                result.append({\n                    'boxes': boxes[indexes],\n                    'scores': scores[indexes],\n                })\n            predictions.append(result)\n    return predictions\n\n\ndef run_wbf(predictions, image_index, image_size=512, iou_thr=best_iou_thr, skip_box_thr=best_skip_box_thr, weights=None):\n    boxes = [(prediction[image_index]['boxes']/(image_size-1)).tolist()  for prediction in predictions]\n    scores = [prediction[image_index]['scores'].tolist()  for prediction in predictions]\n    labels = [np.ones(prediction[image_index]['scores'].shape[0]).tolist() for prediction in predictions]\n    boxes, scores, labels = weighted_boxes_fusion(boxes, scores, labels, weights=None, iou_thr=iou_thr, skip_box_thr=skip_box_thr)\n    boxes = boxes*(image_size-1)\n    return boxes, scores, labels\n\n\ndef 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)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def to_tensor(images):\n    tmp = []\n    for img in images:\n        img = img.astype(np.float32)\n        img /= 255.0\n        img = torch.tensor(img, dtype=torch.float32)\n        tmp.append(img.permute(2,0,1))\n    return torch.stack(tmp)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def run_wbf_tta(predictions, image_size=512, iou_thr=best_iou_thr, skip_box_thr=best_skip_box_thr, weights=None):\n    boxes_1 = []\n    scores_1 = []\n    labels_1 = []\n    for i in range(2):\n        bb = (predictions['boxes'][i]/(image_size-1)).tolist()\n        ss = predictions['scores'][i].tolist()\n        ls = predictions['labels'][i].tolist()\n        boxes_1.append(bb)\n        scores_1.append(ss)\n        labels_1.append(ls)\n\n    boxes_1, scores_1, labels_1 = weighted_boxes_fusion(boxes_1, scores_1, labels_1, \n                                                        weights=None, iou_thr=iou_thr, skip_box_thr=skip_box_thr)\n    \n    boxes_2 = []\n    scores_2 = []\n    labels_2 = []\n    for i in range(2,4):\n        bb = (predictions['boxes'][i]/(image_size-1)).tolist()\n        ss = predictions['scores'][i].tolist()\n        ls = predictions['labels'][i].tolist()\n        boxes_2.append(bb)\n        scores_2.append(ss)\n        labels_2.append(ls)\n    \n    boxes_2, scores_2, labels_2 = weighted_boxes_fusion(boxes_2, scores_2, labels_2, \n                                                        weights=None, iou_thr=iou_thr, skip_box_thr=skip_box_thr)\n    \n    boxes = [boxes_1.tolist(), boxes_2.tolist()]\n    scores = [scores_1.tolist(), scores_2.tolist()]\n    labels = [labels_1.tolist(), labels_2.tolist()]\n    \n    boxes, scores, labels = weighted_boxes_fusion(boxes, scores, labels, \n                                                        weights=None, iou_thr=iou_thr, skip_box_thr=skip_box_thr)\n    \n    boxes = boxes*(image_size-1)\n    return boxes, scores, labels","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true},"cell_type":"code","source":"results = []\n\nfor images, image_ids in data_loader:\n    \n    if USE_TTA:\n        image = images[0]\n        \n        predictions_tta = {\n            \"boxes\": [],\n            \"scores\": [],\n            \"labels\": []\n        }\n        for index in range(4):\n            roated = TTAImage(image, index)\n            roated = to_tensor([roated]).cuda()\n            predictions = make_predictions(roated)\n            boxes, scores, labels = run_wbf(predictions, image_index=0)\n\n            for _ in range(3-index):\n                \n                boxes = rotBoxes90(boxes, 512, 512)\n            \n            if index == 3:\n                \n                boxes = boxes.astype(np.int32)\n                \n            predictions_tta[\"boxes\"].append(boxes)\n            predictions_tta[\"scores\"].append(scores)\n            predictions_tta[\"labels\"].append(labels)\n        \n        boxes, scores, labels = run_wbf_tta(predictions_tta)\n        boxes = (boxes*2).astype(np.int32).clip(min=0, max=1023)\n        boxes[:, 2] = boxes[:, 2] - boxes[:, 0]\n        boxes[:, 3] = boxes[:, 3] - boxes[:, 1]\n        result = {\n                'image_id': image_ids[0],\n                'PredictionString': format_prediction_string(boxes, scores)\n            }\n        results.append(result)\n        \n    else:\n        images = to_tensor(images).cuda()\n        predictions = make_predictions(images)\n        for i, image in enumerate(images):\n            boxes, scores, labels = run_wbf(predictions, image_index=i)\n            boxes = (boxes*2).astype(np.int32).clip(min=0, max=1023)\n            image_id = image_ids[i]\n\n            boxes[:, 2] = boxes[:, 2] - boxes[:, 0]\n            boxes[:, 3] = boxes[:, 3] - boxes[:, 1]\n\n            result = {\n                'image_id': image_id,\n                'PredictionString': format_prediction_string(boxes, scores)\n            }\n            results.append(result)","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)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_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}