{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Import dependencies","execution_count":null},{"metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","trusted":true},"cell_type":"code","source":"import logging\nimport os\nimport re\nimport gc\nimport json\nfrom tqdm.auto import tqdm\n\nimport numpy as np\nimport pandas as pd\nimport cv2\nimport matplotlib.pyplot as plt","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Install packages","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install ../input/pytorch-16/torch-1.6.0cu101-cp37-cp37m-linux_x86_64.whl","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install ../input/pytorch-16/torchvision-0.7.0cu101-cp37-cp37m-linux_x86_64.whl","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"!pip install ../input/pretrainedmodels/pretrainedmodels-0.7.4/pretrainedmodels-0.7.4/ > /dev/null # no output","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install ../input/wheat-pkgs/EfficientNet-PyTorch-master/EfficientNet-PyTorch-master/ > /dev/null # no output","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install ../input/wheat-pkgs/timm-0.1.20-py3-none-any.whl > /dev/null # no output","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install ../input/wheat-pkgs/segmentation_models.pytorch-master/segmentation_models.pytorch-master > /dev/null # no output","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Import more dependencies","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.optim as optim\nimport segmentation_models_pytorch as smp\n\nfrom wheat_infer_utils import *\nfrom wheat_centernet_models import PoseBiFPNNet\nfrom wheat_pseudo_train_l_helpers import (\n    set_seed,\n    create_logging,\n    WheatDataset,\n    FastDataLoader,\n    collate,\n    ModleWithLoss,\n    CtdetLoss,\n    ModelEMA,\n    get_constant_schedule_with_warmup,\n    train_one_epoch,\n    get_train_transforms,\n    freeze_bn\n)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Configuration","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"bifpn_path_0 = '../input/wheat-weights/model_centernet_effnetb5_bifpn_00099.pth'\nbifpn_path_1 = '../input/wheat-weights/model_centernet_effnetb5_bifpn_fold1_00099.pth'\nbifpn_path_3 = '../input/wheat-weights/model_centernet_effnetb5_bifpn_fold3_lb_ema_00099.pth'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class Config:\n    arch = 'timm-efficientnet-b5'\n    heads = {'hm': 1,\n             'wh': 2,\n             'reg': 2}\n    head_conv = 64\n    reg_offset = True\n    cat_spec_wh = False\n    \n    # Image\n    img_size = 1024\n    in_scale = 1024 / img_size\n    down_ratio = 4\n    \n    mean = [0.315290, 0.317253, 0.214556], \n    std = [0.245211, 0.238036, 0.193879]\n    num_classes = 1\n    \n    pad = 63\n    \n    # Test\n    \n    batch_size = 8\n    K = 128\n    max_per_image = 128\n    \n    fix_res = False\n    test_scales = [1]\n    flip_test = False\n    nms = False\n    gpus = [0]\n    amp = True\n    \nopt = Config()\ndevice = torch.device('cuda') if opt.gpus[0] >= 0 else torch.device('cpu')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def change_key(d):\n    for _ in range(len(d)):\n        k, v = d.popitem(False)\n        d['.'.join(k.split('.')[1:])] = v","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Preapre labels","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"DIR_INPUT = '../input/global-wheat-detection'\nDIR_TRAIN = f'{DIR_INPUT}/train'\nDIR_TEST = f'{DIR_INPUT}/test'\n\ntrain_df = pd.read_csv(f'{DIR_INPUT}/train.csv')\ntrain_df.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df['x'] = -1\ntrain_df['y'] = -1\ntrain_df['w'] = -1\ntrain_df['h'] = -1\n\ndef expand_bbox(x):\n    r = np.array(re.findall(\"([0-9]+[.]?[0-9]*)\", x))\n    if len(r) == 0:\n        r = [-1, -1, -1, -1]\n    return r\n\ntrain_df[['x', 'y', 'w', 'h']] = np.stack(train_df['bbox'].apply(lambda x: expand_bbox(x)))\ntrain_df.drop(columns=['bbox'], inplace=True)\ntrain_df['x'] = train_df['x'].astype(np.float)\ntrain_df['y'] = train_df['y'].astype(np.float)\ntrain_df['w'] = train_df['w'].astype(np.float)\ntrain_df['h'] = train_df['h'].astype(np.float)\n\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# DEBUG\n# DIR_TEST = '../input/wheat-fake-test'","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Define test dataset","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"class WheatDatasetTest(torch.utils.data.Dataset):\n    def __init__(self, opt, image_dir, transforms=None,\n                 mean=[0.315290, 0.317253, 0.214556], \n                 std=[0.245211, 0.238036, 0.193879]):\n        \n        self.opt = opt\n        \n        self.image_dir = image_dir\n        self.img_id = os.listdir(self.image_dir)\n        \n        self.transforms = transforms\n        \n        self.mean = np.array(mean, dtype=np.float32).reshape(1, 1, 3)\n        self.std = np.array(std, dtype=np.float32).reshape(1, 1, 3)\n        \n    def __len__(self):\n        return len(self.img_id)\n\n    def __getitem__(self, idx):\n        img_path = os.path.join(self.image_dir, self.img_id[idx])\n        \n        image = cv2.cvtColor(cv2.imread(img_path), cv2.COLOR_BGR2RGB)\n        h0, w0 = image.shape[0:2]\n        \n        if self.transforms is not None:\n            image = self.transforms(image)\n        image_resized = cv2.resize(image, (self.opt.img_size, self.opt.img_size))\n        return image_resized, self.img_id[idx], image, h0, w0","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def flip_lr(img):\n    return np.ascontiguousarray(img[:, ::-1, :])\n\ndef deaug_lr(img, boxes):\n    h, w = img.shape[:2]\n    boxes[:, (0, 2)] = w - boxes[:, (2, 0)]\n    return boxes\n\ndef flip_ud(img):\n    return np.ascontiguousarray(img[::-1, :, :])\n\ndef deaug_ud(img, boxes):\n    h, w = img.shape[:2]\n    boxes[:, (1, 3)] = w - boxes[:, (3, 1)]\n    return boxes","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Visualization helpers","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"BOX_COLOR_PRED = (255, 0, 0)\nTEXT_COLOR = (255, 255, 255)\n\n\ndef visualize_bbox(img, bbox, score, color, thickness=2):\n    x_min, y_min, x_max, y_max = bbox\n    cv2.rectangle(img, (x_min, y_min), (x_max, y_max), color=color, thickness=thickness)\n    ((text_width, text_height), _) = cv2.getTextSize(\"{:.4f}\".format(score), cv2.FONT_HERSHEY_SIMPLEX, 0.35, 1)    \n    cv2.rectangle(img, (x_min, y_min - int(1.3 * text_height)), (x_min + text_width, y_min), color, -1)\n    cv2.putText(img, \"{:.4f}\".format(score), (x_min, y_min - int(0.3 * text_height)), cv2.FONT_HERSHEY_SIMPLEX, 0.35,TEXT_COLOR, lineType=cv2.LINE_AA)\n    return img\n\n\ndef visualize(annotations):\n    img = annotations['image'].copy()\n    for bbox, score in zip(annotations['bboxes'], annotations['scores']):\n        img = visualize_bbox(img, bbox, score, color=BOX_COLOR_PRED)\n    plt.figure(figsize=(12, 12))\n    plt.imshow(img)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Inference","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"testdataset = WheatDatasetTest(opt, DIR_TEST)\nprint('Total number of images in test set: {}'.format(len(testdataset)))\n\ntestdataset_lr = WheatDatasetTest(opt, DIR_TEST, transforms=flip_lr)\ntestdataset_ud = WheatDatasetTest(opt, DIR_TEST, transforms=flip_ud)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Inference helper\ndef do_predict(opt, model, threshold, flip_type=0, return_ids=False, return_shapes=False):\n    \n    if flip_type == 0:\n        test_dataset = testdataset\n        deaug_transform = None\n    elif flip_type == 1:\n        test_dataset = testdataset_lr\n        deaug_transform = deaug_lr\n    elif flip_type == 2:\n        test_dataset = testdataset_ud\n        deaug_transform = deaug_ud\n        \n    detector = CtdetDetector(opt, model)\n    \n    pred_boxes = []\n    pred_scores = []\n    \n    height_list = []\n    width_list = []\n    if return_ids:\n        img_ids = []\n    \n    for img, img_id, img0, h0, w0 in tqdm(test_dataset):\n        \n        ret = detector.run(img)\n        results = ret['results'][1]\n        results = results[results[:, 4] > threshold]\n        \n        pred_box = results[:, :4]\n        if flip_type != 0:\n            pred_box = deaug_transform(img, pred_box)\n        \n        # rescale & clip\n        pred_box[:, 0] = np.clip(pred_box[:, 0] / opt.img_size * w0, 0, w0-1)\n        pred_box[:, 1] = np.clip(pred_box[:, 1] / opt.img_size * h0, 0 ,h0-1)\n        pred_box[:, 2] = np.clip(pred_box[:, 2] / opt.img_size * w0, 0, w0-1)\n        pred_box[:, 3] = np.clip(pred_box[:, 3] / opt.img_size * h0, 0 ,h0-1)\n            \n        pred_boxes.append(pred_box)\n        pred_scores.append(results[:, 4])\n        if return_ids:\n            img_ids.append(os.path.splitext(img_id)[0])\n        \n        if return_shapes:\n            height_list.append(h0)\n            width_list.append(w0)\n    \n    if return_shapes:\n        if return_ids:\n            return pred_boxes, pred_scores, height_list, width_list, img_ids\n        else:\n            return pred_boxes, pred_scores, height_list, width_list\n    else:\n        if return_ids:\n            return pred_boxes, pred_scores, img_ids\n        else:\n            return pred_boxes, pred_scores","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# On BiFPN model","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"## Load Fold 0 weights","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"bifpn_model = PoseBiFPNNet(opt.arch, opt.heads, opt.head_conv)\ncheckpoint = torch.load(bifpn_path_0, map_location=device)\n\nchange_key(checkpoint['model'])\nbifpn_model.load_state_dict(checkpoint['model'])\nbifpn_model.to(device)\n\ndel checkpoint\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"opt.pad = 63\n\nopt.test_scales = [1.1, ]\nthreshold = 0.30\n\nbifpn0_pred_boxes_0   , bifpn0_pred_scores_0, h0_list, w0_list, img_ids = do_predict(opt, bifpn_model, threshold=threshold, flip_type=0, return_ids=True, return_shapes=True)\nbifpn0_pred_boxes_0_lr, bifpn0_pred_scores_0_lr = do_predict(opt, bifpn_model, threshold=threshold, flip_type=1, return_ids=False, return_shapes=False)\nbifpn0_pred_boxes_0_ud, bifpn0_pred_scores_0_ud = do_predict(opt, bifpn_model, threshold=threshold, flip_type=2, return_ids=False, return_shapes=False)\n\n\nopt.test_scales = [1.25, ]\nthreshold = 0.28\n\nbifpn0_pred_boxes_l   , bifpn0_pred_scores_l    = do_predict(opt, bifpn_model, threshold=threshold, flip_type=0, return_ids=False, return_shapes=False)\nbifpn0_pred_boxes_l_lr, bifpn0_pred_scores_l_lr = do_predict(opt, bifpn_model, threshold=threshold, flip_type=1, return_ids=False, return_shapes=False)\nbifpn0_pred_boxes_l_ud, bifpn0_pred_scores_l_ud = do_predict(opt, bifpn_model, threshold=threshold, flip_type=2, return_ids=False, return_shapes=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del bifpn_model\ngc.collect()\ntorch.cuda.empty_cache()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Load Fold 1 weights","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"bifpn_model = PoseBiFPNNet(opt.arch, opt.heads, opt.head_conv)\ncheckpoint = torch.load(bifpn_path_1, map_location=device)\n\nchange_key(checkpoint['model'])\nbifpn_model.load_state_dict(checkpoint['model'])\nbifpn_model.to(device)\n\ndel checkpoint\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"opt.pad = 63\n\nopt.test_scales = [1.1, ]\nthreshold = 0.30\n\nbifpn1_pred_boxes_0   , bifpn1_pred_scores_0    = do_predict(opt, bifpn_model, threshold=threshold, flip_type=0, return_ids=False, return_shapes=False)\nbifpn1_pred_boxes_0_lr, bifpn1_pred_scores_0_lr = do_predict(opt, bifpn_model, threshold=threshold, flip_type=1, return_ids=False, return_shapes=False)\nbifpn1_pred_boxes_0_ud, bifpn1_pred_scores_0_ud = do_predict(opt, bifpn_model, threshold=threshold, flip_type=2, return_ids=False, return_shapes=False)\n\n\nopt.test_scales = [1.25, ]\nthreshold = 0.28\n\nbifpn1_pred_boxes_l   , bifpn1_pred_scores_l    = do_predict(opt, bifpn_model, threshold=threshold, flip_type=0, return_ids=False, return_shapes=False)\nbifpn1_pred_boxes_l_lr, bifpn1_pred_scores_l_lr = do_predict(opt, bifpn_model, threshold=threshold, flip_type=1, return_ids=False, return_shapes=False)\nbifpn1_pred_boxes_l_ud, bifpn1_pred_scores_l_ud = do_predict(opt, bifpn_model, threshold=threshold, flip_type=2, return_ids=False, return_shapes=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del bifpn_model\ngc.collect()\ntorch.cuda.empty_cache()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Load Fold 3 weights","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"bifpn_model = PoseBiFPNNet(opt.arch, opt.heads, opt.head_conv)\ncheckpoint = torch.load(bifpn_path_3, map_location=device)\n\nchange_key(checkpoint['model'])\nbifpn_model.load_state_dict(checkpoint['model'])\nbifpn_model.to(device)\n\ndel checkpoint\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"opt.pad = 63\n\nopt.test_scales = [1.1, ]\nthreshold = 0.30\n\nbifpn3_pred_boxes_0   , bifpn3_pred_scores_0    = do_predict(opt, bifpn_model, threshold=threshold, flip_type=0, return_ids=False, return_shapes=False)\nbifpn3_pred_boxes_0_lr, bifpn3_pred_scores_0_lr = do_predict(opt, bifpn_model, threshold=threshold, flip_type=1, return_ids=False, return_shapes=False)\nbifpn3_pred_boxes_0_ud, bifpn3_pred_scores_0_ud = do_predict(opt, bifpn_model, threshold=threshold, flip_type=2, return_ids=False, return_shapes=False)\n\n\nopt.test_scales = [1.25, ]\nthreshold = 0.28\n\nbifpn3_pred_boxes_l   , bifpn3_pred_scores_l    = do_predict(opt, bifpn_model, threshold=threshold, flip_type=0, return_ids=False, return_shapes=False)\nbifpn3_pred_boxes_l_lr, bifpn3_pred_scores_l_lr = do_predict(opt, bifpn_model, threshold=threshold, flip_type=1, return_ids=False, return_shapes=False)\nbifpn3_pred_boxes_l_ud, bifpn3_pred_scores_l_ud = do_predict(opt, bifpn_model, threshold=threshold, flip_type=2, return_ids=False, return_shapes=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del bifpn_model\ngc.collect()\ntorch.cuda.empty_cache()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Ensemble","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def normalize_boxes(boxes, h0, w0):\n    boxes[:, 0] = boxes[:, 0] / w0\n    boxes[:, 1] = boxes[:, 1] / h0\n    boxes[:, 2] = boxes[:, 2] / w0\n    boxes[:, 3] = boxes[:, 3] / h0\n    return boxes\n\ndef denormalize_clip_boxes(boxes, h0, w0):\n    boxes[:, 0] = np.clip(boxes[:, 0] * w0, 0, w0-1)\n    boxes[:, 1] = np.clip(boxes[:, 1] * h0, 0, h0-1)\n    boxes[:, 2] = np.clip(boxes[:, 2] * w0, 0, w0-1)\n    boxes[:, 3] = np.clip(boxes[:, 3] * h0, 0, h0-1)\n    return boxes","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import sys\nsys.path.insert(0, \"../input/weightedboxesfusion\")\nimport ensemble_boxes\n\niou_thr = 0.44\nskip_box_thr = 0.00001\n\npred_boxes_ensemble = []\npred_scores_ensemble = []\nfor (b00, b01, b02, b03, b04, b05,\n     b10, b11, b12, b13, b14, b15, \n     b20, b21, b22, b23, b24, b25,\n     s00, s01, s02, s03, s04, s05,\n     s10, s11, s12, s13, s14, s15,\n     s20, s21, s22, s23, s24, s25,\n     h0, w0) in zip(\n    tqdm(bifpn0_pred_boxes_0), \n    bifpn0_pred_boxes_0_lr, \n    bifpn0_pred_boxes_0_ud,\n    bifpn0_pred_boxes_l,\n    bifpn0_pred_boxes_l_lr,\n    bifpn0_pred_boxes_l_ud,\n    \n    bifpn1_pred_boxes_0, \n    bifpn1_pred_boxes_0_lr, \n    bifpn1_pred_boxes_0_ud,\n    bifpn1_pred_boxes_l,\n    bifpn1_pred_boxes_l_lr,\n    bifpn1_pred_boxes_l_ud,\n    \n    bifpn3_pred_boxes_0, \n    bifpn3_pred_boxes_0_lr, \n    bifpn3_pred_boxes_0_ud,\n    bifpn3_pred_boxes_l,\n    bifpn3_pred_boxes_l_lr,\n    bifpn3_pred_boxes_l_ud,\n    \n    \n    bifpn0_pred_scores_0,\n    bifpn0_pred_scores_0_lr, \n    bifpn0_pred_scores_0_ud,\n    bifpn0_pred_scores_l,\n    bifpn0_pred_scores_l_lr,\n    bifpn0_pred_scores_l_ud,\n    \n    bifpn1_pred_scores_0,\n    bifpn1_pred_scores_0_lr, \n    bifpn1_pred_scores_0_ud,\n    bifpn1_pred_scores_l,\n    bifpn1_pred_scores_l_lr,\n    bifpn1_pred_scores_l_ud,\n    \n    bifpn3_pred_scores_0,\n    bifpn3_pred_scores_0_lr, \n    bifpn3_pred_scores_0_ud,\n    bifpn3_pred_scores_l,\n    bifpn3_pred_scores_l_lr,\n    bifpn3_pred_scores_l_ud,\n\n    h0_list,\n    w0_list):\n    \n    \n    boxes_list = [\n        normalize_boxes(b00, h0, w0).tolist(),\n        normalize_boxes(b01, h0, w0).tolist(),\n        normalize_boxes(b02, h0, w0).tolist(),\n        normalize_boxes(b03, h0, w0).tolist(),\n        normalize_boxes(b04, h0, w0).tolist(),\n        normalize_boxes(b05, h0, w0).tolist(),\n        normalize_boxes(b10, h0, w0).tolist(),\n        normalize_boxes(b11, h0, w0).tolist(),\n        normalize_boxes(b12, h0, w0).tolist(),\n        normalize_boxes(b13, h0, w0).tolist(),\n        normalize_boxes(b14, h0, w0).tolist(),\n        normalize_boxes(b15, h0, w0).tolist(),\n        normalize_boxes(b20, h0, w0).tolist(),\n        normalize_boxes(b21, h0, w0).tolist(),\n        normalize_boxes(b22, h0, w0).tolist(),\n        normalize_boxes(b23, h0, w0).tolist(),\n        normalize_boxes(b24, h0, w0).tolist(),\n        normalize_boxes(b25, h0, w0).tolist()\n    ]\n    \n    scores_list = [\n        s00.tolist(),\n        s01.tolist(),\n        s02.tolist(),\n        s03.tolist(),\n        s04.tolist(),\n        s05.tolist(),\n        s10.tolist(),\n        s11.tolist(),\n        s12.tolist(),\n        s13.tolist(),\n        s14.tolist(),\n        s15.tolist(),\n        s20.tolist(),\n        s21.tolist(),\n        s22.tolist(),\n        s23.tolist(),\n        s24.tolist(),\n        s25.tolist()\n    ]\n    \n    labels_list = [\n        [0] * len(b00),\n        [0] * len(b01),\n        [0] * len(b02),\n        [0] * len(b03),\n        [0] * len(b04),\n        [0] * len(b05),\n        [0] * len(b10),\n        [0] * len(b11),\n        [0] * len(b12),\n        [0] * len(b13),\n        [0] * len(b14),\n        [0] * len(b15),\n        [0] * len(b20),\n        [0] * len(b21),\n        [0] * len(b22),\n        [0] * len(b23),\n        [0] * len(b24),\n        [0] * len(b25)\n    ]\n    \n    boxes, scores, _ = ensemble_boxes.ensemble_boxes_wbf.weighted_boxes_fusion(boxes_list, scores_list, labels_list, iou_thr=iou_thr, skip_box_thr=skip_box_thr)\n    pred_boxes_ensemble.append(boxes)\n    pred_scores_ensemble.append(scores)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pred_boxes_ensemble = [denormalize_clip_boxes(a, h0, w0) for a, h0, w0 in zip(pred_boxes_ensemble, h0_list, w0_list)]\npred_scores_ensemble = [a for a in pred_scores_ensemble]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# visualization\nidx = -7\nimg = testdataset[idx][2]\nprint(testdataset[idx][1])\nvisualize({'image': img, 'bboxes': (pred_boxes_ensemble[idx]).astype(int), 'scores': pred_scores_ensemble[idx]})","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Generate Pseudo Labels","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"data_dict_pseudo = []\nid_generator = 20201000000\nfor idx, (bboxes, h0, w0) in enumerate(zip(tqdm(pred_boxes_ensemble), h0_list, w0_list)):\n    img_dict = {\n        'file_name': os.path.join(DIR_TEST, testdataset[idx][1]),\n        'height': h0,\n        'width': w0,\n        'id': id_generator,\n    }\n    annotations = []\n    for bbox in bboxes:\n        xywh = np.round([bbox[0], bbox[1], bbox[2]-bbox[0], bbox[3]-bbox[1]]).astype(float).tolist()\n        annotations.append({\n            'area': xywh[2] * xywh[3],\n            'bbox': xywh,\n            'category_id': 0,\n            'bbox_mode': 1\n        })\n    img_dict['annotations'] = annotations\n    id_generator += 1\n    \n    data_dict_pseudo.append(img_dict)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data_dict_pseudo = [d for d in data_dict_pseudo if len(d['annotations']) > 0] # removal","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Training on pseudo labels","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"class TrainConfig:\n    seed = 2519\n    arch = 'timm-efficientnet-b5'\n    heads = {\n        'hm': 1,\n        'wh': 2,\n        'reg': 2}\n    head_conv = 64\n    reg_offset = True\n    \n    # Image\n    data_root = '../input/global-wheat-detection'\n    crop_size = 896\n    scale = 0.\n    shift = 0.\n    rotate = 15.\n    shear = 5.\n    down_ratio = 4\n\n    debug = False\n\n    # loss\n    hm_weight = 1\n    off_weight = 1\n    wh_weight = 0.1\n\n    # train\n    batch_size = 4\n    base_lr = 0.25e-4\n    warmup_iters = 0\n    total_epochs = 9\n    stage_epochs = 9\n    freeze_bn = True\n    accumulate = 3\n    device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n    ema = False\n    amp = True\n\n    # logging\n    output_dir = './'\n    logs_dir = os.path.join(output_dir, 'logs')\n    log_interval = 10\n\n    # saving\n    checkpoint = 1\n    load_model = '../input/wheat-weights/model_centernet_effnetb5_bifpn_00099.pth'\n    resume = ''\n    \ntrain_opt = TrainConfig()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"with open('../input/wheat-splits/wheat_train_3.json', 'r') as f:\n    data_dict_train = json.load(f)\n\nwith open('../input/wheat-splits/wheat_valid_3.json', 'r') as f:\n    data_dict_valid = json.load(f)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def main(opt):\n    set_seed(opt.seed)\n    torch.backends.cudnn.benchmark = True\n    \n    create_logging(opt.logs_dir, 'w')\n\n    train_dataset = WheatDataset(\n        opt, \n        opt.data_root, \n        data_dict_train, \n        data_dict_pseudo=data_dict_pseudo, \n        img_size=1024, \n        transforms=get_train_transforms(opt.crop_size), \n        is_train=True, \n        load_to_ram=False)\n    \n    logging.info('{} images in training set'.format(len(train_dataset.data_dict)))\n    \n    train_loader = FastDataLoader(\n        train_dataset, \n        opt.batch_size,\n        collate_fn=collate,\n        shuffle=True, \n        drop_last=True,\n        pin_memory=True,\n        num_workers=2)\n    \n    model = ModleWithLoss(PoseBiFPNNet(opt.arch, opt.heads, opt.head_conv), CtdetLoss(opt)).to(opt.device)\n    if opt.freeze_bn:\n        model.apply(freeze_bn) # freeze bn\n    if opt.ema:\n        logging.info('Training with EMA')\n        ema = ModelEMA(model)\n    else:\n        ema = None\n    optimizer = optim.Adam(filter(lambda p: p.requires_grad, model.parameters()), lr=opt.base_lr)\n    num_training_steps = int(opt.total_epochs * len(train_dataset) / opt.batch_size / opt.accumulate)\n    scheduler = get_constant_schedule_with_warmup(optimizer, opt.warmup_iters)\n    current_epoch = 0\n\n    if opt.load_model != '':\n        checkpoint = torch.load(opt.load_model)\n        model.load_state_dict(checkpoint['model'])\n\n    elif opt.resume != '':\n        # Load model weights\n        checkpoint = torch.load(opt.resume)\n        model.load_state_dict(checkpoint['model'])\n        optimizer.load_state_dict(checkpoint['optimizer'])\n        scheduler.load_state_dict(checkpoint['scheduler'])\n        current_epoch = checkpoint['epoch'] + 1\n\n    scaler = GradScaler() if opt.amp else None\n    for epoch in tqdm(range(current_epoch, current_epoch + opt.stage_epochs)):\n\n        epoch_start_time = time.time()\n        train_one_epoch(opt, model, optimizer, scheduler, train_loader, epoch, ema=ema, scaler=scaler)\n\n        logging.info('-' * 89)\n        logging.info('end of epoch {:4d} | time: {:5.2f}s |'.format(epoch, (time.time() - epoch_start_time)))\n        logging.info('-' * 89)\n\n    return model.state_dict()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# gc.collect()\n# torch.cuda.empty_cache()\n\n# pseudo_model = PoseBiFPNNet(opt.arch, opt.heads, opt.head_conv)\n\n# if len(os.listdir('../input/global-wheat-detection/test/')) < 11:\n#     checkpoint = torch.load(bifpn_path_0, map_location=device)\n\n#     change_key(checkpoint['model'])\n#     pseudo_model.load_state_dict(checkpoint['model'])\n#     pseudo_model.to(device)\n\n#     del checkpoint\n#     gc.collect()\n    \n# else:\n#     state_dict = main(train_opt)\n#     pseudo_model.load_state_dict(state_dict)\n#     pseudo_model.to(device)\n    \n#     del state_dict\n#     gc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"gc.collect()\ntorch.cuda.empty_cache()\n\npseudo_model = PoseBiFPNNet(train_opt.arch, train_opt.heads, train_opt.head_conv)\n\nif len(os.listdir(DIR_TEST)) < 20:\n    train_opt.total_epochs = 2\n    train_opt.stage_epochs = 2\n    data_dict_train = data_dict_train[:300]\n    \n    state_dict = main(train_opt)\n    change_key(state_dict)\n    \n    pseudo_model.load_state_dict(state_dict)\n    pseudo_model.to(device)\n    \n    del state_dict\n    gc.collect()\n    \nelse:\n    state_dict = main(train_opt)\n    change_key(state_dict)\n    \n    pseudo_model.load_state_dict(state_dict)\n    pseudo_model.to(device)\n    \n    del state_dict\n    gc.collect()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Inference using pseudo model","execution_count":null},{"metadata":{"trusted":true,"_kg_hide-output":true},"cell_type":"code","source":"opt.pad = 63\n\nopt.test_scales = [1.1, ]\nthreshold = 0.32\n\npseudo_pred_boxes_0   , pseudo_pred_scores_0, h0_list, w0_list, img_ids = do_predict(opt, pseudo_model, threshold=threshold, flip_type=0, return_ids=True, return_shapes=True)\npseudo_pred_boxes_0_lr, pseudo_pred_scores_0_lr = do_predict(opt, pseudo_model, threshold=threshold, flip_type=1, return_ids=False, return_shapes=False)\npseudo_pred_boxes_0_ud, pseudo_pred_scores_0_ud = do_predict(opt, pseudo_model, threshold=threshold, flip_type=2, return_ids=False, return_shapes=False)\n\n\nopt.test_scales = [1.25, ]\nthreshold = 0.30\n\npseudo_pred_boxes_l   , pseudo_pred_scores_l    = do_predict(opt, pseudo_model, threshold=threshold, flip_type=0, return_ids=False, return_shapes=False)\npseudo_pred_boxes_l_lr, pseudo_pred_scores_l_lr = do_predict(opt, pseudo_model, threshold=threshold, flip_type=1, return_ids=False, return_shapes=False)\npseudo_pred_boxes_l_ud, pseudo_pred_scores_l_ud = do_predict(opt, pseudo_model, threshold=threshold, flip_type=2, return_ids=False, return_shapes=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"iou_thr = 0.44\nskip_box_thr = 0.00001\n\npred_boxes_pseudo = []\npred_scores_pseudo = []\nfor (b00, b01, b02, b03, b04, b05,\n     s00, s01, s02, s03, s04, s05,\n     h0, w0) in zip(\n    tqdm(pseudo_pred_boxes_0), \n    pseudo_pred_boxes_0_lr, \n    pseudo_pred_boxes_0_ud,\n    pseudo_pred_boxes_l,\n    pseudo_pred_boxes_l_lr,\n    pseudo_pred_boxes_l_ud,\n    \n    \n    pseudo_pred_scores_0,\n    pseudo_pred_scores_0_lr, \n    pseudo_pred_scores_0_ud,\n    pseudo_pred_scores_l,\n    pseudo_pred_scores_l_lr,\n    pseudo_pred_scores_l_ud,\n\n    h0_list,\n    w0_list):\n    \n    \n    boxes_list = [\n        normalize_boxes(b00, h0, w0).tolist(),\n        normalize_boxes(b01, h0, w0).tolist(),\n        normalize_boxes(b02, h0, w0).tolist(),\n        normalize_boxes(b03, h0, w0).tolist(),\n        normalize_boxes(b04, h0, w0).tolist(),\n        normalize_boxes(b05, h0, w0).tolist()\n    ]\n    \n    scores_list = [\n        s00.tolist(),\n        s01.tolist(),\n        s02.tolist(),\n        s03.tolist(),\n        s04.tolist(),\n        s05.tolist()\n    ]\n    \n    labels_list = [\n        [0] * len(b00),\n        [0] * len(b01),\n        [0] * len(b02),\n        [0] * len(b03),\n        [0] * len(b04),\n        [0] * len(b05)\n    ]\n    \n    boxes, scores, _ = ensemble_boxes.ensemble_boxes_wbf.weighted_boxes_fusion(boxes_list, scores_list, labels_list, iou_thr=iou_thr, skip_box_thr=skip_box_thr)\n    pred_boxes_pseudo.append(boxes)\n    pred_scores_pseudo.append(scores)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pred_boxes_pseudo = [denormalize_clip_boxes(a, h0, w0) for a, h0, w0 in zip(pred_boxes_pseudo, h0_list, w0_list)]\npred_scores_pseudo = [a for a in pred_scores_pseudo]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# visualization\nidx = -7\nimg = testdataset[idx][2]\nprint(testdataset[idx][1])\nvisualize({'image': img, 'bboxes': (pred_boxes_pseudo[idx]).astype(int), 'scores': pred_scores_pseudo[idx]})","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Generate Submission file","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def format_prediction_string(boxes, scores):\n    pred_strings = []\n    for s, b in zip(scores, boxes.astype(int)):\n        # xmin, ymin, w, h\n        pred_strings.append(f'{s:.4f} {b[0]} {b[1]} {b[2]} {b[3]}')\n    #print(\" \".join(pred_strings))\n    return \" \".join(pred_strings)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pred_strs = []\nfor bboxes, scores in zip(pred_boxes_pseudo, pred_scores_pseudo):\n    \n    if len(bboxes) > 0:\n        \n        bboxes[:, 2] -= bboxes[:, 0]\n        bboxes[:, 3] -= bboxes[:, 1]\n        bboxes = bboxes.round()\n\n        pred_strs.append(format_prediction_string(bboxes, scores))\n        \n    else:\n        pred_strs.append('')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df = pd.DataFrame({'image_id': img_ids, 'PredictionString':pred_strs})\ntest_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_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}