{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"# https://github.com/AlexeyAB/darknet#how-to-train-to-detect-your-custom-objects","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Autoreloads external files without having to restart the notebook\n%load_ext autoreload\n%autoreload 2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!ls ../input","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!ls ../input/darknet-wheat/\n!ls ../input/darknet-gpu/","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!cp -r ../input/darknet-wheat/* .\n\n!cp ../input/darknet-gpu/darknet .\n!cp ../input/darknet-gpu/darknet.py .\n!cp ../input/darknet-gpu/libdarknet.so .\n\n!chmod a+x ./darknet\n!ls -la .","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# !cat darknet.py\n# !./darknet","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import sys\nsys.path.insert(0, \"../input/weightedboxesfusion/\")\n\nimport pandas as pd\nimport numpy as np\nimport os\nfrom datetime import datetime\nimport time\nimport random\nimport json\nimport collections\nimport shutil as sh\n\nfrom PIL import Image\nimport cv2\nimport matplotlib.pyplot as plt\nimport matplotlib.patches as patches\n%matplotlib inline\n\nfrom sklearn.model_selection import StratifiedKFold\n\nimport darknet as dn\nfrom ensemble_boxes import *\n\n# from skopt import gp_minimize, forest_minimize\n# from skopt.utils import use_named_args\n# from skopt.plots import plot_objective, plot_evaluations, plot_convergence, plot_regret\n# from skopt.space import Categorical, Integer, Real\n\nimport torch\n\nimport gc\ngc.enable()\n\nnp.set_printoptions(suppress=True)\n\nprint('PyTorch version', torch.__version__)\n\nSEED = 1120\n# SEED = 42\n\nimage_width = 1024\nimage_height = 1024\n\nbatch=64\n# subdivisions=16\nsubdivisions=32\n# subdivisions=64\nburn_in = 0\n\n# Prediction confidence score\nprob_threhold = 0.5\n\n# WBF\n# iou_thr = 0.55\n# skip_box_thr = 0.43\niou_thr = 0.55\nskip_box_thr = 0.1\n\nmodel_image_sizes = [1024, 1024, 1024, 1024, 1024]\n\n# [Local Env]\n# dataset_folder = \"/workspace/Kaggle/Wheat\"\n# train_image_folder = \"/workspace/Kaggle/Wheat/train\"\n# test_image_folder = \"/workspace/Kaggle/Wheat/test\"\n\n# meta_file = b\"/workspace/Github/darknet/build/darknet/x64/data/wheat_notebook.data\"\n# model_cfg_files = [\n#     b\"./darknet_wheat/yolov4-v3-20000iter/yolov4-mish-416-wheat-v3.cfg\",\n#     b\"./darknet_wheat/yolov4-v3-20000iter-fold1/yolov4-mish-416-wheat-v3-fold1.cfg\",\n#     b\"./darknet_wheat/yolov4-v3-20000iter-fold2/yolov4-mish-416-wheat-v3-fold2.cfg\",\n#     b\"./darknet_wheat/yolov4-v3-20000iter-fold3/yolov4-mish-416-wheat-v3-fold3.cfg\",\n#     b\"./darknet_wheat/yolov4-v3-20000iter-fold4/yolov4-mish-416-wheat-v3-fold4.cfg\",\n# ]\n# model_weights_files = [\n#     b\"./darknet_wheat/yolov4-v3-20000iter/yolov4-mish-416-wheat-v3_best.weights\",\n#     b\"./darknet_wheat/yolov4-v3-20000iter-fold1/yolov4-mish-416-wheat-v3-fold1_best.weights\",\n#     b\"./darknet_wheat/yolov4-v3-20000iter-fold2/yolov4-mish-416-wheat-v3-fold2_best.weights\",\n#     b\"./darknet_wheat/yolov4-v3-20000iter-fold3/yolov4-mish-416-wheat-v3-fold3_best.weights\",\n#     b\"./darknet_wheat/yolov4-v3-20000iter-fold4/yolov4-mish-416-wheat-v3-fold4_best.weights\",\n# ]\n\n# [Kaggle Env]\ndataset_folder = \"../input/global-wheat-detection/\"\ntrain_image_folder = \"../input/global-wheat-detection/train\"\ntest_image_folder = \"../input/global-wheat-detection/test\"\n\nmeta_file = b\"data/wheat.data\"\nmodel_cfg_files = [\n#     b\"./yolov4-v3-20000iter/yolov4-mish-416-wheat-v3.cfg\",\n#     b\"./yolov4-v3-20000iter-fold1/yolov4-mish-416-wheat-v3-fold1.cfg\",\n    b\"./yolov4-v3-20000iter-fold2/yolov4-mish-416-wheat-v3-fold2.cfg\",\n#     b\"./yolov4-v3-20000iter-fold3/yolov4-mish-416-wheat-v3-fold3.cfg\",\n#     b\"./yolov4-v3-20000iter-fold4/yolov4-mish-416-wheat-v3-fold4.cfg\",\n]\nmodel_weights_files = [\n#     b\"./yolov4-v3-20000iter/yolov4-mish-416-wheat-v3_best.weights\",\n#     b\"./yolov4-v3-20000iter-fold1/yolov4-mish-416-wheat-v3-fold1_best.weights\",\n    b\"./yolov4-v3-20000iter-fold2/yolov4-mish-416-wheat-v3-fold2_best.weights\",\n#     b\"./yolov4-v3-20000iter-fold3/yolov4-mish-416-wheat-v3-fold3_best.weights\",\n#     b\"./yolov4-v3-20000iter-fold4/yolov4-mish-416-wheat-v3-fold4_best.weights\",\n]\n\n# used for fast inference in submission\nUSE_OPTIMIZE = len(os.listdir(test_image_folder)) == 10  \n\n# About 2310 iterations per epoch\nif USE_OPTIMIZE:\n    iteration_offset = 0\n    pseudo_iterations = 10 # 4 minutes\n    # pseudo_iterations = 50 # 20 minutes\nelse:\n    iteration_offset = 0\n    # pseudo_iterations = 600 # 4 hours\n    pseudo_iterations = 1000\n\n\ndef seed_everything(seed):\n    random.seed(seed)\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    np.random.seed(seed)\n\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = False\n\n\nseed_everything(SEED)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# https://www.kaggle.com/c/global-wheat-detection/discussion/159578\nbad_images = [\n    \"41c0123cc\",\n    \"a1321ca95\",\n    \"2cc75e9f5\",\n    \"42e6efaaa\",\n    \"409a8490c\",\n    \"d067ac2b1\",\n    \"d60e832a5\",\n    \"893938464\",\n]\n\nbad_boxes = [\n    3687, 117344, 173, 113947, 52868, 2159, 2169, 121633, 121634, 147504,\n    118211, 52727, 147552\n]","execution_count":null,"outputs":[]},{"metadata":{"heading_collapsed":true},"cell_type":"markdown","source":"## Create Stratified K-Folds","execution_count":null},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"marking_df = pd.read_csv(f\"{dataset_folder}/train.csv\")\n\n# replace nan values with zeros\nmarking_df['bbox'] = marking_df.bbox.fillna('[0,0,0,0]')\n\nbboxs = np.stack(\n    marking_df['bbox'].apply(lambda x: np.fromstring(x[1:-1], sep=',')))\nfor i, column in enumerate(['x', 'y', 'w', 'h']):\n    marking_df[column] = bboxs[:, i]\nmarking_df.drop(columns=['bbox'], inplace=True)\n\nmarking_df[\"id\"] = marking_df.index.tolist()\n\nmarking_df['x_center'] = marking_df['x'] + marking_df['w'] / 2\nmarking_df['y_center'] = marking_df['y'] + marking_df['h'] / 2\nmarking_df['classes'] = 0","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"# Drop bad bboxes\ndataset_df = marking_df[~marking_df[\"id\"].isin(bad_boxes)].copy()\nassert dataset_df.shape[0] + len(bad_boxes) == marking_df.shape[0]\nprint(marking_df.shape, dataset_df.shape)\ndataset_df = dataset_df[~dataset_df[\"image_id\"].isin(bad_images)].copy()\nprint(marking_df.shape, dataset_df.shape)","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"n_folds = 5\nskf = StratifiedKFold(n_splits=n_folds, shuffle=True, random_state=SEED)\nskf","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"df_folds = dataset_df[['image_id']].copy()\ndf_folds.loc[:, 'bbox_count'] = 1\ndf_folds = df_folds.groupby('image_id').count()\n\ndf_folds.loc[:, 'source'] = dataset_df[['image_id', 'source'\n                                        ]].groupby('image_id').min()['source']\n\ndf_folds.loc[:, 'stratify_group'] = np.char.add(\n    df_folds['source'].values.astype(str),\n    df_folds['bbox_count'].apply(lambda x: f'_{x // 15}').values.astype(str))\ndf_folds.loc[:, 'fold'] = 0\n\nfor fold_number, (train_index, val_index) in enumerate(\n        skf.split(X=df_folds.index, y=df_folds['stratify_group'])):\n    df_folds.loc[df_folds.iloc[val_index].index, 'fold'] = fold_number\n\ndf_folds = df_folds.reset_index()","execution_count":null,"outputs":[]},{"metadata":{"heading_collapsed":true},"cell_type":"markdown","source":"## Utility Functions","execution_count":null},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"# https://www.kaggle.com/pestipeti/pytorch-starter-fasterrcnn-inference\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(\n            j[0], j[1][0], j[1][1], j[1][2], j[1][3]))\n\n    return \" \".join(pred_strings)\n\n\ndef process_detection_result(bboxes, resize_width, prob_threhold=0.5):\n    scores = np.zeros((len(bboxes)))\n    numpy_bboxes = np.zeros((len(bboxes), 4))\n    for i, bbox in enumerate(bboxes):\n        scores[i] = bbox[1]\n        cord = bbox[2]\n\n        # Convert center (x,y, w, h) to (x1, y1, x2, y2)\n        x1 = cord[0] - cord[2] / 2\n        y1 = cord[1] - cord[3] / 2\n        x2 = cord[0] + cord[2] / 2\n        y2 = cord[1] + cord[3] / 2\n\n        # Convert to original resolution\n        x1 /= resize_width\n        y1 /= resize_width\n        x2 /= resize_width\n        y2 /= resize_width\n\n        x1 *= image_width\n        y1 *= image_width\n        x2 *= image_width\n        y2 *= image_width\n\n        x1 = int(round(max(min(x1, image_width - 1), 0)))\n        y1 = int(round(max(min(y1, image_width - 1), 0)))\n        x2 = int(round(max(min(x2, image_width - 1), 0)))\n        y2 = int(round(max(min(y2, image_width - 1), 0)))\n\n        numpy_bboxes[i, :] = np.array([x1, y1, x2, y2])\n\n    indexes = np.where(scores > prob_threhold)\n    numpy_bboxes = numpy_bboxes[indexes]\n    scores = scores[indexes]\n\n    return scores, numpy_bboxes","execution_count":null,"outputs":[]},{"metadata":{"heading_collapsed":true},"cell_type":"markdown","source":"## TTA Functions","execution_count":null},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"class BaseWheatTTA:\n    \"\"\" author: @shonenkov \"\"\"\n    image_size = image_width\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\n\nclass TTAHorizontalFlip(BaseWheatTTA):\n    \"\"\" author: @shonenkov \"\"\"\n    def augment(self, image):\n        image = np.fliplr(image)\n        return image\n        # return image.flip(1)\n\n    def batch_augment(self, images):\n        images = np.fliplr(images)\n        return images\n        # return images.flip(2)\n\n    def deaugment_boxes(self, boxes):\n        boxes[:, [0, 2]] = self.image_size - boxes[:, [2, 0]]\n        return boxes\n\n\nclass TTAVerticalFlip(BaseWheatTTA):\n    \"\"\" author: @shonenkov \"\"\"\n    def augment(self, image):\n        image = np.flipud(image)\n        return image\n        # return image.flip(2)\n\n    def batch_augment(self, images):\n        images = np.flipud(images)\n        return images\n        # return images.flip(3)\n\n    def deaugment_boxes(self, boxes):\n        boxes[:, [3, 1]] = self.image_size - boxes[:, [1, 3]]\n        return boxes\n\n\nclass TTARotate90(BaseWheatTTA):\n    \"\"\" author: @shonenkov \"\"\"\n    def augment(self, image):\n        image = np.rot90(image, k=1, axes=(0, 1))\n        return image\n        # return torch.rot90(image, 1, (1, 2))\n\n    def batch_augment(self, images):\n        images = np.rot90(images, k=1, axes=(1, 2))\n        return 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\n\nclass TTARotate180(BaseWheatTTA):\n    def augment(self, image):\n        tmp = np.rot90(image, k=1, axes=(0, 1))\n        tmp = np.rot90(tmp, k=1, axes=(0, 1))\n        # tmp = np.rot90(image, k=1, axes=(1, 2))\n        # tmp = np.rot90(tmp, k=1, axes=(1, 2))\n        return tmp\n        # tmp = torch.rot90(image, 1, (1, 2))\n        # return torch.rot90(tmp, 1, (1, 2))\n\n    def batch_augment(self, images):\n        tmp = np.rot90(images, k=1, axes=(1, 2))\n        tmp = np.rot90(tmp, k=1, axes=(1, 2))\n        # tmp = np.rot90(images, k=1, axes=(2, 3))\n        # tmp = np.rot90(tmp, k=1, axes=(2, 3))\n        return tmp\n        # tmp = torch.rot90(images, 1, (2, 3))\n        # return torch.rot90(tmp, 1, (2, 3))\n\n    def deaugment_boxes(self, boxes):\n        tmp = TTARotate90().deaugment_boxes(boxes)\n        return TTARotate90().deaugment_boxes(tmp)\n\n\nclass TTARotate270(BaseWheatTTA):\n    def augment(self, image):\n        tmp = TTARotate180().augment(image)\n        tmp = np.rot90(tmp, k=1, axes=(0, 1))\n        return tmp\n        # return torch.rot90(tmp, 1, (1, 2))\n\n    def batch_augment(self, images):\n        tmp = TTARotate180().batch_augment(images)\n        tmp = np.rot90(tmp, k=1, axes=(1, 2))\n        return tmp\n        # return torch.rot90(tmp, 1, (2, 3))\n\n    def deaugment_boxes(self, boxes):\n        tmp = TTARotate180().deaugment_boxes(boxes)\n        return TTARotate90().deaugment_boxes(tmp)\n\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":{"heading_collapsed":true},"cell_type":"markdown","source":"## Model Loading Test","execution_count":null},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"# import darknet as dn\n# meta_file = b\"/workspace/Github/darknet/build/darknet/x64/data/wheat_notebook.data\"\n# cfg = b\"/workspace/Github/darknet/build/darknet/x64/yolov4-mish-416-wheat-v3.cfg\"\n# weights = b\"/workspace/Github/darknet/build/darknet/x64/backup/yolov4-mish-416-wheat-v3_best.weights\"\n# net = dn.load_net_custom(cfg, weights, 0, 1)\n# meta = dn.load_meta(meta_file)","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"# net","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"# dn.free_network_ptr(net)","execution_count":null,"outputs":[]},{"metadata":{"heading_collapsed":true},"cell_type":"markdown","source":"## Predict Test Dataset","execution_count":null},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"def run_wbf(preds, image_size=image_width,\n            iou_thr=0.55, skip_box_thr=0.7, weights=None):\n    boxes = [(p['boxes'] / (image_size-1)).tolist() for p in preds]\n    scores = [p['scores'].tolist() for p in preds]\n    labels = [np.ones(p['scores'].shape[0]).astype(int).tolist() for p in preds]\n    \n    # print(boxes)\n    boxes, scores, labels = ensemble_boxes_wbf.weighted_boxes_fusion(\n        boxes, scores, labels, weights=weights, 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":{"hidden":true,"trusted":true},"cell_type":"code","source":"from itertools import product\n\ntta_transforms = []\n\nfor tta_combination in product([TTAHorizontalFlip(), None], \n                               [TTAVerticalFlip(), None],\n                               [TTARotate90(), None]):\n    tta_transforms.append(\n        TTACompose([\n            tta_transform for tta_transform in tta_combination if tta_transform\n        ]))","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"def detect(net, meta, darknet_image, target_image, prob_threshold=.5):\n    dn.copy_image_from_bytes(darknet_image, target_image.tobytes())\n    return dn.detect_image(net,\n                           meta,\n                           darknet_image,\n                           thresh=prob_threshold,\n                           hier_thresh=.5,\n                           nms=.45)\n\n\n# Modified from: https://www.kaggle.com/nvnnghia/yolov4-inference\ndef predict_test(batch_size=1, prob_threhold=0.5):\n    image_names = os.listdir(test_image_folder)\n\n    # Store results by image\n    image_pred_results = collections.defaultdict(list)\n    for model_index, cfg in enumerate(model_cfg_files):\n        print(f\"Generating inference for model cfg file {cfg} ......\")\n\n        weights = model_weights_files[model_index]\n        net = dn.load_net_custom(cfg, weights, 0, batch_size)\n        meta = dn.load_meta(meta_file)\n\n        resize = model_image_sizes[model_index]\n\n        # Create an image we reuse for each detect\n        darknet_image = dn.make_image(resize, resize, 3)\n\n        for name in image_names:\n            image_id = name.split('.')[0]\n\n            image = cv2.imread(f'{test_image_folder}/{image_id}.jpg')\n            image = cv2.resize(image, (resize, resize))\n            image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n\n            infer_start = time.time()\n\n            # Test time augmentation\n            for tta in tta_transforms:\n                tta_image = tta.augment(image)\n\n                preds = detect(net, meta, darknet_image, tta_image)\n                scores, preds = process_detection_result(\n                    preds, resize, prob_threhold)\n\n                # Convert back to the orignal coordinations\n                preds = tta.deaugment_boxes(preds)\n                preds = preds.clip(min=0, max=image_width - 1)\n\n                image_pred_results[name].append({\n                    'boxes': preds,\n                    'scores': scores,\n                })\n\n            print(\n                f\"Time spent on augmented inference for {name}: {time.time() - infer_start:2f} seconds\"\n            )\n\n            del image, preds\n            gc.collect()\n\n        dn.free_network_ptr(net)\n        del net, meta\n        gc.collect()\n\n    return image_pred_results\n\n\ndef ensemble(image_pred_results, iou_thr=0.5, skip_box_thr=0.1):\n    ensemble_results = {}\n\n    image_names = os.listdir(test_image_folder)\n    for name in image_names:\n        print(f\"Running ensemble by WBF for {name} ......\")\n        image_id = name.split('.')[0]\n\n        tta_preds = image_pred_results[name]\n\n        boxes, scores, labels = run_wbf(tta_preds,\n                                        iou_thr=iou_thr,\n                                        skip_box_thr=skip_box_thr)\n        boxes = boxes.round().astype(np.int32).clip(min=0, max=image_width - 1)\n\n        # Convert to width and height\n        boxes[:, 2] = boxes[:, 2] - boxes[:, 0]\n        boxes[:, 3] = boxes[:, 3] - boxes[:, 1]\n\n        ensemble_results[name] = {\n            'boxes': boxes,\n            'scores': scores,\n        }\n\n    return ensemble_results\n\n\ndef generate_submit(ensemble_results):\n    results = []\n\n    count = 0\n    image_names = os.listdir(test_image_folder)\n    for name in image_names:\n        image_id = name.split('.')[0]\n\n        if len(image_names) < 11:\n            image = cv2.imread(f'{test_image_folder}/{image_id}.jpg')\n            image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n\n        r = ensemble_results[name]\n        boxes, scores = r[\"boxes\"], r[\"scores\"]\n\n        results.append({\n            'image_id':\n            image_id,\n            'PredictionString':\n            format_prediction_string(boxes, scores)\n        })\n\n        if len(image_names) < 11 and count < 10:\n            fig, ax = plt.subplots(1, 1, figsize=(20, 10))\n            for box, score in zip(boxes, scores):\n                cv2.rectangle(image, (box[0], box[1], box[2], box[3]),\n                              color=(99, 228, 255),\n                              thickness=4)\n                cv2.putText(\n                    image,\n                    f\"{score:.2f}\",\n                    (box[0], box[1] + box[3] - 5),\n                    cv2.FONT_HERSHEY_SIMPLEX,\n                    0.8,  # fontScale\n                    (255, 255, 255),\n                    2,  # thickness\n                    cv2.LINE_AA)\n            ax.imshow(image)\n            count += 1\n\n    return results","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"scrolled":true,"trusted":true},"cell_type":"code","source":"pred_start = time.time()\ntest_preds = predict_test(batch_size=1, prob_threhold=prob_threhold)\nprint(\n    f\"Time spent on generating submission predictions: {time.time() - pred_start:2f} seconds\"\n)","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"pred_start = time.time()\nensemble_results = ensemble(test_preds,\n                            iou_thr=iou_thr,\n                            skip_box_thr=skip_box_thr)\nprint(f\"Time spent on ensemble: {time.time() - pred_start:2f} seconds\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Pseudo Labeling","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"!mkdir -p data/wheat backup","execution_count":null,"outputs":[]},{"metadata":{"heading_collapsed":true},"cell_type":"markdown","source":"### Create Dataset Files","execution_count":null},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"with open(\"./data/wheat.names\", 'w') as out:\n    out.write(\"wheat\\n\")","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"!cat ./data/wheat.names","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"with open(f\"./data/wheat_pseudo.data\", 'w') as out:\n    out.write(\"classes= 1\\n\")\n    out.write(f\"train = data/train_wheat_pseudo.txt\\n\")\n    out.write(f\"valid = data/valid_wheat_pseudo.txt\\n\")\n    out.write(\"names  = data/wheat.names\\n\")\n    out.write(\"backup = backup\")","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"!cat ./data/wheat_pseudo.data","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"fold_id = 0\n\nfold_train_df, fold_val_df = df_folds[~(df_folds[\"fold\"] == fold_id)].copy(\n), df_folds[df_folds[\"fold\"] == fold_id].copy()\n\nassert fold_train_df.shape[0] + fold_val_df.shape[0] == df_folds.shape[0]\nfold_train_df.shape[0], fold_val_df.shape[0]","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"with open(f\"./data/train_wheat_pseudo.txt\", 'w') as out:\n    training_image_ids = []\n    for image_id in fold_train_df[\"image_id\"].unique():\n        training_image_ids.append((image_id, True))\n\n    for name in os.listdir(test_image_folder):\n        image_id = name.split('.')[0]\n        training_image_ids.append((image_id, False))\n\n    # Shuffle images to avoid overfitting\n    random.shuffle(training_image_ids)\n\n    for (image_id, is_train) in training_image_ids:\n        if is_train:\n            sh.copy(f\"{train_image_folder}/{image_id}.jpg\",\n                    f\"./data/wheat/{image_id}.jpg\")\n            out.write(f\"./data/wheat/{image_id}.jpg\\n\")\n        else:\n            # Resize to ensure correct size\n            image = cv2.imread(f\"{test_image_folder}/{image_id}.jpg\")\n            image = cv2.resize(image, (image_width, image_height))\n            cv2.imwrite(f\"./data/wheat/{image_id}.jpg\", image)\n            out.write(f\"./data/wheat/{image_id}.jpg\\n\")","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"!ls -la ./data/wheat | head -n 10","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"scrolled":true,"trusted":true},"cell_type":"code","source":"# !cat ./data/train_wheat_pseudo.txt","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"with open(f\"./data/valid_wheat_pseudo.txt\", 'w') as out:\n    image_ids_with_head = fold_val_df[\"image_id\"].unique()\n    for image_id in image_ids_with_head:\n        sh.copy(f\"{train_image_folder}/{image_id}.jpg\",\n                f\"./data/wheat/{image_id}.jpg\")\n        out.write(f\"./data/wheat/{image_id}.jpg\\n\")","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"# !cat ./data/valid_wheat_pseudo.txt","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"for image_id in df_folds[\"image_id\"].unique():\n    df = dataset_df[dataset_df[\"image_id\"] == image_id].copy()\n    with open(f\"./data/wheat/{image_id}.txt\", 'w') as out:\n        for index, row in df.iterrows():\n            if row['x_center'] > 0 and row[\n                    'y_center'] and row['w'] > 0 and row['h'] > 0:\n\n                out.write(f\"{row['classes']} \" +\n                          f\"{row['x_center']/image_width} \" +\n                          f\"{row['y_center']/image_height} \" +\n                          f\"{row['w']/image_width} \" +\n                          f\"{row['h']/image_height}\\n\")","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"len(ensemble_results)","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"for name in os.listdir(test_image_folder):\n    image_id = name.split('.')[0]\n\n    with open(f\"./data/wheat/{image_id}.txt\", 'w') as out:\n        r = ensemble_results[name]\n        boxes, scores = r[\"boxes\"], r[\"scores\"]\n\n        # Convert (x, y, w, h) to (center x, center y, w, h)\n        boxes[:, 0] = boxes[:, 0] + boxes[:, 2] / 2\n        boxes[:, 1] = boxes[:, 1] + boxes[:, 3] / 2\n\n        print(boxes.shape)\n        for i in range(boxes.shape[0]):\n            box = boxes[i, :]\n            if box[0] > 0 and box[1] > 0 and box[2] > 0 and box[3] > 0:\n                out.write(f\"0 \" + f\"{box[0]/image_width} \" +\n                          f\"{box[1]/image_height} \" +\n                          f\"{box[2]/image_width} \" +\n                          f\"{box[3]/image_height}\\n\")","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"# os.listdir(test_image_folder)","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"# !cat ./data/wheat/2fd875eaa.txt","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"# !cat ./data/wheat/51b3e36ab.txt | wc -l","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"# ! cat ./data/wheat/{os.listdir(train_image_folder)[0][:-4]}.txt | wc -l","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"# os.listdir(test_image_folder)","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"# !cat ./data/wheat/51b3e36ab.txt | wc -l","execution_count":null,"outputs":[]},{"metadata":{"heading_collapsed":true},"cell_type":"markdown","source":"### Create Config File","execution_count":null},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"cfg_content = f\"\"\"\n# [V3]\n# With pseudo labels\n# mosaic=0\n\n[net]\nbatch={batch}\nsubdivisions={subdivisions}\n\nwidth=608\nheight=608\n\nchannels=3\nmomentum=0.949\ndecay=0.0005\nangle=0\nsaturation = 1.5\nexposure = 1.5\nhue=.1\n\nlearning_rate=0.0005\n# learning_rate=0.001\n\nburn_in={burn_in}\n\nmax_batches = {iteration_offset+pseudo_iterations}\npolicy=steps\nsteps={int(0.8*(iteration_offset+pseudo_iterations))},{int(0.9*(iteration_offset+pseudo_iterations))}\nscales=.1,.1\n\n# mosaic=1\nblur=1\ngaussian_noise=1\n# https://github.com/AlexeyAB/darknet/issues/4446\n# cutmix=1 # for training Classifier\n# mixup=1 # for training Classifier\n\n[convolutional]\nbatch_normalize=1\nfilters=32\nsize=3\nstride=1\npad=1\nactivation=mish\n\n# Downsample\n\n[convolutional]\nbatch_normalize=1\nfilters=64\nsize=3\nstride=2\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=64\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[route]\nlayers = -2\n\n[convolutional]\nbatch_normalize=1\nfilters=64\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=32\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=64\nsize=3\nstride=1\npad=1\nactivation=mish\n\n[shortcut]\nfrom=-3\nactivation=linear\n\n[convolutional]\nbatch_normalize=1\nfilters=64\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[route]\nlayers = -1,-7\n\n[convolutional]\nbatch_normalize=1\nfilters=64\nsize=1\nstride=1\npad=1\nactivation=mish\n\n# Downsample\n\n[convolutional]\nbatch_normalize=1\nfilters=128\nsize=3\nstride=2\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=64\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[route]\nlayers = -2\n\n[convolutional]\nbatch_normalize=1\nfilters=64\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=64\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=64\nsize=3\nstride=1\npad=1\nactivation=mish\n\n[shortcut]\nfrom=-3\nactivation=linear\n\n[convolutional]\nbatch_normalize=1\nfilters=64\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=64\nsize=3\nstride=1\npad=1\nactivation=mish\n\n[shortcut]\nfrom=-3\nactivation=linear\n\n[convolutional]\nbatch_normalize=1\nfilters=64\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[route]\nlayers = -1,-10\n\n[convolutional]\nbatch_normalize=1\nfilters=128\nsize=1\nstride=1\npad=1\nactivation=mish\n\n# Downsample\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=3\nstride=2\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=128\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[route]\nlayers = -2\n\n[convolutional]\nbatch_normalize=1\nfilters=128\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=128\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=128\nsize=3\nstride=1\npad=1\nactivation=mish\n\n[shortcut]\nfrom=-3\nactivation=linear\n\n[convolutional]\nbatch_normalize=1\nfilters=128\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=128\nsize=3\nstride=1\npad=1\nactivation=mish\n\n[shortcut]\nfrom=-3\nactivation=linear\n\n[convolutional]\nbatch_normalize=1\nfilters=128\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=128\nsize=3\nstride=1\npad=1\nactivation=mish\n\n[shortcut]\nfrom=-3\nactivation=linear\n\n[convolutional]\nbatch_normalize=1\nfilters=128\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=128\nsize=3\nstride=1\npad=1\nactivation=mish\n\n[shortcut]\nfrom=-3\nactivation=linear\n\n\n[convolutional]\nbatch_normalize=1\nfilters=128\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=128\nsize=3\nstride=1\npad=1\nactivation=mish\n\n[shortcut]\nfrom=-3\nactivation=linear\n\n[convolutional]\nbatch_normalize=1\nfilters=128\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=128\nsize=3\nstride=1\npad=1\nactivation=mish\n\n[shortcut]\nfrom=-3\nactivation=linear\n\n[convolutional]\nbatch_normalize=1\nfilters=128\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=128\nsize=3\nstride=1\npad=1\nactivation=mish\n\n[shortcut]\nfrom=-3\nactivation=linear\n\n[convolutional]\nbatch_normalize=1\nfilters=128\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=128\nsize=3\nstride=1\npad=1\nactivation=mish\n\n[shortcut]\nfrom=-3\nactivation=linear\n\n[convolutional]\nbatch_normalize=1\nfilters=128\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[route]\nlayers = -1,-28\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=1\nstride=1\npad=1\nactivation=mish\n\n# Downsample\n\n[convolutional]\nbatch_normalize=1\nfilters=512\nsize=3\nstride=2\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[route]\nlayers = -2\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=3\nstride=1\npad=1\nactivation=mish\n\n[shortcut]\nfrom=-3\nactivation=linear\n\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=3\nstride=1\npad=1\nactivation=mish\n\n[shortcut]\nfrom=-3\nactivation=linear\n\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=3\nstride=1\npad=1\nactivation=mish\n\n[shortcut]\nfrom=-3\nactivation=linear\n\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=3\nstride=1\npad=1\nactivation=mish\n\n[shortcut]\nfrom=-3\nactivation=linear\n\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=3\nstride=1\npad=1\nactivation=mish\n\n[shortcut]\nfrom=-3\nactivation=linear\n\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=3\nstride=1\npad=1\nactivation=mish\n\n[shortcut]\nfrom=-3\nactivation=linear\n\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=3\nstride=1\npad=1\nactivation=mish\n\n[shortcut]\nfrom=-3\nactivation=linear\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=3\nstride=1\npad=1\nactivation=mish\n\n[shortcut]\nfrom=-3\nactivation=linear\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[route]\nlayers = -1,-28\n\n[convolutional]\nbatch_normalize=1\nfilters=512\nsize=1\nstride=1\npad=1\nactivation=mish\n\n# Downsample\n\n[convolutional]\nbatch_normalize=1\nfilters=1024\nsize=3\nstride=2\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=512\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[route]\nlayers = -2\n\n[convolutional]\nbatch_normalize=1\nfilters=512\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=512\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=512\nsize=3\nstride=1\npad=1\nactivation=mish\n\n[shortcut]\nfrom=-3\nactivation=linear\n\n[convolutional]\nbatch_normalize=1\nfilters=512\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=512\nsize=3\nstride=1\npad=1\nactivation=mish\n\n[shortcut]\nfrom=-3\nactivation=linear\n\n[convolutional]\nbatch_normalize=1\nfilters=512\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=512\nsize=3\nstride=1\npad=1\nactivation=mish\n\n[shortcut]\nfrom=-3\nactivation=linear\n\n[convolutional]\nbatch_normalize=1\nfilters=512\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=512\nsize=3\nstride=1\npad=1\nactivation=mish\n\n[shortcut]\nfrom=-3\nactivation=linear\n\n[convolutional]\nbatch_normalize=1\nfilters=512\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[route]\nlayers = -1,-16\n\n[convolutional]\nbatch_normalize=1\nfilters=1024\nsize=1\nstride=1\npad=1\nactivation=mish\n\n##########################\n\n[convolutional]\nbatch_normalize=1\nfilters=512\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nsize=3\nstride=1\npad=1\nfilters=1024\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=512\nsize=1\nstride=1\npad=1\nactivation=mish\n\n### SPP ###\n[maxpool]\nstride=1\nsize=5\n\n[route]\nlayers=-2\n\n[maxpool]\nstride=1\nsize=9\n\n[route]\nlayers=-4\n\n[maxpool]\nstride=1\nsize=13\n\n[route]\nlayers=-1,-3,-5,-6\n### End SPP ###\n\n[convolutional]\nbatch_normalize=1\nfilters=512\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nsize=3\nstride=1\npad=1\nfilters=1024\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=512\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[upsample]\nstride=2\n\n[route]\nlayers = 85\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[route]\nlayers = -1, -3\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nsize=3\nstride=1\npad=1\nfilters=512\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nsize=3\nstride=1\npad=1\nfilters=512\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=128\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[upsample]\n# stride=4\nstride=2\n\n[route]\n# layers = 23\nlayers = 54\n\n[convolutional]\nbatch_normalize=1\nfilters=128\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[route]\nlayers = -1, -3\n\n[convolutional]\nbatch_normalize=1\nfilters=128\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nsize=3\nstride=1\npad=1\nfilters=256\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=128\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nsize=3\nstride=1\npad=1\nfilters=256\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=128\nsize=1\nstride=1\npad=1\nactivation=mish\n\n##########################\n\n[convolutional]\nbatch_normalize=1\nsize=3\nstride=1\npad=1\nfilters=256\nactivation=mish\n\n[convolutional]\nsize=1\nstride=1\npad=1\nfilters=18\nactivation=linear\n\n[yolo]\nmask = 0,1,2\nanchors = 10,13,  16,30,  33,23,  30,61,  62,45,  59,119,  116,90,  156,198,  373,326\nclasses=1\nnum=9\njitter=.3\nignore_thresh = .7\ntruth_thresh = 1\nrandom=1\nscale_x_y = 1.2\niou_thresh=0.213\ncls_normalizer=1.0\niou_normalizer=0.07\niou_loss=ciou\nnms_kind=greedynms\nbeta_nms=0.6\n\n[route]\nlayers = -4\n\n[convolutional]\nbatch_normalize=1\nsize=3\nstride=2\n# stride=4\npad=1\nfilters=256\nactivation=mish\n\n[route]\nlayers = -1, -16\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nsize=3\nstride=1\npad=1\nfilters=512\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nsize=3\nstride=1\npad=1\nfilters=512\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=256\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nsize=3\nstride=1\npad=1\nfilters=512\nactivation=mish\n\n[convolutional]\nsize=1\nstride=1\npad=1\nfilters=18\nactivation=linear\n\n[yolo]\nmask = 3,4,5\nanchors = 10,13,  16,30,  33,23,  30,61,  62,45,  59,119,  116,90,  156,198,  373,326\nclasses=1\nnum=9\njitter=.3\nignore_thresh = .7\ntruth_thresh = 1\nrandom=1\nscale_x_y = 1.1\niou_thresh=0.213\ncls_normalizer=1.0\niou_normalizer=0.07\niou_loss=ciou\nnms_kind=greedynms\nbeta_nms=0.6\n\n[route]\nlayers = -4\n\n[convolutional]\nbatch_normalize=1\nsize=3\nstride=2\npad=1\nfilters=512\nactivation=mish\n\n[route]\nlayers = -1, -37\n\n[convolutional]\nbatch_normalize=1\nfilters=512\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nsize=3\nstride=1\npad=1\nfilters=1024\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=512\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nsize=3\nstride=1\npad=1\nfilters=1024\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nfilters=512\nsize=1\nstride=1\npad=1\nactivation=mish\n\n[convolutional]\nbatch_normalize=1\nsize=3\nstride=1\npad=1\nfilters=1024\nactivation=mish\n\n[convolutional]\nsize=1\nstride=1\npad=1\nfilters=18\nactivation=linear\n\n[yolo]\nmask = 6,7,8\nanchors = 10,13,  16,30,  33,23,  30,61,  62,45,  59,119,  116,90,  156,198,  373,326\nclasses=1\nnum=9\njitter=.3\nignore_thresh = .7\ntruth_thresh = 1\nrandom=1\nscale_x_y = 1.05\niou_thresh=0.213\ncls_normalizer=1.0\niou_normalizer=0.07\niou_loss=ciou\nnms_kind=greedynms\nbeta_nms=0.6\n\nmax=200\n\"\"\"","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"with open(f\"./yolov4-mish-416-wheat-v3-pseudo.cfg\", 'w') as out:\n    out.write(f\"{cfg_content}\\n\")","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"# !cat ./yolov4-mish-416-wheat-v3-pseudo.cfg","execution_count":null,"outputs":[]},{"metadata":{"hidden":true,"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Start Pseudo Training","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# Redirect outputs to console\n# import sys\n# jupyter_console = sys.stdout\n# sys.stdout = open('/dev/stdout', 'w')\n\n# Append to log file\n# sys.stdout = open(f\"stdout.log\", 'a')\n# sys.stdout = jupyter_console","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Local mode\n# !./darknet detector train \\\n#     data/wheat_pseudo.data \\\n#     yolov4-mish-416-wheat-v3-pseudo.cfg \\\n#     {model_weights_files[0].decode('ascii')} \\\n#     -dont_show -mjpeg_port 8090 -map \\\n#     -gpus 1 \\\n#     -clear","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Kernel mode\n!./darknet detector train \\\n    data/wheat_pseudo.data \\\n    yolov4-mish-416-wheat-v3-pseudo.cfg \\\n    {model_weights_files[0].decode('ascii')} \\\n    -dont_show -mjpeg_port 8090 -map \\\n    -gpus 0 \\\n    -clear \\\n    > /dev/null 2>&1","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Generate New Test Predictions","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"!ls -la ./backup","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Modified from: https://www.kaggle.com/nvnnghia/yolov4-inference\ndef predict_new_test(batch_size=1, prob_threhold=0.5):\n    image_names = os.listdir(test_image_folder)\n\n    # Store results by image\n    image_pred_results = collections.defaultdict(list)\n    \n    cfg = b\"./yolov4-mish-416-wheat-v3-pseudo.cfg\"\n    # weights = b\"./backup/yolov4-mish-416-wheat-v3-pseudo_last.weights\"\n    weights = b\"./backup/yolov4-mish-416-wheat-v3-pseudo_best.weights\"\n    resize = 618\n    \n    print(f\"Generating inference for model cfg file {cfg} ......\")\n    \n    net = dn.load_net_custom(cfg, weights, 0, batch_size)\n    meta = dn.load_meta(meta_file)\n\n    # Create an image we reuse for each detect\n    darknet_image = dn.make_image(resize, resize, 3)\n\n    for name in image_names:\n        image_id = name.split('.')[0]\n\n        image = cv2.imread(f'{test_image_folder}/{image_id}.jpg')\n        image = cv2.resize(image, (resize, resize))\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n\n        infer_start = time.time()\n\n        # Test time augmentation\n        for tta in tta_transforms:\n            tta_image = tta.augment(image)\n\n            preds = detect(net, meta, darknet_image, tta_image)\n            scores, preds = process_detection_result(\n                preds, resize, prob_threhold)\n\n            # Convert back to the orignal coordinations\n            preds = tta.deaugment_boxes(preds)\n            preds = preds.clip(min=0, max=image_width - 1)\n\n            image_pred_results[name].append({\n                'boxes': preds,\n                'scores': scores,\n            })\n\n        print(\n            f\"Time spent on augmented inference for {name}: {time.time() - infer_start:2f} seconds\"\n        )\n\n        del image, preds\n        gc.collect()\n\n    dn.free_network_ptr(net)\n    del net, meta\n    gc.collect()\n\n    return image_pred_results","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pred_start = time.time()\nnew_test_preds = predict_new_test(batch_size=1, prob_threhold=prob_threhold)\nprint(\n    f\"Time spent on generating submission predictions: {time.time() - pred_start:2f} seconds\"\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pred_start = time.time()\nnew_ensemble_results = ensemble(new_test_preds,\n                                iou_thr=iou_thr,\n                                skip_box_thr=skip_box_thr)\nprint(f\"Time spent on ensemble: {time.time() - pred_start:2f} seconds\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Generate Submission","execution_count":null},{"metadata":{"scrolled":false,"trusted":true},"cell_type":"code","source":"pred_start = time.time()\nfinal_results = generate_submit(new_ensemble_results)\nfinal_results[:2]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df = pd.DataFrame(final_results, columns=['image_id', 'PredictionString'])\ntest_df.head()\ntest_df.to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df.head(10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"! ls -la","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!rm -rf __pycache__ darknet* data libdarknet.so yolov4-* *.jpg","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"! ls -la","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"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}