{"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 os\nimport ast\nimport yaml\nimport torch\nimport shutil\nimport random\nimport numpy as np\nimport pandas as pd\nfrom joblib import Parallel, delayed\nfrom sklearn.model_selection import GroupKFold\n\nfrom tqdm.notebook import tqdm\ntqdm.pandas()\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\nimport sys\nsys.path.append('../input/d/cowfrica/yolov5')\nsys.path.append('../input/hyperparameters-for-yolov5')\nsys.path.append('../input/tensorflow-great-barrier-reef')\n\nimport utils\ntqdm.pandas()\n\n%pip install -q wandb\n%pip install wandb --upgrade\nimport wandb\nwandb.login(key=\"f04c0b8d3b383666c2518b204435adcb3f9532e9\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","editable":false,"execution":{"iopub.status.busy":"2021-12-26T21:21:45.670539Z","iopub.execute_input":"2021-12-26T21:21:45.671189Z","iopub.status.idle":"2021-12-26T21:22:13.776851Z","shell.execute_reply.started":"2021-12-26T21:21:45.671046Z","shell.execute_reply":"2021-12-26T21:22:13.776134Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def random_seed(seed):\n    np.random.seed(seed)\n    random.seed(seed)\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    if torch.cuda.is_available():\n        torch.cuda.manual_seed_all(seed)\n        torch.backends.cudnn.deterministic = True\n        \nrandom_seed(1702)","metadata":{"editable":false,"execution":{"iopub.status.busy":"2021-12-26T21:22:13.778481Z","iopub.execute_input":"2021-12-26T21:22:13.779045Z","iopub.status.idle":"2021-12-26T21:22:13.788646Z","shell.execute_reply.started":"2021-12-26T21:22:13.779014Z","shell.execute_reply":"2021-12-26T21:22:13.787818Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"FOLD = 4 \nIMAGE_WIDTH = 1280\nIMAGE_HEIGHT = 720\nREMOVE_NOBBOX = True \nNUM_BACKGROUND_IMG = 400\n\nCWD = '/kaggle/working/'\nIMAGE_DIR = '/kaggle/images' \nLABEL_DIR = '/kaggle/labels' \nROOT_DIR = '/kaggle/input/tensorflow-great-barrier-reef/'","metadata":{"editable":false,"execution":{"iopub.status.busy":"2021-12-26T21:22:13.789778Z","iopub.execute_input":"2021-12-26T21:22:13.789995Z","iopub.status.idle":"2021-12-26T21:22:13.801563Z","shell.execute_reply.started":"2021-12-26T21:22:13.789969Z","shell.execute_reply":"2021-12-26T21:22:13.800705Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!mkdir -p {IMAGE_DIR}\n!mkdir -p {LABEL_DIR}","metadata":{"editable":false,"execution":{"iopub.status.busy":"2021-12-26T21:22:13.803423Z","iopub.execute_input":"2021-12-26T21:22:13.804166Z","iopub.status.idle":"2021-12-26T21:22:15.318475Z","shell.execute_reply.started":"2021-12-26T21:22:13.804106Z","shell.execute_reply":"2021-12-26T21:22:15.317246Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def coco2yolo(image_width, image_height, bboxes):\n    bboxes = bboxes.copy().astype(float) \n    \n    # normalize\n    bboxes[..., [0, 2]] = bboxes[..., [0, 2]] / image_width\n    bboxes[..., [1, 3]] = bboxes[..., [1, 3]] / image_height\n    \n    # gets xmid and ymid \n    bboxes[..., [0, 1]] = bboxes[..., [0, 1]] + bboxes[..., [2, 3]] / 2\n    \n    return bboxes\n\ndef get_bbox(annots):\n    # converts from dictionary to list \n    # formart after converting: [x, y, width, height]\n    \n    bboxes = [list(annot.values()) for annot in annots]\n    return bboxes","metadata":{"editable":false,"execution":{"iopub.status.busy":"2021-12-26T21:22:15.321825Z","iopub.execute_input":"2021-12-26T21:22:15.322514Z","iopub.status.idle":"2021-12-26T21:22:15.331193Z","shell.execute_reply.started":"2021-12-26T21:22:15.322449Z","shell.execute_reply":"2021-12-26T21:22:15.330455Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_path(row):\n    row['old_image_path'] = f'{ROOT_DIR}/train_images/video_{row.video_id}/{row.video_frame}.jpg'\n    row['image_path'] = f'{IMAGE_DIR}/video_{row.video_id}_{row.video_frame}.jpg'\n    row['label_path'] = f'{LABEL_DIR}/video_{row.video_id}_{row.video_frame}.txt'\n    \n    return row\n\ndf = pd.read_csv(f'{ROOT_DIR}/train.csv')\ndf = df.progress_apply(get_path, axis=1)\ndf['annotations'] = df['annotations'].progress_apply(lambda x: ast.literal_eval(x))\ndf['num_bbox'] = df['annotations'].progress_apply(lambda x: len(x))\ndf['bboxes'] = df.annotations.progress_apply(get_bbox)\n\ndf.head(2)","metadata":{"editable":false,"execution":{"iopub.status.busy":"2021-12-26T21:22:15.332575Z","iopub.execute_input":"2021-12-26T21:22:15.333315Z","iopub.status.idle":"2021-12-26T21:23:00.459504Z","shell.execute_reply.started":"2021-12-26T21:22:15.333276Z","shell.execute_reply":"2021-12-26T21:23:00.458559Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# gets background images\ndf_empty_bbox = df[df[\"num_bbox\"] == 0]\ndf_empty_bbox = df_empty_bbox.sample(frac=1).reset_index(drop=True).iloc[:NUM_BACKGROUND_IMG,]\n\n# gets images with objects\ndf = df[df[\"num_bbox\"] > 0]\n\n# concats background images and image with objects\ndf = pd.concat([df, df_empty_bbox], ignore_index=True)","metadata":{"editable":false,"execution":{"iopub.status.busy":"2021-12-26T21:23:00.460778Z","iopub.execute_input":"2021-12-26T21:23:00.461061Z","iopub.status.idle":"2021-12-26T21:23:00.499161Z","shell.execute_reply.started":"2021-12-26T21:23:00.461029Z","shell.execute_reply":"2021-12-26T21:23:00.498241Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# copy from the original path to kaggle/working \n# because the models requires folder that can be written data on\n\ndef make_copy(path):\n    data = path.split('/')\n    filename = data[-1]\n    video_id = data[-2]\n    new_path = os.path.join(IMAGE_DIR, f'{video_id}_{filename}')\n    shutil.copy(path, new_path)\n    return\n\n# using Parrallel for faster copying \nimage_paths = df.old_image_path.tolist()\n_ = Parallel(n_jobs=-1, backend='threading')(delayed(make_copy)(path) for path in tqdm(image_paths))","metadata":{"editable":false,"execution":{"iopub.status.busy":"2021-12-26T21:23:00.500813Z","iopub.execute_input":"2021-12-26T21:23:00.501135Z","iopub.status.idle":"2021-12-26T21:23:22.110334Z","shell.execute_reply.started":"2021-12-26T21:23:00.501090Z","shell.execute_reply":"2021-12-26T21:23:22.109480Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"kf = GroupKFold(n_splits = 5)\ndf = df.reset_index(drop=True)\ndf['fold'] = -1\n\nfor fold, (_, val_idx) in enumerate(kf.split(df, y=df.video_id.tolist(), groups=df.sequence)):\n    df.loc[val_idx, 'fold'] = fold\n\ndf.fold.value_counts()","metadata":{"editable":false,"execution":{"iopub.status.busy":"2021-12-26T21:23:22.111334Z","iopub.execute_input":"2021-12-26T21:23:22.111582Z","iopub.status.idle":"2021-12-26T21:23:22.131377Z","shell.execute_reply.started":"2021-12-26T21:23:22.111551Z","shell.execute_reply":"2021-12-26T21:23:22.130619Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = df[df.fold != FOLD]\nvalid_df = df[df.fold == FOLD]\n\ntrain_df.shape[0], valid_df.shape[0]","metadata":{"editable":false,"execution":{"iopub.status.busy":"2021-12-26T21:23:22.133383Z","iopub.execute_input":"2021-12-26T21:23:22.133677Z","iopub.status.idle":"2021-12-26T21:23:25.316555Z","shell.execute_reply.started":"2021-12-26T21:23:22.133645Z","shell.execute_reply":"2021-12-26T21:23:25.315501Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# files requirement for YOLO\n\nwith open(os.path.join(CWD, 'train.txt'), 'w') as f:\n    for path in train_df.image_path.tolist():\n        f.write(path + '\\n')\n            \nwith open(os.path.join(CWD, 'val.txt'), 'w') as f:\n    for path in valid_df.image_path.tolist():\n        f.write(path + '\\n')\n\ndata = dict(\n    path  = CWD,\n    train =  os.path.join(CWD, 'train.txt'),\n    val   =  os.path.join(CWD, 'val.txt' ),\n    nc    = 1,\n    names = ['cots'],\n    )\n\nwith open(os.path.join(CWD, 'starfish.yaml'), 'w') as outfile:\n    yaml.dump(data, outfile, default_flow_style=False)\n\nf = open(os.path.join(CWD, 'starfish.yaml'), 'r')\nprint('\\nyaml:')\nprint(f.read())","metadata":{"editable":false,"execution":{"iopub.status.busy":"2021-12-26T21:23:25.317938Z","iopub.execute_input":"2021-12-26T21:23:25.318585Z","iopub.status.idle":"2021-12-26T21:23:25.546096Z","shell.execute_reply.started":"2021-12-26T21:23:25.318537Z","shell.execute_reply":"2021-12-26T21:23:25.545229Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for row_idx in tqdm(range(df.shape[0])):\n    row = df.iloc[row_idx]\n    bboxes_coco = np.array(row.bboxes).astype(np.float32).copy()\n    num_bbox = row.num_bbox\n    names = ['cots'] * num_bbox\n    labels = [0] * num_bbox\n\n    with open(row.label_path, 'w') as f:\n        if num_bbox < 1:\n            annot = ''\n            f.write(annot)\n            continue\n            \n        bboxes_yolo  = coco2yolo(IMAGE_WIDTH, IMAGE_HEIGHT, bboxes_coco)\n        bboxes_yolo  = np.clip(bboxes_yolo, 0, 1)\n        \n        for bbox_idx in range(len(bboxes_yolo)):\n            label = [str(labels[bbox_idx])]\n            bboxes = list(bboxes_yolo[bbox_idx].astype(str))\n            new_line = (['\\n'] if num_bbox!=(bbox_idx+1) else [''])\n            \n            annot =  label + bboxes + new_line\n            annot = ' '.join(annot)\n            annot = annot.strip(' ')\n            \n            f.write(annot)","metadata":{"editable":false,"execution":{"iopub.status.busy":"2021-12-26T21:23:25.547471Z","iopub.execute_input":"2021-12-26T21:23:25.548223Z","iopub.status.idle":"2021-12-26T21:23:28.645020Z","shell.execute_reply.started":"2021-12-26T21:23:25.548180Z","shell.execute_reply":"2021-12-26T21:23:28.644132Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%cd /kaggle/working\n!rm -r /kaggle/working/yolov5\n!cp -r ../input/d/cowfrica/yolov5 /kaggle/working/yolov5\n%cd yolov5\n\n!python train.py --img 1280\\\n--batch 10\\\n--epochs 20\\\n--data /kaggle/working/starfish.yaml\\\n--weights yolov5m.pt --workers 0\\\n--adam\\\n--save-period 1","metadata":{"editable":false,"execution":{"iopub.status.busy":"2021-12-26T21:23:28.646481Z","iopub.execute_input":"2021-12-26T21:23:28.646798Z","iopub.status.idle":"2021-12-26T21:23:41.917609Z","shell.execute_reply.started":"2021-12-26T21:23:28.646754Z","shell.execute_reply":"2021-12-26T21:23:41.916538Z"},"trusted":true},"execution_count":null,"outputs":[]}]}