{"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":"# Install yolo & download pretrained","metadata":{}},{"cell_type":"code","source":"!git clone -b 0.3.0 https://github.com/meituan/YOLOv6.git\n!pip install -r YOLOv6/requirements.txt","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-08-08T05:58:30.834782Z","iopub.execute_input":"2023-08-08T05:58:30.835146Z","iopub.status.idle":"2023-08-08T05:59:13.282397Z","shell.execute_reply.started":"2023-08-08T05:58:30.835115Z","shell.execute_reply":"2023-08-08T05:59:13.281185Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!wget https://github.com/meituan/YOLOv6/releases/download/0.3.0/yolov6m.pt","metadata":{"execution":{"iopub.status.busy":"2023-08-08T06:00:58.384832Z","iopub.execute_input":"2023-08-08T06:00:58.385200Z","iopub.status.idle":"2023-08-08T06:01:01.171437Z","shell.execute_reply.started":"2023-08-08T06:00:58.385170Z","shell.execute_reply":"2023-08-08T06:01:01.170183Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Convert coco to yolo format","metadata":{}},{"cell_type":"code","source":"!mkdir -p /kaggle/working/labels/train/\n!mkdir -p /kaggle/working/labels/valid/\n\n!mkdir -p /kaggle/working/images/train/\n!mkdir -p /kaggle/working/images/valid/","metadata":{"execution":{"iopub.status.busy":"2023-08-08T05:59:13.285117Z","iopub.execute_input":"2023-08-08T05:59:13.286483Z","iopub.status.idle":"2023-08-08T05:59:17.512427Z","shell.execute_reply.started":"2023-08-08T05:59:13.286443Z","shell.execute_reply":"2023-08-08T05:59:17.511092Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%writefile COCO2YOLO.py\n# https://github.com/alexmihalyk23/COCO2YOLO\nimport json\nimport os\nimport argparse\nparser = argparse.ArgumentParser(description='Test yolo data.')\nparser.add_argument('-j', help='JSON file', dest='json', required=True)\nparser.add_argument('-o', help='path to output folder', dest='out',required=True)\n\nargs = parser.parse_args()\n\njson_file = args.json \noutput = args.out \nclass COCO2YOLO:\n    def __init__(self):\n        self._check_file_and_dir(json_file, output)\n        self.labels = json.load(open(json_file, 'r', encoding='utf-8'))\n        self.coco_id_name_map = self._categories()\n        self.coco_name_list = list(self.coco_id_name_map.values())\n        print(\"total images\", len(self.labels['images']))\n        print(\"total categories\", len(self.labels['categories']))\n        print(\"total labels\", len(self.labels['annotations']))\n\n    def _check_file_and_dir(self, file_path, dir_path):\n        if not os.path.exists(file_path):\n            raise ValueError(\"file not found\")\n        if not os.path.exists(dir_path):\n            os.makedirs(dir_path)\n\n    def _categories(self):\n        categories = {}\n        for cls in self.labels['categories']:\n            categories[cls['id']] = cls['name']\n        return categories\n\n    def _load_images_info(self):\n        images_info = {}\n        for image in self.labels['images']:\n            id = image['id']\n            file_name = image['file_name']\n            if file_name.find('\\\\') > -1:\n                file_name = file_name[file_name.index('\\\\')+1:]\n            w = image['width']\n            h = image['height']\n            images_info[id] = (file_name, w, h)\n\n        return images_info\n\n    def _bbox_2_yolo(self, bbox, img_w, img_h):\n        x, y, w, h = bbox[0], bbox[1], bbox[2], bbox[3]\n        centerx = bbox[0] + w / 2\n        centery = bbox[1] + h / 2\n        dw = 1 / img_w\n        dh = 1 / img_h\n        centerx *= dw\n        w *= dw\n        centery *= dh\n        h *= dh\n        return centerx, centery, w, h\n\n    def _convert_anno(self, images_info):\n        anno_dict = dict()\n        for anno in self.labels['annotations']:\n            bbox = anno['bbox']\n            image_id = anno['image_id']\n            category_id = anno['category_id']\n\n            image_info = images_info.get(image_id)\n            image_name = image_info[0]\n            img_w = image_info[1]\n            img_h = image_info[2]\n            yolo_box = self._bbox_2_yolo(bbox, img_w, img_h)\n\n            anno_info = (image_name, category_id, yolo_box)\n            anno_infos = anno_dict.get(image_id)\n            if not anno_infos:\n                anno_dict[image_id] = [anno_info]\n            else:\n                anno_infos.append(anno_info)\n                anno_dict[image_id] = anno_infos\n        return anno_dict\n\n    def save_classes(self):\n        sorted_classes = list(map(lambda x: x['name'], sorted(self.labels['categories'], key=lambda x: x['id'])))\n        print('coco names', sorted_classes)\n        with open('coco.names', 'w', encoding='utf-8') as f:\n            for cls in sorted_classes:\n                f.write(cls + '\\n')\n        f.close()\n\n    def coco2yolo(self):\n        print(\"loading image info...\")\n        images_info = self._load_images_info()\n        print(\"loading done, total images\", len(images_info))\n\n        print(\"start converting...\")\n        anno_dict = self._convert_anno(images_info)\n        print(\"converting done, total labels\", len(anno_dict))\n\n        print(\"saving txt file...\")\n        self._save_txt(anno_dict)\n        print(\"saving done\")\n\n    def _save_txt(self, anno_dict):\n        for k, v in anno_dict.items():\n            file_name = v[0][0].split(\".\")[0] + \".txt\"\n            with open(os.path.join(output, file_name), 'w', encoding='utf-8') as f:\n                print(k, v)\n                for obj in v:\n                    cat_name = self.coco_id_name_map.get(obj[1])\n                    category_id = self.coco_name_list.index(cat_name)\n                    box = ['{:.6f}'.format(x) for x in obj[2]]\n                    box = ' '.join(box)\n                    line = str(category_id) + ' ' + box\n                    f.write(line + '\\n')\n\n\nif __name__ == '__main__':\n    c2y = COCO2YOLO()\n    c2y.coco2yolo()","metadata":{"execution":{"iopub.status.busy":"2023-08-08T05:59:17.514846Z","iopub.execute_input":"2023-08-08T05:59:17.515770Z","iopub.status.idle":"2023-08-08T05:59:17.526953Z","shell.execute_reply.started":"2023-08-08T05:59:17.515723Z","shell.execute_reply":"2023-08-08T05:59:17.525744Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!python COCO2YOLO.py -j /kaggle/input/coco-hubmap-final-2class/coco_annotations_train_all_fold1_2classes.json -o /kaggle/working/labels/train\n!python COCO2YOLO.py -j /kaggle/input/coco-hubmap-final-2class/coco_annotations_valid_all_fold1_2classes.json -o /kaggle/working/labels/valid\n","metadata":{"execution":{"iopub.status.busy":"2023-08-08T05:59:17.529283Z","iopub.execute_input":"2023-08-08T05:59:17.529664Z","iopub.status.idle":"2023-08-08T05:59:20.886055Z","shell.execute_reply.started":"2023-08-08T05:59:17.529630Z","shell.execute_reply":"2023-08-08T05:59:20.884784Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nfrom tqdm.auto import tqdm\nimport shutil\nfrom joblib import delayed, Parallel\nfrom glob import glob","metadata":{"execution":{"iopub.status.busy":"2023-08-08T05:59:28.634979Z","iopub.execute_input":"2023-08-08T05:59:28.635392Z","iopub.status.idle":"2023-08-08T05:59:28.753455Z","shell.execute_reply.started":"2023-08-08T05:59:28.635349Z","shell.execute_reply":"2023-08-08T05:59:28.752439Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMG_DIR = '/kaggle/input/hubmap-hacking-the-human-vasculature/train'\ndef copy_file(file_path):\n    file_name = file_path.split('/')[-1]\n    img_id = file_name[:-4]\n    if \"/train/\" in file_path:\n        fold = 'train'\n    else:\n        fold = 'valid'\n    shutil.copyfile(f'{IMG_DIR}/{img_id}.tif', f'/kaggle/working/images/{fold}/{img_id}.jpg')","metadata":{"execution":{"iopub.status.busy":"2023-08-08T05:59:45.588943Z","iopub.execute_input":"2023-08-08T05:59:45.589385Z","iopub.status.idle":"2023-08-08T05:59:45.596872Z","shell.execute_reply.started":"2023-08-08T05:59:45.589327Z","shell.execute_reply":"2023-08-08T05:59:45.595679Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels_path = glob('/kaggle/working/labels/train/*.txt')\n_ = Parallel(n_jobs=8)(delayed(copy_file)(x) for x in tqdm(labels_path))","metadata":{"execution":{"iopub.status.busy":"2023-08-08T06:00:00.221064Z","iopub.execute_input":"2023-08-08T06:00:00.221464Z","iopub.status.idle":"2023-08-08T06:00:05.995977Z","shell.execute_reply.started":"2023-08-08T06:00:00.221431Z","shell.execute_reply":"2023-08-08T06:00:05.994855Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels_path = glob('/kaggle/working/labels/valid/*.txt')\n_ = Parallel(n_jobs=8)(delayed(copy_file)(x) for x in tqdm(labels_path))","metadata":{"execution":{"iopub.status.busy":"2023-08-08T06:00:06.000034Z","iopub.execute_input":"2023-08-08T06:00:06.000407Z","iopub.status.idle":"2023-08-08T06:00:06.339317Z","shell.execute_reply.started":"2023-08-08T06:00:06.000373Z","shell.execute_reply":"2023-08-08T06:00:06.336398Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Write config","metadata":{}},{"cell_type":"code","source":"%%writefile /kaggle/working/hubmap_dataset.yaml\n# Please insure that your custom_dataset are put in same parent dir with YOLOv6_DIR\ntrain: /kaggle/working/images/train # train images\n# - images\n# - labels\nval: /kaggle/working/images/valid # val images\ntest: /kaggle/working/images/valid # test images (optional)\n\n# whether it is coco dataset, only coco dataset should be set to True.\nis_coco: False\n# anno_path: /kaggle/working/coco_annotations_train_all_fold1.json\n# Classes\nnc: 2  # number of classes\nnames: ['blood_vessel', 'unsure']  # class names","metadata":{"execution":{"iopub.status.busy":"2023-08-08T06:00:30.896863Z","iopub.execute_input":"2023-08-08T06:00:30.897255Z","iopub.status.idle":"2023-08-08T06:00:30.905948Z","shell.execute_reply.started":"2023-08-08T06:00:30.897221Z","shell.execute_reply":"2023-08-08T06:00:30.904841Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%writefile /kaggle/working/yolov6m_hubmap.py\n# YOLOv6m model\nmodel = dict(\n    type='YOLOv6m',\n    pretrained='/kaggle/working/yolov6m.pt',\n    depth_multiple=0.60,  \n    width_multiple=0.75,\n    backbone=dict(\n        type='CSPBepBackbone',\n        num_repeats=[1, 6, 12, 18, 6],\n        out_channels=[64, 128, 256, 512, 1024],\n        csp_e=float(2)/3,\n        fuse_P2=True,\n        ),\n    neck=dict(\n        type='CSPRepBiFPANNeck',\n        num_repeats=[12, 12, 12, 12],\n        out_channels=[256, 128, 128, 256, 256, 512],\n        csp_e=float(2)/3,\n        ),\n    head=dict(\n        type='EffiDeHead',\n        in_channels=[128, 256, 512],\n        num_layers=3,\n        begin_indices=24,\n        anchors=3,\n        anchors_init=[[10,13, 19,19, 33,23], \n                      [30,61, 59,59, 59,119], \n                      [116,90, 185,185, 373,326]],\n        out_indices=[17, 20, 23],\n        strides=[8, 16, 32],\n        atss_warmup_epoch=0,\n        iou_type='giou',\n        use_dfl=True,\n        reg_max=16, #if use_dfl is False, please set reg_max to 0\n        distill_weight={\n            'class': 0.8,\n            'dfl': 1.0,\n        },\n    )\n)\n\nsolver = dict(\n    optim='SGD',\n    lr_scheduler='Cosine',\n    lr0=0.0032,\n    lrf=0.12,\n    momentum=0.843,\n    weight_decay=0.00036,\n    warmup_epochs=2.0,\n    warmup_momentum=0.5,\n    warmup_bias_lr=0.05\n)\n\ndata_aug = dict(\n    hsv_h=0.0138,\n    hsv_s=0.664,\n    hsv_v=0.464,\n    degrees=0.373,\n    translate=0.245,\n    scale=0.898,\n    shear=0.602,\n    flipud=0.00856,\n    fliplr=0.5,\n    mosaic=1.0,\n    mixup=0.243,\n)","metadata":{"execution":{"iopub.status.busy":"2023-08-08T06:01:35.009276Z","iopub.execute_input":"2023-08-08T06:01:35.009748Z","iopub.status.idle":"2023-08-08T06:01:35.017374Z","shell.execute_reply.started":"2023-08-08T06:01:35.009709Z","shell.execute_reply":"2023-08-08T06:01:35.016402Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Training","metadata":{}},{"cell_type":"code","source":"%cd /kaggle/working/YOLOv6\n!python tools/train.py --batch 8 --epochs 1 --img 1024 --eval-interval 5 --conf /kaggle/working/yolov6m_hubmap.py --data /kaggle/working/hubmap_dataset.yaml --device 0","metadata":{"execution":{"iopub.status.busy":"2023-08-08T06:02:49.016039Z","iopub.execute_input":"2023-08-08T06:02:49.016511Z","iopub.status.idle":"2023-08-08T06:07:21.672008Z","shell.execute_reply.started":"2023-08-08T06:02:49.016466Z","shell.execute_reply":"2023-08-08T06:07:21.670626Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# eval\n!python tools/eval.py --batch-siz 16 --weights runs/train/exp1/weights/best_ckpt.pt --data /kaggle/working/hubmap_dataset.yaml --img-size 1024 --device 0 --verbose","metadata":{"execution":{"iopub.status.busy":"2023-08-08T06:07:29.191847Z","iopub.execute_input":"2023-08-08T06:07:29.192284Z","iopub.status.idle":"2023-08-08T06:07:52.393845Z","shell.execute_reply.started":"2023-08-08T06:07:29.192244Z","shell.execute_reply":"2023-08-08T06:07:52.392551Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}