{"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":"markdown","source":"**GitHub:[IceVision Framework](https://github.com/airctic/icevision)**\n\n**Documentation: [IceVision Docs](https://airctic.com/dev/)**","metadata":{}},{"cell_type":"markdown","source":"# **Installation**","metadata":{}},{"cell_type":"code","source":"import torch\ncuda_version_major = int(torch.version.cuda.split('.')[0])\n\n!git clone --depth=1 https://github.com/airctic/icevision.git\n%cd icevision\n!pip install -e .[all,dev]\n!pre-commit install\n    \nimport IPython\nIPython.Application.instance().kernel.do_shutdown(True)","metadata":{"execution":{"iopub.status.busy":"2022-01-12T02:19:24.292409Z","iopub.execute_input":"2022-01-12T02:19:24.293287Z","iopub.status.idle":"2022-01-12T02:21:27.827324Z","shell.execute_reply.started":"2022-01-12T02:19:24.293167Z","shell.execute_reply":"2022-01-12T02:21:27.826534Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import IPython\nIPython.Application.instance().kernel.do_shutdown(True)","metadata":{"execution":{"iopub.status.busy":"2022-01-12T03:05:16.640065Z","iopub.execute_input":"2022-01-12T03:05:16.640356Z","iopub.status.idle":"2022-01-12T03:05:16.648387Z","shell.execute_reply.started":"2022-01-12T03:05:16.640325Z","shell.execute_reply":"2022-01-12T03:05:16.647447Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# print(cuda_version_major)\nimport torch\nprint(torch.__version__)","metadata":{"execution":{"iopub.status.busy":"2022-01-12T02:23:21.680961Z","iopub.execute_input":"2022-01-12T02:23:21.681243Z","iopub.status.idle":"2022-01-12T02:23:22.163114Z","shell.execute_reply.started":"2022-01-12T02:23:21.681211Z","shell.execute_reply":"2022-01-12T02:23:22.162274Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install mmcv-full==\"1.3.17\" -f https://download.openmmlab.com/mmcv/dist/11/1.9.1/index.html --upgrade\n!pip install mmdet","metadata":{"execution":{"iopub.status.busy":"2022-01-12T02:39:12.934954Z","iopub.execute_input":"2022-01-12T02:39:12.935233Z","iopub.status.idle":"2022-01-12T03:02:21.133853Z","shell.execute_reply.started":"2022-01-12T02:39:12.935200Z","shell.execute_reply":"2022-01-12T03:02:21.132922Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Imports**","metadata":{}},{"cell_type":"code","source":"from icevision.all import *\n\nimport pandas as pd\nimport os\nimport ast\nimport numpy as np\n\nimport greatbarrierreef","metadata":{"execution":{"iopub.status.busy":"2022-01-12T03:05:25.960798Z","iopub.execute_input":"2022-01-12T03:05:25.961036Z","iopub.status.idle":"2022-01-12T03:06:15.044313Z","shell.execute_reply.started":"2022-01-12T03:05:25.960973Z","shell.execute_reply":"2022-01-12T03:06:15.043501Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Prepare Training dataset**","metadata":{}},{"cell_type":"code","source":"INPUT_DIR = '/kaggle/input/tensorflow-great-barrier-reef/'\nINPUT_DIR_IMG = '/kaggle/input/tensorflow-great-barrier-reef/train_images/'\nsys.path.append(INPUT_DIR)\nsys.path.append(INPUT_DIR_IMG)","metadata":{"execution":{"iopub.status.busy":"2022-01-12T03:06:27.725288Z","iopub.execute_input":"2022-01-12T03:06:27.725564Z","iopub.status.idle":"2022-01-12T03:06:27.730784Z","shell.execute_reply.started":"2022-01-12T03:06:27.725529Z","shell.execute_reply":"2022-01-12T03:06:27.729773Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TRAINING_RATIO = 0.8\n\ndata_df = pd.read_csv(os.path.join(INPUT_DIR, 'train.csv'))\n\n# Split the dataset so that no sequence is leaked from the training dataset into the validation dataset.\nsplit_index = int(TRAINING_RATIO * len(data_df))\nwhile data_df.iloc[split_index - 1].sequence == data_df.iloc[split_index].sequence:\n    split_index += 1\n\n# Shuffle both the training and validation datasets.\ntrain_data_df = data_df.iloc[:split_index].sample(frac=1).reset_index(drop=True)\nval_data_df = data_df.iloc[split_index:].sample(frac=1).reset_index(drop=True)\n\ntrain_positive_count = len(train_data_df[train_data_df.annotations != '[]'])\nval_positive_count = len(val_data_df[val_data_df.annotations != '[]'])\n\nprint('Training ratio (all samples):', \n      float(len(train_data_df)) / (len(train_data_df) + len(val_data_df)))\nprint('Training ratio (positive samples):', \n      float(train_positive_count) / (train_positive_count + val_positive_count))","metadata":{"execution":{"iopub.status.busy":"2022-01-12T03:06:28.035615Z","iopub.execute_input":"2022-01-12T03:06:28.036010Z","iopub.status.idle":"2022-01-12T03:06:28.333153Z","shell.execute_reply.started":"2022-01-12T03:06:28.035976Z","shell.execute_reply":"2022-01-12T03:06:28.331025Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Take only the positive images for training and validation\ntrain_data_df = train_data_df[train_data_df.annotations != '[]'].reset_index()\nprint('Number of positive images used for training:', len(train_data_df))\nval_data_df = val_data_df[val_data_df.annotations != '[]'].reset_index()\nprint('Number of positive images used for validation:', len(val_data_df))\n\ntrain_data_df[\"annotations\"] = train_data_df[\"annotations\"].map(lambda x : ast.literal_eval(x))\n\ntrain_data_df[\"filepath\"] = train_data_df.apply(lambda x : f\"video_{x.video_id}/{x.video_frame}.jpg\", axis=1)\n\ntrain_data_df.head(3)","metadata":{"execution":{"iopub.status.busy":"2022-01-12T03:06:28.379812Z","iopub.execute_input":"2022-01-12T03:06:28.380076Z","iopub.status.idle":"2022-01-12T03:06:28.710353Z","shell.execute_reply.started":"2022-01-12T03:06:28.380039Z","shell.execute_reply":"2022-01-12T03:06:28.709699Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data_df.head(3)","metadata":{"execution":{"iopub.status.busy":"2022-01-12T03:06:28.712053Z","iopub.execute_input":"2022-01-12T03:06:28.712308Z","iopub.status.idle":"2022-01-12T03:06:28.726679Z","shell.execute_reply.started":"2022-01-12T03:06:28.712271Z","shell.execute_reply":"2022-01-12T03:06:28.725929Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"HEIGHT, WIDTH = 720, 1280\npresize = 512\nsize = 384\n\ndf = train_data_df\ndf = df.explode(\"annotations\")\n\ndf[\"width\"] = [WIDTH]*len(df)\ndf[\"height\"] = [HEIGHT]*len(df)\ndf[\"label\"] = [\"starfish\"]*len(df)\n\ndf[\"xmin\"] = df.apply(lambda x : x.annotations[\"x\"], axis=1)\ndf[\"ymin\"] = df.apply(lambda x : x.annotations[\"y\"], axis=1)\ndf[\"xmax\"] = df.apply(lambda x : x.annotations[\"x\"]+x.annotations[\"width\"], axis=1)\ndf[\"ymax\"] = df.apply(lambda x : x.annotations[\"y\"]+x.annotations[\"height\"], axis=1)\n\ndf.loc[df[\"xmax\"] > 1280, \"xmax\"] = 1280\ndf.loc[df[\"ymax\"] > 720, \"ymax\"] = 720\n\ndf = df.drop([\"video_id\",\"sequence\",\"video_frame\",\"sequence_frame\",\n              \"image_id\",\"annotations\"], axis=1)\n\ndf = df.reset_index(drop=True)\ndf.head(3)","metadata":{"execution":{"iopub.status.busy":"2022-01-12T03:06:28.949586Z","iopub.execute_input":"2022-01-12T03:06:28.949867Z","iopub.status.idle":"2022-01-12T03:06:29.774262Z","shell.execute_reply.started":"2022-01-12T03:06:28.949836Z","shell.execute_reply":"2022-01-12T03:06:29.773506Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.head(10)","metadata":{"execution":{"iopub.status.busy":"2022-01-12T03:06:29.775754Z","iopub.execute_input":"2022-01-12T03:06:29.776016Z","iopub.status.idle":"2022-01-12T03:06:29.787416Z","shell.execute_reply.started":"2022-01-12T03:06:29.775978Z","shell.execute_reply":"2022-01-12T03:06:29.786726Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Data Parser**","metadata":{}},{"cell_type":"markdown","source":"### Creating [custom parser](https://airctic.com/dev/custom_parser/) for the COTS dataset","metadata":{}},{"cell_type":"code","source":"#Class template for creating custom parser in Icevision\ntemplate_record = ObjectDetectionRecord()\nParser.generate_template(template_record)","metadata":{"execution":{"iopub.status.busy":"2022-01-12T03:13:49.008808Z","iopub.execute_input":"2022-01-12T03:13:49.009108Z","iopub.status.idle":"2022-01-12T03:13:49.016364Z","shell.execute_reply.started":"2022-01-12T03:13:49.009072Z","shell.execute_reply":"2022-01-12T03:13:49.015556Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class COTSParser(Parser):\n    def __init__(self, template_record, data_dir, df):\n        super().__init__(template_record=template_record)\n        \n        self.data_dir = data_dir\n        self.df = df\n        self.class_map = ClassMap(list(self.df['label'].unique()))\n        \n    def __iter__(self) -> Any:\n        for o in self.df.itertuples():\n            yield o\n            \n    def __len__(self) -> int:\n        return len(self.df)\n    \n    def record_id(self, o) -> Hashable:\n        return o.filepath\n    \n    def parse_fields(self, o, record, is_new):\n        if is_new:\n            record.set_filepath(os.path.join(self.data_dir,o.filepath))\n            record.set_img_size(ImgSize(width=o.width, height=o.height))\n            record.detection.set_class_map(self.class_map)\n\n        record.detection.add_bboxes([BBox.from_xyxy(o.xmin, o.ymin, o.xmax, o.ymax)])\n        record.detection.add_labels([o.label])","metadata":{"execution":{"iopub.status.busy":"2022-01-12T03:13:49.338772Z","iopub.execute_input":"2022-01-12T03:13:49.339003Z","iopub.status.idle":"2022-01-12T03:13:49.347140Z","shell.execute_reply.started":"2022-01-12T03:13:49.338977Z","shell.execute_reply":"2022-01-12T03:13:49.346240Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Data Loader**","metadata":{}},{"cell_type":"code","source":"parser = COTSParser(template_record, INPUT_DIR_IMG, df)\n\ntrain_records, valid_records = parser.parse()\nprint(parser.class_map)","metadata":{"execution":{"iopub.status.busy":"2022-01-12T03:15:53.988076Z","iopub.execute_input":"2022-01-12T03:15:53.988373Z","iopub.status.idle":"2022-01-12T03:15:57.900003Z","shell.execute_reply.started":"2022-01-12T03:15:53.988337Z","shell.execute_reply":"2022-01-12T03:15:57.899189Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Augmentations using albumentation\ntrain_tfms = tfms.A.Adapter([*tfms.A.aug_tfms(size=size, presize=presize), tfms.A.Normalize()])\n\nvalid_tfms = tfms.A.Adapter([*tfms.A.resize_and_pad(size), tfms.A.Normalize()])\n\ntrain_ds = Dataset(train_records, train_tfms)\nvalid_ds = Dataset(valid_records, valid_tfms)\n\nsamples = [train_ds[0] for _ in range(5)]\nshow_samples(samples, ncols=3)","metadata":{"execution":{"iopub.status.busy":"2022-01-12T03:15:57.901430Z","iopub.execute_input":"2022-01-12T03:15:57.901868Z","iopub.status.idle":"2022-01-12T03:15:59.758649Z","shell.execute_reply.started":"2022-01-12T03:15:57.901822Z","shell.execute_reply":"2022-01-12T03:15:59.757753Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Defining Model**","metadata":{}},{"cell_type":"code","source":"PATH = \"../input/yolo-x-training-using-icevision/COTS_yolo-sx.pth\"\nfine_tune = True #set false if running this for the first time\n\nmodel_type = models.mmdet.yolox #selecting the model\nbackbone = model_type.backbones.yolox_s_8x8(pretrained=True) #selecting backbone for the model\nmodel = model_type.model(backbone=backbone(pretrained=True), num_classes=len(parser.class_map)) #instantiate the model\n\nif fine_tune:\n    state_dict = torch.load(PATH)\n    model.load_state_dict(state_dict)","metadata":{"execution":{"iopub.status.busy":"2022-01-12T03:15:59.760446Z","iopub.execute_input":"2022-01-12T03:15:59.760738Z","iopub.status.idle":"2022-01-12T03:16:01.153377Z","shell.execute_reply.started":"2022-01-12T03:15:59.760699Z","shell.execute_reply":"2022-01-12T03:16:01.152585Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dl = model_type.train_dl(train_ds, batch_size=1, shuffle=True)\nvalid_dl = model_type.valid_dl(valid_ds, batch_size=4, shuffle=False)","metadata":{"execution":{"iopub.status.busy":"2022-01-12T03:16:01.154840Z","iopub.execute_input":"2022-01-12T03:16:01.155160Z","iopub.status.idle":"2022-01-12T03:16:01.160015Z","shell.execute_reply.started":"2022-01-12T03:16:01.155111Z","shell.execute_reply":"2022-01-12T03:16:01.158966Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"metrics = [COCOMetric(metric_type=COCOMetricType.bbox)]","metadata":{"execution":{"iopub.status.busy":"2022-01-12T03:16:01.161500Z","iopub.execute_input":"2022-01-12T03:16:01.162067Z","iopub.status.idle":"2022-01-12T03:16:01.170975Z","shell.execute_reply.started":"2022-01-12T03:16:01.162024Z","shell.execute_reply":"2022-01-12T03:16:01.170233Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Model Training**","metadata":{}},{"cell_type":"code","source":"#finding the best prabable learning rate\nlearn = model_type.fastai.learner(dls=[train_dl, valid_dl], model=model, metrics=metrics)\nlearn.lr_find() ","metadata":{"execution":{"iopub.status.busy":"2022-01-12T03:16:01.172014Z","iopub.execute_input":"2022-01-12T03:16:01.172222Z","iopub.status.idle":"2022-01-12T03:16:05.860599Z","shell.execute_reply.started":"2022-01-12T03:16:01.172190Z","shell.execute_reply":"2022-01-12T03:16:05.859600Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#begin training\nlearn.fine_tune(5, 6.309573450380412e-07, freeze_epochs=1)","metadata":{"execution":{"iopub.status.busy":"2022-01-12T03:16:35.644238Z","iopub.execute_input":"2022-01-12T03:16:35.644553Z","iopub.status.idle":"2022-01-12T04:03:37.432235Z","shell.execute_reply.started":"2022-01-12T03:16:35.644508Z","shell.execute_reply":"2022-01-12T04:03:37.431479Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"infer_dl = model_type.infer_dl([valid_ds[0],valid_ds[4],valid_ds[7],valid_ds[9]], batch_size=1, shuffle=False)\npreds = model_type.predict_from_dl(model, infer_dl, keep_images=True)\nshow_preds(preds=preds)","metadata":{"execution":{"iopub.status.busy":"2022-01-12T04:21:25.162158Z","iopub.execute_input":"2022-01-12T04:21:25.162443Z","iopub.status.idle":"2022-01-12T04:21:26.423119Z","shell.execute_reply.started":"2022-01-12T04:21:25.162407Z","shell.execute_reply":"2022-01-12T04:21:26.422435Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"torch.save(model.state_dict(), \"COTS_yolo-sx2.pth\")","metadata":{"execution":{"iopub.status.busy":"2022-01-12T04:21:55.499056Z","iopub.execute_input":"2022-01-12T04:21:55.499333Z","iopub.status.idle":"2022-01-12T04:21:55.595235Z","shell.execute_reply.started":"2022-01-12T04:21:55.499300Z","shell.execute_reply":"2022-01-12T04:21:55.594438Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}