{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import warnings\nwarnings.filterwarnings(\"ignore\")\n\nimport ast\nimport os\nimport json\nimport pandas as pd\nimport torch\nimport importlib\nimport cv2 \n\nfrom shutil import copyfile\nfrom tqdm.notebook import tqdm\ntqdm.pandas()\nfrom sklearn.model_selection import GroupKFold\nfrom PIL import Image\nfrom string import Template\nfrom IPython.display import display\n\nTRAIN_PATH = '/kaggle/input/tensorflow-great-barrier-reef'","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:35:40.698659Z","iopub.execute_input":"2022-01-02T17:35:40.699135Z","iopub.status.idle":"2022-01-02T17:35:42.9668Z","shell.execute_reply.started":"2022-01-02T17:35:40.699047Z","shell.execute_reply":"2022-01-02T17:35:42.965906Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:35:42.968372Z","iopub.execute_input":"2022-01-02T17:35:42.968643Z","iopub.status.idle":"2022-01-02T17:35:43.693269Z","shell.execute_reply.started":"2022-01-02T17:35:42.968606Z","shell.execute_reply":"2022-01-02T17:35:43.692368Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# check Torch and CUDA version\nprint(f\"Torch: {torch.__version__}\")\n!nvcc --version","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:35:43.697487Z","iopub.execute_input":"2022-01-02T17:35:43.697707Z","iopub.status.idle":"2022-01-02T17:35:44.444141Z","shell.execute_reply.started":"2022-01-02T17:35:43.697676Z","shell.execute_reply":"2022-01-02T17:35:44.443224Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!git config --global --unset https.proxy","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:35:44.446812Z","iopub.execute_input":"2022-01-02T17:35:44.44731Z","iopub.status.idle":"2022-01-02T17:35:45.137801Z","shell.execute_reply.started":"2022-01-02T17:35:44.447268Z","shell.execute_reply":"2022-01-02T17:35:45.136768Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!git clone https://github.com/Owaiskhan9654/YOLO-X-Owais-Modified.git -q\n\n\n%cd YOLO-X-Owais-Modified\n!pip install -U pip && pip install -r requirements.txt\n!pip install -v -e .","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:35:45.139676Z","iopub.execute_input":"2022-01-02T17:35:45.140335Z","iopub.status.idle":"2022-01-02T17:36:40.512747Z","shell.execute_reply.started":"2022-01-02T17:35:45.140288Z","shell.execute_reply":"2022-01-02T17:36:40.511849Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:36:40.514111Z","iopub.execute_input":"2022-01-02T17:36:40.519106Z","iopub.status.idle":"2022-01-02T17:36:41.292086Z","shell.execute_reply.started":"2022-01-02T17:36:40.51906Z","shell.execute_reply":"2022-01-02T17:36:41.291149Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''# norfair dependencies\n%cd /kaggle/input/norfair031py3/\n!pip install commonmark-0.9.1-py2.py3-none-any.whl -f ./ --no-index\n!pip install rich-9.13.0-py3-none-any.whl\n\n!mkdir /kaggle/working/tmp\n!cp -r /kaggle/input/norfair031py3/filterpy-1.4.5/filterpy-1.4.5/ /kaggle/working/tmp/\n%cd /kaggle/working/tmp/filterpy-1.4.5/\n!pip install .\n!rm -rf /kaggle/working/tmp\n\n# norfair\n%cd /kaggle/input/norfair031py3/\n!pip install norfair-0.3.1-py3-none-any.whl -f ./ --no-index'''","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:36:41.295688Z","iopub.execute_input":"2022-01-02T17:36:41.295967Z","iopub.status.idle":"2022-01-02T17:36:41.309391Z","shell.execute_reply.started":"2022-01-02T17:36:41.295931Z","shell.execute_reply":"2022-01-02T17:36:41.308564Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install 'git+https://github.com/cocodataset/cocoapi.git#subdirectory=PythonAPI'","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:36:41.312583Z","iopub.execute_input":"2022-01-02T17:36:41.312805Z","iopub.status.idle":"2022-01-02T17:36:59.090301Z","shell.execute_reply.started":"2022-01-02T17:36:41.312779Z","shell.execute_reply":"2022-01-02T17:36:59.089338Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_bbox(annots):\n    bboxes = [list(annot.values()) for annot in annots]\n    return bboxes\n\ndef get_path(row):\n    row['image_path'] = f'{TRAIN_PATH}/train_images/video_{row.video_id}/{row.video_frame}.jpg'\n    return row","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:36:59.092401Z","iopub.execute_input":"2022-01-02T17:36:59.092701Z","iopub.status.idle":"2022-01-02T17:36:59.102415Z","shell.execute_reply.started":"2022-01-02T17:36:59.092654Z","shell.execute_reply":"2022-01-02T17:36:59.101546Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = pd.read_csv(\"/kaggle/input/tensorflow-great-barrier-reef/train.csv\")\ndf.head(5)","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:36:59.106652Z","iopub.execute_input":"2022-01-02T17:36:59.107789Z","iopub.status.idle":"2022-01-02T17:36:59.177784Z","shell.execute_reply.started":"2022-01-02T17:36:59.107715Z","shell.execute_reply":"2022-01-02T17:36:59.176937Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\ndf[\"num_bbox\"] = df['annotations'].apply(lambda x: str.count(x, 'x'))\ndf_train = df[df[\"num_bbox\"]>0]\n\n\ndf_train['annotations'] = df_train['annotations'].progress_apply(lambda x: ast.literal_eval(x))\ndf_train['bboxes'] = df_train.annotations.progress_apply(get_bbox)\n\n\ndf_train[\"width\"] = 1280\ndf_train[\"height\"] = 720\n\n\ndf_train = df_train.progress_apply(get_path, axis=1)","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:36:59.179126Z","iopub.execute_input":"2022-01-02T17:36:59.179503Z","iopub.status.idle":"2022-01-02T17:37:03.37351Z","shell.execute_reply.started":"2022-01-02T17:36:59.179459Z","shell.execute_reply":"2022-01-02T17:37:03.372782Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"kf = GroupKFold(n_splits = 5) \ndf_train = df_train.reset_index(drop=True)\ndf_train['fold'] = -1\nfor fold, (train_idx, val_idx) in enumerate(kf.split(df_train, y = df_train.video_id.tolist(), groups=df_train.sequence)):\n    df_train.loc[val_idx, 'fold'] = fold\n\ndf_train.head(5)","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:37:03.374821Z","iopub.execute_input":"2022-01-02T17:37:03.375211Z","iopub.status.idle":"2022-01-02T17:37:03.408891Z","shell.execute_reply.started":"2022-01-02T17:37:03.375173Z","shell.execute_reply":"2022-01-02T17:37:03.407523Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"HOME_DIR = '/kaggle/working/' \nDATASET_PATH = 'dataset/images'\n\n!mkdir {HOME_DIR}dataset\n!mkdir {HOME_DIR}{DATASET_PATH}\n!mkdir {HOME_DIR}{DATASET_PATH}/train2017\n!mkdir {HOME_DIR}{DATASET_PATH}/val2017\n!mkdir {HOME_DIR}{DATASET_PATH}/annotations","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:37:03.410441Z","iopub.execute_input":"2022-01-02T17:37:03.41071Z","iopub.status.idle":"2022-01-02T17:37:06.714929Z","shell.execute_reply.started":"2022-01-02T17:37:03.410673Z","shell.execute_reply":"2022-01-02T17:37:06.714008Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"SELECTED_FOLD = 4\n\nfor i in tqdm(range(len(df_train))):\n    row = df_train.loc[i]\n    if row.fold != SELECTED_FOLD:\n        copyfile(f'{row.image_path}', f'{HOME_DIR}{DATASET_PATH}/train2017/{row.image_id}.jpg')\n    else:\n        copyfile(f'{row.image_path}', f'{HOME_DIR}{DATASET_PATH}/val2017/{row.image_id}.jpg') ","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:37:06.717704Z","iopub.execute_input":"2022-01-02T17:37:06.718002Z","iopub.status.idle":"2022-01-02T17:38:10.519653Z","shell.execute_reply.started":"2022-01-02T17:37:06.717945Z","shell.execute_reply":"2022-01-02T17:38:10.518921Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f'Number of training files: {len(os.listdir(f\"{HOME_DIR}{DATASET_PATH}/train2017/\"))}')\nprint(f'Number of validation files: {len(os.listdir(f\"{HOME_DIR}{DATASET_PATH}/val2017/\"))}')","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:38:10.520838Z","iopub.execute_input":"2022-01-02T17:38:10.521105Z","iopub.status.idle":"2022-01-02T17:38:10.530038Z","shell.execute_reply.started":"2022-01-02T17:38:10.521076Z","shell.execute_reply":"2022-01-02T17:38:10.529202Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def save_annot_json(json_annotation, filename):\n    with open(filename, 'w') as f:\n        output_json = json.dumps(json_annotation)\n        f.write(output_json)","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:38:10.53157Z","iopub.execute_input":"2022-01-02T17:38:10.531888Z","iopub.status.idle":"2022-01-02T17:38:10.538375Z","shell.execute_reply.started":"2022-01-02T17:38:10.531851Z","shell.execute_reply":"2022-01-02T17:38:10.537649Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"annotion_id = 0","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:38:10.539452Z","iopub.execute_input":"2022-01-02T17:38:10.539738Z","iopub.status.idle":"2022-01-02T17:38:10.545921Z","shell.execute_reply.started":"2022-01-02T17:38:10.539702Z","shell.execute_reply":"2022-01-02T17:38:10.545169Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def dataset2coco(df, dest_path):\n    \n    global annotion_id\n    \n    annotations_json = {\n        \"info\": [],\n        \"licenses\": [],\n        \"categories\": [],\n        \"images\": [],\n        \"annotations\": []\n    }\n    \n    info = {\n        \"year\": \"2021\",\n        \"version\": \"1\",\n        \"description\": \"COTS dataset - COCO format\",\n        \"contributor\": \"\",\n        \"url\": \"https://kaggle.com\",\n        \"date_created\": \"2021-11-30T15:01:26+00:00\"\n    }\n    annotations_json[\"info\"].append(info)\n    \n    lic = {\n            \"id\": 1,\n            \"url\": \"\",\n            \"name\": \"Unknown\"\n        }\n    annotations_json[\"licenses\"].append(lic)\n\n    classes = {\"id\": 0, \"name\": \"starfish\", \"supercategory\": \"none\"}\n\n    annotations_json[\"categories\"].append(classes)\n\n    \n    for ann_row in df.itertuples():\n            \n        images = {\n            \"id\": ann_row[0],\n            \"license\": 1,\n            \"file_name\": ann_row.image_id + '.jpg',\n            \"height\": ann_row.height,\n            \"width\": ann_row.width,\n            \"date_captured\": \"2021-11-30T15:01:26+00:00\"\n        }\n        \n        annotations_json[\"images\"].append(images)\n        \n        bbox_list = ann_row.bboxes\n        \n        for bbox in bbox_list:\n            b_width = bbox[2]\n            b_height = bbox[3]\n            \n            # some boxes in COTS are outside the image height and width\n            if (bbox[0] + bbox[2] > 1280):\n                b_width = bbox[0] - 1280 \n            if (bbox[1] + bbox[3] > 720):\n                b_height = bbox[1] - 720 \n                \n            image_annotations = {\n                \"id\": annotion_id,\n                \"image_id\": ann_row[0],\n                \"category_id\": 0,\n                \"bbox\": [bbox[0], bbox[1], b_width, b_height],\n                \"area\": bbox[2] * bbox[3],\n                \"segmentation\": [],\n                \"iscrowd\": 0\n            }\n            \n            annotion_id += 1\n            annotations_json[\"annotations\"].append(image_annotations)\n        \n        \n    print(f\"Dataset COTS annotation to COCO json format completed! Files: {len(df)}\")\n    return annotations_json","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:38:10.547721Z","iopub.execute_input":"2022-01-02T17:38:10.547942Z","iopub.status.idle":"2022-01-02T17:38:10.561472Z","shell.execute_reply.started":"2022-01-02T17:38:10.547918Z","shell.execute_reply":"2022-01-02T17:38:10.560696Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\ntrain_annot_json = dataset2coco(df_train[df_train.fold != SELECTED_FOLD], f\"{HOME_DIR}{DATASET_PATH}/train2017/\")\nval_annot_json = dataset2coco(df_train[df_train.fold == SELECTED_FOLD], f\"{HOME_DIR}{DATASET_PATH}/val2017/\")\n\n\nsave_annot_json(train_annot_json, f\"{HOME_DIR}{DATASET_PATH}/annotations/train.json\")\nsave_annot_json(val_annot_json, f\"{HOME_DIR}{DATASET_PATH}/annotations/valid.json\")","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:38:10.562911Z","iopub.execute_input":"2022-01-02T17:38:10.563219Z","iopub.status.idle":"2022-01-02T17:38:10.670337Z","shell.execute_reply.started":"2022-01-02T17:38:10.563182Z","shell.execute_reply":"2022-01-02T17:38:10.669568Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"config_file_template = \"\"\"\n\nimport os\n\nimport torch\nimport torch.distributed as dist\nimport torch.nn as nn\nimport random\n\nfrom yolox.exp import Exp as MyExp\n\nclass Exp(MyExp):\n    def __init__(self):\n        super().__init__()\n\n        # ---------------- model config ---------------- #\n        self.num_classes = 1\n        self.depth = 1 \n        self.width = 1 \n        self.act = 'silu'\n\n        # ---------------- dataloader config ---------------- #\n        # set worker to 4 for shorter dataloader init time\n        self.data_num_workers = 2\n        self.input_size = (960, 960)  # (height, width) \n        # Actual multiscale ranges: [640-5*32, 640+5*32].\n        # To disable multiscale training, set the\n        # self.multiscale_range to 0.\n        self.multiscale_range = 5\n        # You can uncomment this line to specify a multiscale range\n        # self.random_size = (14, 26)\n        self.data_dir = \"/kaggle/working/dataset/images\"\n        #self.train_ann = \"instances_train2017.json\"\n        self.train_ann = 'train.json'\n        self.val_ann = 'valid.json'\n\n        # --------------- transform config ----------------- #\n        self.mosaic_prob = 0.5\n        self.mixup_prob = 1\n        self.hsv_prob = 0.7\n        self.flip_prob = 0.7\n        self.degrees = 10.0\n        self.translate = 0.1\n        self.mosaic_scale = (0.5, 1.5)\n        self.mixup_scale = (0.5, 1.5)\n        self.shear = 2.0\n        self.enable_mixup = True\n\n        # --------------  training config --------------------- #\n        self.warmup_epochs = 5\n        self.max_epoch = $max_epoch\n        self.warmup_lr = 0\n        self.basic_lr_per_img = 0.01/64\n        self.scheduler = \"yoloxwarmcos\"\n        self.no_aug_epochs = 2\n        self.min_lr_ratio = 0.05\n        self.ema = True\n\n        self.weight_decay = 5e-4\n        self.momentum = 0.937\n        self.print_interval = 10\n        self.eval_interval = 1\n        self.exp_name = os.path.split(os.path.realpath(__file__))[1].split(\".\")[0]\n\n        # -----------------  testing config ------------------ #\n        self.test_size = (960,960)\n        self.test_conf = 0.01\n        self.nmsthre = 0.65\n\n    def get_model(self):\n        from yolox.models import YOLOX, YOLOPAFPN, YOLOXHead\n\n        def init_yolo(M):\n            for m in M.modules():\n                if isinstance(m, nn.BatchNorm2d):\n                    m.eps = 1e-3\n                    m.momentum = 0.03\n\n        if getattr(self, \"model\", None) is None:\n            in_channels = [256, 512, 1024]\n            backbone = YOLOPAFPN(self.depth, self.width, in_channels=in_channels, act=self.act)\n            head = YOLOXHead(self.num_classes, self.width, in_channels=in_channels, act=self.act)\n            self.model = YOLOX(backbone, head)\n\n        self.model.apply(init_yolo)\n        self.model.head.initialize_biases(1e-2)\n        return self.model\n\n    def get_data_loader(\n        self, batch_size, is_distributed, no_aug=False, cache_img=False\n    ):\n        from yolox.data import (\n            COCODataset,\n            TrainTransform,\n            YoloBatchSampler,\n            DataLoader,\n            InfiniteSampler,\n            MosaicDetection,\n            worker_init_reset_seed,\n        )\n        from yolox.utils import (\n            wait_for_the_master,\n            get_local_rank,\n        )\n\n        local_rank = get_local_rank()\n\n        with wait_for_the_master(local_rank):\n            dataset = COCODataset(\n                data_dir=self.data_dir,\n                json_file=self.train_ann,\n                img_size=self.input_size,\n                preproc=TrainTransform(\n                    max_labels=50,\n                    flip_prob=self.flip_prob,\n                    hsv_prob=self.hsv_prob),\n                cache=cache_img,\n            )\n\n        dataset = MosaicDetection(\n            dataset,\n            mosaic=not no_aug,\n            img_size=self.input_size,\n            preproc=TrainTransform(\n                max_labels=120,\n                flip_prob=self.flip_prob,\n                hsv_prob=self.hsv_prob),\n            degrees=self.degrees,\n            translate=self.translate,\n            mosaic_scale=self.mosaic_scale,\n            mixup_scale=self.mixup_scale,\n            shear=self.shear,\n            enable_mixup=self.enable_mixup,\n            mosaic_prob=self.mosaic_prob,\n            mixup_prob=self.mixup_prob,\n        )\n\n        self.dataset = dataset\n\n        if is_distributed:\n            batch_size = batch_size // dist.get_world_size()\n\n        sampler = InfiniteSampler(len(self.dataset), seed=self.seed if self.seed else 0)\n\n        batch_sampler = YoloBatchSampler(\n            sampler=sampler,\n            batch_size=batch_size,\n            drop_last=False,\n            mosaic=not no_aug,\n        )\n\n        dataloader_kwargs = {\"num_workers\": self.data_num_workers, \"pin_memory\": True}\n        dataloader_kwargs[\"batch_sampler\"] = batch_sampler\n\n        # Make sure each process has different random seed, especially for 'fork' method.\n        # Check https://github.com/pytorch/pytorch/issues/63311 for more details.\n        dataloader_kwargs[\"worker_init_fn\"] = worker_init_reset_seed\n\n        train_loader = DataLoader(self.dataset, **dataloader_kwargs)\n\n        return train_loader\n\n    def random_resize(self, data_loader, epoch, rank, is_distributed):\n        tensor = torch.LongTensor(2).cuda()\n\n        if rank == 0:\n            size_factor = self.input_size[1] * 1.0 / self.input_size[0]\n            if not hasattr(self, 'random_size'):\n                min_size = int(self.input_size[0] / 32) - self.multiscale_range\n                max_size = int(self.input_size[0] / 32) + self.multiscale_range\n                self.random_size = (min_size, max_size)\n            size = random.randint(*self.random_size)\n            size = (int(32 * size), 32 * int(size * size_factor))\n            tensor[0] = size[0]\n            tensor[1] = size[1]\n\n        if is_distributed:\n            dist.barrier()\n            dist.broadcast(tensor, 0)\n\n        input_size = (tensor[0].item(), tensor[1].item())\n        return input_size\n\n    def preprocess(self, inputs, targets, tsize):\n        scale_y = tsize[0] / self.input_size[0]\n        scale_x = tsize[1] / self.input_size[1]\n        if scale_x != 1 or scale_y != 1:\n            inputs = nn.functional.interpolate(\n                inputs, size=tsize, mode=\"bilinear\", align_corners=False\n            )\n            targets[..., 1::2] = targets[..., 1::2] * scale_x\n            targets[..., 2::2] = targets[..., 2::2] * scale_y\n        return inputs, targets\n\n    def get_optimizer(self, batch_size):\n        if \"optimizer\" not in self.__dict__:\n            if self.warmup_epochs > 0:\n                lr = self.warmup_lr\n            else:\n                lr = self.basic_lr_per_img * batch_size\n\n            pg0, pg1, pg2 = [], [], []  # optimizer parameter groups\n\n            for k, v in self.model.named_modules():\n                if hasattr(v, \"bias\") and isinstance(v.bias, nn.Parameter):\n                    pg2.append(v.bias)  # biases\n                if isinstance(v, nn.BatchNorm2d) or \"bn\" in k:\n                    pg0.append(v.weight)  # no decay\n                elif hasattr(v, \"weight\") and isinstance(v.weight, nn.Parameter):\n                    pg1.append(v.weight)  # apply decay\n\n            optimizer = torch.optim.SGD(\n                pg0, lr=lr, momentum=self.momentum, nesterov=True\n            )\n            optimizer.add_param_group(\n                {\"params\": pg1, \"weight_decay\": self.weight_decay}\n            )  # add pg1 with weight_decay\n            optimizer.add_param_group({\"params\": pg2})\n            self.optimizer = optimizer\n\n        return self.optimizer\n\n    def get_lr_scheduler(self, lr, iters_per_epoch):\n        from yolox.utils import LRScheduler\n\n        scheduler = LRScheduler(\n            self.scheduler,\n            lr,\n            #iters_per_epoch,\n            50,\n            self.max_epoch,\n            warmup_epochs=self.warmup_epochs,\n            warmup_lr_start=self.warmup_lr,\n            no_aug_epochs=self.no_aug_epochs,\n            min_lr_ratio=self.min_lr_ratio,\n        )\n        return scheduler\n\n    def get_eval_loader(self, batch_size, is_distributed, testdev=False, legacy=False):\n        from yolox.data import COCODataset, ValTransform\n\n        valdataset = COCODataset(\n            data_dir=self.data_dir,\n            json_file=self.val_ann if not testdev else \"image_info_test-dev2017.json\",\n            name=\"val2017\" if not testdev else \"test2017\",\n            img_size=self.test_size,\n            preproc=ValTransform(legacy=legacy),\n        )\n\n        if is_distributed:\n            batch_size = batch_size // dist.get_world_size()\n            sampler = torch.utils.data.distributed.DistributedSampler(\n                valdataset, shuffle=False\n            )\n        else:\n            sampler = torch.utils.data.SequentialSampler(valdataset)\n\n        dataloader_kwargs = {\n            \"num_workers\": self.data_num_workers,\n            \"pin_memory\": True,\n            \"sampler\": sampler,\n        }\n        dataloader_kwargs[\"batch_size\"] = batch_size\n        val_loader = torch.utils.data.DataLoader(valdataset, **dataloader_kwargs)\n\n        return val_loader\n\n    def get_evaluator(self, batch_size, is_distributed, testdev=False, legacy=False):\n        from yolox.evaluators import COCOEvaluator\n\n        val_loader = self.get_eval_loader(batch_size, is_distributed, testdev, legacy)\n        evaluator = COCOEvaluator(\n            dataloader=val_loader,\n            img_size=self.test_size,\n            confthre=self.test_conf,\n            nmsthre=self.nmsthre,\n            num_classes=self.num_classes,\n            testdev=testdev,\n        )\n        return evaluator\n\n    def eval(self, model, evaluator, is_distributed, half=False):\n        return evaluator.evaluate(model, is_distributed, half)\n\n\"\"\"","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:38:10.672671Z","iopub.execute_input":"2022-01-02T17:38:10.672945Z","iopub.status.idle":"2022-01-02T17:38:10.685544Z","shell.execute_reply.started":"2022-01-02T17:38:10.672909Z","shell.execute_reply":"2022-01-02T17:38:10.684442Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"PIPELINE_CONFIG_PATH='cots_config.py'\n\npipeline = Template(config_file_template).substitute(max_epoch = 2)\n\nwith open(PIPELINE_CONFIG_PATH, 'w') as f:\n    f.write(pipeline)","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:38:10.686704Z","iopub.execute_input":"2022-01-02T17:38:10.6876Z","iopub.status.idle":"2022-01-02T17:38:10.698531Z","shell.execute_reply.started":"2022-01-02T17:38:10.687563Z","shell.execute_reply":"2022-01-02T17:38:10.697762Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pwd","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:38:10.699876Z","iopub.execute_input":"2022-01-02T17:38:10.702937Z","iopub.status.idle":"2022-01-02T17:38:11.375323Z","shell.execute_reply.started":"2022-01-02T17:38:10.70291Z","shell.execute_reply":"2022-01-02T17:38:11.374392Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls yolox","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:38:11.377242Z","iopub.execute_input":"2022-01-02T17:38:11.37918Z","iopub.status.idle":"2022-01-02T17:38:12.043795Z","shell.execute_reply.started":"2022-01-02T17:38:11.379127Z","shell.execute_reply":"2022-01-02T17:38:12.042936Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n\nvoc_cls = '''\nVOC_CLASSES = (\n  \"starfish\",\n)\n'''\nwith open('./yolox/data/datasets/voc_classes.py', 'w') as f:\n    f.write(voc_cls)\n\n\ncoco_cls = '''\nCOCO_CLASSES = (\n  \"starfish\",\n)\n'''\nwith open('./yolox/data/datasets/coco_classes.py', 'w') as f:\n    f.write(coco_cls)\n\n# check if everything is ok    \n!more ./yolox/data/datasets/coco_classes.py","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:38:12.047134Z","iopub.execute_input":"2022-01-02T17:38:12.047375Z","iopub.status.idle":"2022-01-02T17:38:12.718698Z","shell.execute_reply.started":"2022-01-02T17:38:12.047344Z","shell.execute_reply":"2022-01-02T17:38:12.717922Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pwd","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:38:12.721399Z","iopub.execute_input":"2022-01-02T17:38:12.721627Z","iopub.status.idle":"2022-01-02T17:38:13.642598Z","shell.execute_reply.started":"2022-01-02T17:38:12.721598Z","shell.execute_reply":"2022-01-02T17:38:13.641644Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sh = 'wget https://github.com/Megvii-BaseDetection/storage/releases/download/0.0.1/yolox_l.pth'\nMODEL_FILE = 'yolox_l.pth'\n\nwith open('script.sh', 'w') as file:\n  file.write(sh)\n\n!bash script.sh","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:38:13.645582Z","iopub.execute_input":"2022-01-02T17:38:13.645906Z","iopub.status.idle":"2022-01-02T17:38:50.253083Z","shell.execute_reply.started":"2022-01-02T17:38:13.645859Z","shell.execute_reply":"2022-01-02T17:38:50.252343Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ls","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:38:50.254561Z","iopub.execute_input":"2022-01-02T17:38:50.255101Z","iopub.status.idle":"2022-01-02T17:38:50.920407Z","shell.execute_reply.started":"2022-01-02T17:38:50.255056Z","shell.execute_reply":"2022-01-02T17:38:50.919601Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!rm *.2","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:38:50.925166Z","iopub.execute_input":"2022-01-02T17:38:50.925633Z","iopub.status.idle":"2022-01-02T17:38:51.640696Z","shell.execute_reply.started":"2022-01-02T17:38:50.9256Z","shell.execute_reply":"2022-01-02T17:38:51.639826Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!cp ./tools/train.py ./","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:38:51.642485Z","iopub.execute_input":"2022-01-02T17:38:51.643181Z","iopub.status.idle":"2022-01-02T17:38:53.176561Z","shell.execute_reply.started":"2022-01-02T17:38:51.643127Z","shell.execute_reply":"2022-01-02T17:38:53.175588Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!python train.py \\\n    -f cots_config.py \\\n    -d 1 \\\n    -b 8 \\\n    --fp16 \\\n    -o \\\n    -c {MODEL_FILE}   # Remember to chenge this line if you take different model eg. yolo_nano.pth, yolox_s.pth or yolox_m.pth\\","metadata":{"execution":{"iopub.status.busy":"2022-01-02T17:38:53.178228Z","iopub.execute_input":"2022-01-02T17:38:53.178535Z","iopub.status.idle":"2022-01-02T18:02:15.686126Z","shell.execute_reply.started":"2022-01-02T17:38:53.178494Z","shell.execute_reply":"2022-01-02T18:02:15.685272Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ls","metadata":{"execution":{"iopub.status.busy":"2022-01-02T18:02:15.687899Z","iopub.execute_input":"2022-01-02T18:02:15.688206Z","iopub.status.idle":"2022-01-02T18:02:16.377272Z","shell.execute_reply.started":"2022-01-02T18:02:15.688161Z","shell.execute_reply":"2022-01-02T18:02:16.37633Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%cd /kaggle/working/YOLOX\n#yolox-cots-models\nCHECKPOINT_FILE = './YOLOX_outputs/cots_config/best_ckpt.pth'","metadata":{"execution":{"iopub.status.busy":"2022-01-02T18:02:16.380876Z","iopub.execute_input":"2022-01-02T18:02:16.381154Z","iopub.status.idle":"2022-01-02T18:02:16.388302Z","shell.execute_reply.started":"2022-01-02T18:02:16.381121Z","shell.execute_reply":"2022-01-02T18:02:16.387128Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def yolox_inference(img, model, test_size): \n    bboxes = []\n    bbclasses = []\n    scores = []\n    \n    preproc = ValTransform(legacy = False)\n\n    tensor_img, _ = preproc(img, None, test_size)\n    tensor_img = torch.from_numpy(tensor_img).unsqueeze(0)\n    tensor_img = tensor_img.float()\n    tensor_img = tensor_img.cuda()\n\n    with torch.no_grad():\n        outputs = model(tensor_img)\n        outputs = postprocess(\n                    outputs, num_classes, confthre,\n                    nmsthre, class_agnostic=True\n                )\n\n    if outputs[0] is None:\n        return [], [], []\n    \n    outputs = outputs[0].cpu()\n    bboxes = outputs[:, 0:4]\n\n    bboxes /= min(test_size[0] / img.shape[0], test_size[1] / img.shape[1])\n    bbclasses = outputs[:, 6]\n    scores = outputs[:, 4] * outputs[:, 5]\n    \n    return bboxes, bbclasses, scores","metadata":{"execution":{"iopub.status.busy":"2022-01-02T18:02:16.389863Z","iopub.execute_input":"2022-01-02T18:02:16.3908Z","iopub.status.idle":"2022-01-02T18:02:16.403858Z","shell.execute_reply.started":"2022-01-02T18:02:16.390746Z","shell.execute_reply":"2022-01-02T18:02:16.40296Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def draw_yolox_predictions(img, bboxes, scores, bbclasses, confthre, classes_dict):\n    for i in range(len(bboxes)):\n            box = bboxes[i]\n            cls_id = int(bbclasses[i])\n            score = scores[i]\n            if score < confthre:\n                continue\n            x0 = int(box[0])\n            y0 = int(box[1])\n            x1 = int(box[2])\n            y1 = int(box[3])\n\n            cv2.rectangle(img, (x0, y0), (x1, y1), (0, 255, 0), 2)\n            cv2.putText(img, '{}:{:.1f}%'.format(classes_dict[cls_id], score * 100), (x0, y0 - 3), cv2.FONT_HERSHEY_PLAIN, 0.8, (0,255,0), thickness = 1)\n    return img","metadata":{"execution":{"iopub.status.busy":"2022-01-02T18:02:16.405424Z","iopub.execute_input":"2022-01-02T18:02:16.40599Z","iopub.status.idle":"2022-01-02T18:02:16.415368Z","shell.execute_reply.started":"2022-01-02T18:02:16.405934Z","shell.execute_reply":"2022-01-02T18:02:16.414542Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ls","metadata":{"execution":{"iopub.status.busy":"2022-01-02T18:02:16.416821Z","iopub.execute_input":"2022-01-02T18:02:16.417642Z","iopub.status.idle":"2022-01-02T18:02:17.084054Z","shell.execute_reply.started":"2022-01-02T18:02:16.417601Z","shell.execute_reply":"2022-01-02T18:02:17.083271Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from yolox.utils import postprocess\nfrom yolox.data.data_augment import ValTransform\n\nCOCO_CLASSES = (\n  \"starfish\",\n)\n\n# get YOLOX experiment\ncurrent_exp = importlib.import_module('cots_config')\nexp = current_exp.Exp()\n\n# set inference parameters\ntest_size = (800, 1280)\nnum_classes = 1\nconfthre = 0.35\nnmsthre = 0.4\n\n\n# get YOLOX model\nmodel = exp.get_model()\nmodel.cuda()\nmodel.eval()\n\n# get custom trained checkpoint\nckpt_file = CHECKPOINT_FILE\nckpt = torch.load(ckpt_file, map_location=\"cpu\")\nmodel.load_state_dict(ckpt[\"model\"])","metadata":{"execution":{"iopub.status.busy":"2022-01-02T18:02:17.08564Z","iopub.execute_input":"2022-01-02T18:02:17.085931Z","iopub.status.idle":"2022-01-02T18:02:23.773573Z","shell.execute_reply.started":"2022-01-02T18:02:17.085891Z","shell.execute_reply":"2022-01-02T18:02:23.772817Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TEST_IMAGE_PATH = \"/kaggle/input/tensorflow-great-barrier-reef/train_images/video_0/9674.jpg\"\nimg = cv2.imread(TEST_IMAGE_PATH)\n\n# Get predictions\nbboxes, bbclasses, scores = yolox_inference(img, model, test_size)\n\n# Draw predictions\nout_image = draw_yolox_predictions(img, bboxes, scores, bbclasses, confthre, COCO_CLASSES)\n\n# Since we load image using OpenCV we have to convert it \nout_image = cv2.cvtColor(out_image, cv2.COLOR_BGR2RGB)\ndisplay(Image.fromarray(out_image))","metadata":{"execution":{"iopub.status.busy":"2022-01-02T18:02:23.774735Z","iopub.execute_input":"2022-01-02T18:02:23.775352Z","iopub.status.idle":"2022-01-02T18:02:24.949625Z","shell.execute_reply.started":"2022-01-02T18:02:23.775309Z","shell.execute_reply":"2022-01-02T18:02:24.948738Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%cd /kaggle/working/","metadata":{"execution":{"iopub.status.busy":"2022-01-02T18:02:24.950722Z","iopub.execute_input":"2022-01-02T18:02:24.953022Z","iopub.status.idle":"2022-01-02T18:02:24.962088Z","shell.execute_reply.started":"2022-01-02T18:02:24.952953Z","shell.execute_reply":"2022-01-02T18:02:24.961321Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import greatbarrierreef\n\nenv = greatbarrierreef.make_env()   # initialize the environment\niter_test = env.iter_test()  ","metadata":{"execution":{"iopub.status.busy":"2022-01-02T18:02:24.963161Z","iopub.execute_input":"2022-01-02T18:02:24.963657Z","iopub.status.idle":"2022-01-02T18:02:24.992191Z","shell.execute_reply.started":"2022-01-02T18:02:24.96363Z","shell.execute_reply":"2022-01-02T18:02:24.991439Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install norfair","metadata":{"execution":{"iopub.status.busy":"2022-01-02T18:02:24.993435Z","iopub.execute_input":"2022-01-02T18:02:24.993663Z","iopub.status.idle":"2022-01-02T18:02:35.281958Z","shell.execute_reply.started":"2022-01-02T18:02:24.993633Z","shell.execute_reply":"2022-01-02T18:02:35.281162Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nfrom norfair import Detection, Tracker\n\n# Helper to convert bbox in format [x_min, y_min, x_max, y_max, score] to norfair.Detection class\ndef to_norfair(detects, frame_id):\n    result = []\n    for x_min, y_min, x_max, y_max, score in detects:\n        xc, yc = (x_min + x_max) / 2, (y_min + y_max) / 2\n        w, h = x_max - x_min, y_max - y_min\n        result.append(Detection(points=np.array([xc, yc]), scores=np.array([score]), data=np.array([w, h, frame_id])))\n        \n    return result\n\n# Euclidean distance function to match detections on this frame with tracked_objects from previous frames\ndef euclidean_distance(detection, tracked_object):\n    return np.linalg.norm(detection.points - tracked_object.estimate)","metadata":{"execution":{"iopub.status.busy":"2022-01-02T18:02:35.284241Z","iopub.execute_input":"2022-01-02T18:02:35.284518Z","iopub.status.idle":"2022-01-02T18:02:35.349078Z","shell.execute_reply.started":"2022-01-02T18:02:35.284477Z","shell.execute_reply":"2022-01-02T18:02:35.348281Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_dict = {\n    'id': [],\n    'prediction_string': [],\n}\n\n\n#######################################################\n#                      Tracking                       #\n#######################################################\n\n# Tracker will update tracks based on detections from current frame\n# Matching based on euclidean distance between bbox centers of detections \n# from current frame and tracked_objects based on previous frames\n# You can check it's parameters in norfair docs\n# https://github.com/tryolabs/norfair/blob/master/docs/README.md\ntracker = Tracker(\n    distance_function=euclidean_distance, \n    distance_threshold=30,\n    hit_inertia_min=3,\n    hit_inertia_max=6,\n    initialization_delay=1,\n)\n\n# Save frame_id into detection to know which tracks have no detections on current frame\nframe_id = 0\n#######################################################\n\n\nfor (image_np, sample_prediction_df) in iter_test:\n \n    bboxes, bbclasses, scores = yolox_inference(image_np[:,:,::-1], model, test_size)\n    \n    predictions = []\n    detects = []\n    for i in range(len(bboxes)):\n        box = bboxes[i]\n        cls_id = int(bbclasses[i])\n        score = scores[i]\n        if score < confthre:\n            continue\n        x_min = int(box[0])\n        y_min = int(box[1])\n        x_max = int(box[2])\n        y_max = int(box[3])\n        detects.append([x_min, y_min, x_max, y_max, score])\n        \n        bbox_width = x_max - x_min\n        bbox_height = y_max - y_min\n        \n        predictions.append('{:.2f} {} {} {} {}'.format(score, x_min, y_min, bbox_width, bbox_height))\n    \n    #######################################################\n    #                      Tracking                       #\n    #######################################################\n    \n    # Update tracks using detects from current frame\n    tracked_objects = tracker.update(detections=to_norfair(detects, frame_id))\n    for tobj in tracked_objects:\n        bbox_width, bbox_height, last_detected_frame_id = tobj.last_detection.data\n        if last_detected_frame_id == frame_id:  # Skip objects that were detected on current frame\n            continue\n            \n        # Add objects that have no detections on current frame to predictions\n        xc, yc = tobj.estimate[0]\n        x_min, y_min = int(round(xc - bbox_width / 2)), int(round(yc - bbox_height / 2))\n        score = tobj.last_detection.scores[0]\n\n        predictions.append('{:.2f} {} {} {} {}'.format(score, x_min, y_min, bbox_width, bbox_height))\n    #######################################################\n    \n    prediction_str = ' '.join(predictions)\n    sample_prediction_df['annotations'] = prediction_str\n    env.predict(sample_prediction_df)\n\n    print('Prediction:', prediction_str)\n    frame_id += 1","metadata":{"execution":{"iopub.status.busy":"2022-01-02T18:06:09.779877Z","iopub.execute_input":"2022-01-02T18:06:09.78039Z","iopub.status.idle":"2022-01-02T18:06:09.794324Z","shell.execute_reply.started":"2022-01-02T18:06:09.780355Z","shell.execute_reply":"2022-01-02T18:06:09.793641Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub_df = pd.read_csv('submission.csv')\nsub_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-02T18:06:37.941948Z","iopub.execute_input":"2022-01-02T18:06:37.942216Z","iopub.status.idle":"2022-01-02T18:06:37.955724Z","shell.execute_reply.started":"2022-01-02T18:06:37.942188Z","shell.execute_reply":"2022-01-02T18:06:37.954988Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}