{"cells":[{"metadata":{"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":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"_kg_hide-output":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\nimport sys\nsys.path.insert(0, \"../input/weightedboxesfusion\")\nsys.path.insert(0, \"../input/timm-efficientdet-pytorch\")\nsys.path.insert(0, \"../input/omegaconf\")\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport torch\nfrom torchvision import transforms\nfrom matplotlib import pyplot as plt\nfrom torchvision import transforms\nimport torchvision \nfrom torchvision.models.detection.faster_rcnn import FastRCNNPredictor\nfrom torchvision.models.detection import FasterRCNN\nfrom torch.utils.data import Dataset,DataLoader\nimport glob\nimport albumentations as A\nimport cv2\nfrom albumentations.pytorch.transforms import ToTensorV2\ndevice = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\nprint(device)\nimport ensemble_boxes\nfrom ensemble_boxes import *\nimport effdet\nfrom effdet import get_efficientdet_config, EfficientDet, DetBenchTrain, DetBenchEval\nfrom effdet.efficientdet import HeadNet\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 5GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"def get_model_d7(checkpoint_path):\n    config = get_efficientdet_config('tf_efficientdet_d7')\n    model = EfficientDet(config, pretrained_backbone=False)\n    config.num_classes = 1\n    config.image_size=512\n    model.class_net = HeadNet(config, num_outputs=config.num_classes, norm_kwargs=dict(eps=.001, momentum=.01))\n    checkpoint = torch.load(checkpoint_path)\n    model.load_state_dict(checkpoint['model_state_dict'])\n    model = DetBenchEval(model, config)\n    model.to(device)\n    model.eval();\n    return model\n\ndef get_model_d5(checkpoint_path):\n    config = get_efficientdet_config('tf_efficientdet_d5')\n    model = EfficientDet(config, pretrained_backbone=False)\n    config.num_classes = 1\n    config.image_size=512\n    model.class_net = HeadNet(config, num_outputs=config.num_classes, norm_kwargs=dict(eps=.001, momentum=.01))\n    checkpoint = torch.load(checkpoint_path)\n    model.load_state_dict(checkpoint['model_state_dict'])\n    model = DetBenchEval(model, config)\n    model.to(device)\n    model.eval();\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"eff_d7_33 = \"../input/d7effiecient-33e/cp33 (1).pt\"\neff_d7_26e= \"../input/d726eefficient/cp26.pt\"\n# resnet101_50e = \"/content/gdrive/My Drive/CV/פרויקטון/anna_saved_models/saved- RCNN-1024/אימון2 - לוס 0.68:(/cp49.pt\"\neff_d5_21= \"../input/d520eefficient/cp21.pt\"\neff_D7_39e= \"../input/d7efficient-39e/efficient-D7-39e.pt.pth\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"models = [\n    get_model_d7(eff_d7_33),\n    get_model_d7(eff_d7_26e),\n    get_model_d7(eff_D7_39e),\n#     get_model_d5(eff_d5_21)\n\n    # load_resnet101_model(resnet101_33e),\n    # load_resnet101_model(resnet101_50e)\n]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_valid_transforms():\n    return A.Compose([\n            A.Resize(height=512, width=512, p=1.0),\n            ToTensorV2(p=1.0),\n        ], p=1.0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"DATA_ROOT_PATH = \"../input/global-wheat-detection/test\"\n\nclass DatasetRetriever(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).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]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dataset = DatasetRetriever(np.array([path.split('/')[-1][:-4] for path in glob.glob(f'{DATA_ROOT_PATH}/*.jpg')]),get_valid_transforms())\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=1,\n    drop_last=False,\n    collate_fn=collate_fn\n)","execution_count":null,"outputs":[]},{"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\n    return \" \".join(pred_strings)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class BaseWheatTTA:\n    \"\"\" author: @shonenkov \"\"\"\n    image_size = 512\n\n    def augment(self, image):\n        raise NotImplementedError\n    \n    def batch_augment(self, images):\n        raise NotImplementedError\n    \n    def deaugment_boxes(self, boxes):\n        raise NotImplementedError\n\nclass TTAHorizontalFlip(BaseWheatTTA):\n    \"\"\" author: @shonenkov \"\"\"\n\n    def augment(self, image):\n        return image.flip(1)\n    \n    def batch_augment(self, images):\n        return images.flip(2)\n    \n    def deaugment_boxes(self, boxes):\n        boxes[:, [1,3]] = self.image_size - boxes[:, [3,1]]\n        return boxes\n\nclass TTAVerticalFlip(BaseWheatTTA):\n    \"\"\" author: @shonenkov \"\"\"\n    \n    def augment(self, image):\n        return image.flip(2)\n    \n    def batch_augment(self, images):\n        return images.flip(3)\n    \n    def deaugment_boxes(self, boxes):\n        boxes[:, [0,2]] = self.image_size - boxes[:, [2,0]]\n        return boxes\n    \nclass TTARotate90(BaseWheatTTA):\n    \"\"\" author: @shonenkov \"\"\"\n    \n    def augment(self, image):\n        return torch.rot90(image, 1, (1, 2))\n\n    def batch_augment(self, images):\n        return torch.rot90(images, 1, (2, 3))\n    \n    def deaugment_boxes(self, boxes):\n        res_boxes = boxes.copy()\n        res_boxes[:, [0,2]] = self.image_size - boxes[:, [1,3]]\n        res_boxes[:, [1,3]] = boxes[:, [2,0]]\n        return res_boxes\n    \nclass TTARotate180(BaseWheatTTA):\n    \"\"\" author: @shonenkov \"\"\"\n    \n    def augment(self, image):\n        return torch.rot90(image, 2, (1, 2))\n\n    def batch_augment(self, images):\n        return torch.rot90(images, 2, (2, 3))\n    \n    def deaugment_boxes(self, boxes):\n        boxes[:, [0,1,2,3]] = self.image_size - boxes[:, [2,3,0,1]]\n        return boxes\n    \nclass TTARotate270(BaseWheatTTA):\n    \"\"\" author: @shonenkov \"\"\"\n    \n    def augment(self, image):\n        return torch.rot90(image, 3, (1, 2))\n\n    def batch_augment(self, images):\n        return torch.rot90(images, 3, (2, 3))\n    \n    def deaugment_boxes(self, boxes):\n        res_boxes = boxes.copy()\n        res_boxes[:, [0,2]] = boxes[:, [1,3]]\n        res_boxes[:, [1,3]] = self.image_size - boxes[:, [2,0]]\n        return res_boxes\n    \nclass TTACompose(BaseWheatTTA):\n    \"\"\" author: @shonenkov \"\"\"\n    def __init__(self, transforms):\n        self.transforms = transforms\n        \n    def augment(self, image):\n        for transform in self.transforms:\n            image = transform.augment(image)\n        return image\n    \n    def batch_augment(self, images):\n        for transform in self.transforms:\n            images = transform.batch_augment(images)\n        return images\n    \n    def prepare_boxes(self, boxes):\n        result_boxes = boxes.copy()\n        result_boxes[:,0] = np.min(boxes[:, [0,2]], axis=1)\n        result_boxes[:,2] = np.max(boxes[:, [0,2]], axis=1)\n        result_boxes[:,1] = np.min(boxes[:, [1,3]], axis=1)\n        result_boxes[:,3] = np.max(boxes[:, [1,3]], axis=1)\n        return result_boxes\n    \n    def deaugment_boxes(self, boxes):\n        for transform in self.transforms[::-1]:\n            boxes = transform.deaugment_boxes(boxes)\n        return self.prepare_boxes(boxes)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from itertools import product\n\ntta_transforms = []\nfor tta_combination in product([TTAHorizontalFlip(), None], \n                               [TTAVerticalFlip(), None],\n                               [TTARotate90(), None]):\n    tta_transforms.append(TTACompose([tta_transform for tta_transform in tta_combination if tta_transform]))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# def make_tta_predictions(model, images, score_threshold=0.25):\n#     model.eval()\n#     model.to(device)\n#     with torch.no_grad():\n#         images = torch.stack(images).float().cuda()\n#         predictions = []\n#         for tta_transform in tta_transforms:\n#             result = []\n#             det = model(tta_transform.batch_augment(images.clone()), img_size =  torch.tensor([images[0].shape[-2:]] * 1, dtype=torch.float).to(device), img_scales= torch.tensor([1]*images.shape[0]).float().cuda())\n\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#                 boxes = tta_transform.deaugment_boxes(boxes.copy())\n#                 result.append({\n#                     'boxes': boxes,\n#                     'scores': scores[indexes],\n#                 })\n#             predictions.append(result)\n#     return predictions","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import ensemble_boxes\nfrom ensemble_boxes import *\n\n# def make_ensemble_predictions(images):\n#     images = list(image.to(device) for image in images)    \n#     result = []\n#     for model in models:\n#         predictions = make_tta_predictions(model, images)\n#         with torch.no_grad():\n#             for i in range(len(images)):\n#                 boxes, scores, labels = run_wbf(predictions, image_index=i)\n#                 outputs = {'boxes': boxes,'labels': labels, 'scores':scores }\n#                 result.append([outputs])\n#                 torch.cuda.empty_cache()\n\n#     return result\n\ndef make_ensemble_predictions(images):\n    # images = list(image.to(device) for image in images)\n    images = torch.stack(images).cuda().float()    \n    result = []\n    for model in models:\n        with torch.no_grad():\n            model.eval()\n#             x= torch.tensor([1]*images.shape[0]).float().cuda()\n#             y = torch.tensor([images[0].shape[-2:]] * 1, dtype=torch.float).to(device)\n            outputs = model(images, torch.tensor([1.0] * 1, dtype=torch.float).to(device))\n            results = []\n            for i in range(images.shape[0]):\n                boxes = outputs[i].detach().cpu().numpy()[:,:4]    \n                scores = outputs[i].detach().cpu().numpy()[:,4]\n                indexes = np.where(scores > 0.23)[0]\n                boxes = boxes[indexes]\n                boxes[:, 2] = boxes[:, 2] + boxes[:, 0]\n                boxes[:, 3] = boxes[:, 3] + boxes[:, 1]\n                results.append({\n                    'boxes': boxes,\n                    'scores': scores[indexes],\n                })\n            result.append(results)\n            torch.cuda.empty_cache()\n    return result\n\ndef run_wbf(predictions, image_index, image_size=512, iou_thr=0.3, skip_box_thr=0.25,score_threshold= 0.28, weights=None ):\n    boxes = [(prediction[image_index]['boxes']/(image_size)).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]).astype(int).tolist() for prediction in predictions]\n    boxes, scores, labels = ensemble_boxes.ensemble_boxes_wbf.weighted_boxes_fusion(boxes, scores, labels, weights=None, iou_thr=iou_thr, skip_box_thr=skip_box_thr)\n    indexes = np.where(scores > score_threshold)[0]\n    boxes = boxes[indexes]    \n    scores = scores[indexes]\n    boxes = boxes*(image_size)\n    return boxes, scores, labels","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for j, (images, image_ids) in enumerate(data_loader):\n    break\npredictions = make_ensemble_predictions(images)\n\ni = 0\nsample = images[i].permute(1,2,0).cpu().numpy()\nboxes, scores, labels = run_wbf(predictions, image_index=i, weights = [2,2,4])\nboxes = boxes.round().astype(np.int32).clip(min=0, max=1023)\n\nfig, ax = plt.subplots(1, 1, figsize=(16, 8))\n\nfor j,box in enumerate(boxes):\n    cv2.rectangle(sample, (box[0], box[1]), (box[2], box[3]), (1, 0, 0), 2)\n    score=str(float(\"{:.3f}\".format(scores[j])))\n    \n#     cv2.putText(\n#                 sample,\n#                 score,\n#                 org=(int(box[0]), int(box[1] )), # bottom left\n#                 fontFace=cv2.FONT_HERSHEY_PLAIN,\n#                 fontScale=1.5,\n#                 color=(1,0, 0),\n#                 thickness=2\n#             )\nax.set_axis_off()\nax.imshow(sample);","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"validation_image_precisions = []\niou_thresholds = [x for x in np.arange(0.5, 0.76, 0.05)]\n# model.eval()\n# model.to(device)\n\nresults = []\n\nfor images, image_ids in data_loader:    \n    predictions = make_ensemble_predictions(images)\n    for i, image in enumerate(images):\n        boxes, scores, labels = run_wbf(predictions, image_index=i, weights = [2,2,4])\n        boxes = (boxes*2).astype(np.int32).clip(min=0, max=1023)\n        image_id = image_ids[i]\n\n        #plot the images\n#         sample = images[i].permute(1,2,0).cpu().numpy()\n#         sample = cv2.resize(sample,(1024,1024))\n#         fig, ax = plt.subplots(1, 1, figsize=(6, 6))\n\n#         for j,box in enumerate(boxes):\n#             cv2.rectangle(sample, (box[0], box[1]), (box[2], box[3]), (1, 0, 0), 3)\n#             score=str(float(\"{:.3f}\".format(scores[j])))\n\n#             cv2.putText(\n#               sample,\n#               score,\n#               org=(int(box[0]), int(box[1] )), # bottom left\n#               fontFace=cv2.FONT_HERSHEY_PLAIN,\n#               fontScale=3,\n#               color=(1,0, 0),\n#               thickness=3\n#             )\n#         ax.set_axis_off()\n#         ax.imshow(sample)\n        \n\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)\n","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(10)","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}