{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Inference EfficientDet\n\nHi everyone!\n\nMy name is Hieu, I am AI engineer. Especially I am in Love with CV & DL.\n\n\nI hope it is useful for you, my friends! If you didn't read this kernel, don't forget to do it! :)\n\n\nHere I would like to share with you inference part for my training kernel:\n\n- [[Training] EfficientDet](https://www.kaggle.com/backtracking/efficient-det-training)"},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install timm==0.1.26","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import sys\nsys.path.insert(0, \"../input/efficientdet-torch\")\nsys.path.insert(0, \"../input/omegaconf\")\nsys.path.insert(0, \"../input/weightedboxesfusion\")\nfrom ensemble_boxes import *\nimport torch\nimport os\nimport pydicom\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 matplotlib import pyplot as plt\nfrom glob import glob\nfrom effdet import get_efficientdet_config, EfficientDet, DetBenchEval\nfrom effdet.efficientdet import HeadNet\nfrom tqdm import tqdm\nimport warnings\nwarnings.filterwarnings('ignore')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"def get_valid_transforms():\n    return A.Compose([\n            A.Resize(height=1024, width=1024, p=1.0),\n            ToTensorV2(p=1.0),\n        ], p=1.0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image_dir = \"../input/vinbigdata-chest-xray-abnormalities-detection/test\"\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        dicom = pydicom.dcmread(f\"{image_dir}/{image_id}.dicom\")\n        image = dicom.pixel_array\n        if \"PhotometricInterpretation\" in dicom:\n            if dicom.PhotometricInterpretation == \"MONOCHROME1\":\n                image = np.amax(image) - image\n\n        image = np.stack([image, image, image])\n        image = image.astype('float32')\n        image = image - image.min()\n        image = image / image.max()\n        image = image.transpose(1, 2, 0)\n        \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":"image_ids = glob(os.path.join('../input/vinbigdata-chest-xray-abnormalities-detection/test', \"*.dicom\"))\nimage_ids = [image_id.split('/')[-1].split('.')[0] for image_id in image_ids]\ndataset = DatasetRetriever(image_ids = np.array(image_ids), transforms = get_valid_transforms())\n\ndef collate_fn(batch):\n    return tuple(zip(*batch))\n\ndata_loader = DataLoader(dataset, batch_size=8, shuffle=False, num_workers=2, drop_last=False, collate_fn=collate_fn)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"device = torch.device('cuda:0') if torch.cuda.is_available() else torch.device('cpu')\n\ndef load_net(checkpoint_path):\n    config = get_efficientdet_config('tf_efficientdet_d4')\n    net = EfficientDet(config, pretrained_backbone=False)\n\n    config.num_classes = 14\n    config.image_size = 1024\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    net = DetBenchEval(net, config)\n    net.eval()\n    return net.to(device)\n\nnet = load_net('../input/effdet-weights/last-checkpoint.bin')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def make_predictions(images, score_threshold=0.22):\n    images = torch.stack(images).cuda().float()\n    predictions = []\n    with torch.no_grad():\n        det = net(images, image_scales=torch.tensor([1] * images.shape[0]).float().cuda())\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            labels = det[i].detach().cpu().numpy()[:, 5]\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            predictions.append({\n                'boxes': boxes[indexes],\n                'scores': scores[indexes],\n                'labels': labels[indexes]\n            })\n    return [predictions]\n\ndef run_wbf(predictions, image_index, image_size=1024, iou_thr=0.5, skip_box_thr=0.4):\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 = [prediction[image_index]['labels'].tolist() for prediction in predictions]\n    boxes, scores, labels = weighted_boxes_fusion(boxes, scores, labels, weights=None, iou_thr=iou_thr,\n                                                  skip_box_thr=skip_box_thr)\n    boxes = boxes * (image_size - 1)\n    return boxes, scores, labels","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"mapping = {0: 'Aortic enlargement', 1: 'Atelectasis', 2: 'Calcification', 3: 'Cardiomegaly', 4: 'Consolidation', 5: 'ILD',6: 'Infiltration', 7: 'Lung Opacity', \n           8: 'Nodule/Mass', 9: 'Other lesion', 10: 'Pleural effusion', 11: 'Pleural thickening',12: 'Pneumothorax', 13: 'Pulmonary fibrosis'}\n\nfont = cv2.FONT_HERSHEY_SIMPLEX\nfontScale = 1\nthickness = 3\ncolor = (1, 0, 0)\nfor j, (images, image_ids) in enumerate(data_loader):\n    if j >= 20:\n        break\n    predictions = make_predictions(images=images, score_threshold=0.5)\n    i = 1\n    sample = images[i].permute(1, 2, 0).cpu().numpy()\n    boxes, scores, labels = run_wbf(predictions, image_index=i)\n    if len(labels) > 0:\n        boxes = boxes.astype(np.int32).clip(min=0, max=1023)\n        fig, ax = plt.subplots(1, 1, figsize=(8, 8))\n        for score, box, label in zip(scores, boxes, labels):\n            cv2.rectangle(sample, (box[0], box[1]), (box[2], box[3]), (0, 1, 1), thickness)\n            cv2.putText(sample, mapping[label] + \"---\" + str(round(score, 2)), (box[0], box[1]),\n                        font, fontScale, color, thickness, cv2.LINE_AA)\n        ax.set_axis_off()\n        ax.imshow(sample)\n        plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def format_prediction_string(boxes, scores, labels):\n    pred_strings = []\n    for pred in zip(labels, scores, boxes):\n        pred_strings.append(\"{0} {1:.4f} {2} {3} {4} {5}\".format(int(pred[0]), pred[1], pred[2][0], pred[2][1], pred[2][2], pred[2][3]))\n    if len(pred_strings) == 0:\n        return str(\"14 1 0 0 1 1\")\n    return \" \".join(pred_strings)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"results = []\nfrom tqdm import tqdm\nfor images, image_ids in tqdm(data_loader):\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, labels)\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":{"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}