{"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":"<p style='text-align: center;'><span style=\"color: #000508; font-family: Segoe UI; font-size: 2.5em; font-weight: 300;\">MMDetection+Cascade RCNN+Weight&Bias</span></p>","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19"}},{"cell_type":"markdown","source":"<span style=\"color: #E45D00; font-family: Segoe UI; font-size: 1.9em; font-weight: 300;\">Overview</span>\n\n&nbsp;&nbsp;✅&nbsp;&nbsp;MMDetection and Weights & Biases Setup<br>\n&nbsp;&nbsp;✅&nbsp;&nbsp;Preparation of MMDetection Config<br>\n&nbsp;&nbsp;✅&nbsp;&nbsp;Weights & Biases Integration<br>\n&nbsp;&nbsp;✅&nbsp;&nbsp;Training and Evaluation<br>\n&nbsp;&nbsp;✅&nbsp;&nbsp;Experiment Tracking and Logging with Weights & Biases<br>\n&nbsp;&nbsp;✅&nbsp;&nbsp;Inference<br>\n\n<span style=\"color: #E45D00; font-family: Segoe UI; font-size: 1.9em; font-weight: 300;\">MMDetection</span>\n\n[MMDetection](https://github.com/open-mmlab/mmdetection) is an open-source toolbox based on PyTorch for Object Detection and Segmentation tasks. The toolbox supports over **50+ baselines**.\n\n<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.4em;\">🧫 Features:</span>\n\n<p style='text-align: justify; font-family: Segoe UI;'><span style=\"color: #000508;  font-size: 1.1em; font-weight: 600;\">Modular Design</span>: The framework is split into different components and we can easily construct a customized object detection framework by combining different modules.</p>\n\n<p style='text-align: justify; font-family: Segoe UI;'><span style=\"color: #000508;  font-size: 1.1em; font-weight: 600;\">Support of multiple frameworks out of box</span>: The toolbox directly supports popular and contemporary detection frameworks, e.g. Faster RCNN, Mask RCNN, RetinaNet, etc.</p>\n\n<p style='text-align: justify; font-family: Segoe UI;'><span style=\"color: #000508;  font-size: 1.1em; font-weight: 600;\">High efficiency</span>: All basic bbox and mask operations run on GPUs. The training speed is faster than or comparable to other codebases, including Detectron2, maskrcnn-benchmark and SimpleDet.</p>\n\n<p style='text-align: justify; font-family: Segoe UI;'><span style=\"color: #000508;  font-size: 1.1em; font-weight: 600;\">State of the art</span>: The toolbox stems from the codebase developed by the MMDet team, who won COCO Detection Challenge in 2018.</p>","metadata":{"execution":{"iopub.status.busy":"2021-07-26T03:14:32.758685Z","iopub.execute_input":"2021-07-26T03:14:32.759254Z","iopub.status.idle":"2021-07-26T03:14:33.005808Z","shell.execute_reply.started":"2021-07-26T03:14:32.759219Z","shell.execute_reply":"2021-07-26T03:14:33.00449Z"}}},{"cell_type":"markdown","source":"<span style=\"color: #E45D00; font-family: Segoe UI; font-size: 1.9em; font-weight: 300;\">📐 Setup MMDetection</span>","metadata":{}},{"cell_type":"code","source":"!nvidia-smi","metadata":{"execution":{"iopub.status.busy":"2022-04-29T02:13:38.212092Z","iopub.execute_input":"2022-04-29T02:13:38.212465Z","iopub.status.idle":"2022-04-29T02:13:38.928546Z","shell.execute_reply.started":"2022-04-29T02:13:38.212387Z","shell.execute_reply":"2022-04-29T02:13:38.927397Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%bash\n# Check nvcc version\nnvcc -V\necho\n# Check GCC version\ngcc --version\necho\n# Check the version of torch and cuda packages\npip list | grep \"torch\\|cuda\"","metadata":{"execution":{"iopub.status.busy":"2022-04-29T02:13:40.36972Z","iopub.execute_input":"2022-04-29T02:13:40.37015Z","iopub.status.idle":"2022-04-29T02:13:42.043868Z","shell.execute_reply.started":"2022-04-29T02:13:40.370106Z","shell.execute_reply":"2022-04-29T02:13:42.042959Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# !git clone https://github.com/SwinTransformer/Swin-Transformer-Object-Detection.git swinTxs","metadata":{"execution":{"iopub.status.busy":"2022-04-29T02:13:42.046048Z","iopub.execute_input":"2022-04-29T02:13:42.046323Z","iopub.status.idle":"2022-04-29T02:13:42.050751Z","shell.execute_reply.started":"2022-04-29T02:13:42.046294Z","shell.execute_reply":"2022-04-29T02:13:42.049695Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install mmcv-full==1.4.8 -f https://download.openmmlab.com/mmcv/dist/cu110/torch1.7.0/index.html","metadata":{"execution":{"iopub.status.busy":"2022-04-29T02:13:42.052504Z","iopub.execute_input":"2022-04-29T02:13:42.053042Z","iopub.status.idle":"2022-04-29T02:13:58.778599Z","shell.execute_reply.started":"2022-04-29T02:13:42.053003Z","shell.execute_reply":"2022-04-29T02:13:58.777638Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# !cd swinTxs && pip install -r requirements.txt && python setup.py develop","metadata":{"scrolled":true,"execution":{"iopub.status.busy":"2022-04-29T02:13:58.780426Z","iopub.execute_input":"2022-04-29T02:13:58.780806Z","iopub.status.idle":"2022-04-29T02:13:58.787152Z","shell.execute_reply.started":"2022-04-29T02:13:58.780766Z","shell.execute_reply":"2022-04-29T02:13:58.786341Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%capture\n!rm -rf mmdetection\n!git clone https://github.com/open-mmlab/mmdetection.git\n!cd mmdetection && pip install -r requirements.txt && pip install -v -e .","metadata":{"scrolled":true,"execution":{"iopub.status.busy":"2022-04-29T02:13:58.789815Z","iopub.execute_input":"2022-04-29T02:13:58.790115Z","iopub.status.idle":"2022-04-29T02:15:25.21916Z","shell.execute_reply.started":"2022-04-29T02:13:58.790089Z","shell.execute_reply":"2022-04-29T02:15:25.218045Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<span style=\"color: #E45D00; font-family: Segoe UI; font-size: 1.9em; font-weight: 300;\">Setup Weights & Biases</span>","metadata":{}},{"cell_type":"code","source":"!pip install wandb","metadata":{"execution":{"iopub.status.busy":"2022-04-29T02:15:25.220754Z","iopub.execute_input":"2022-04-29T02:15:25.221093Z","iopub.status.idle":"2022-04-29T02:15:32.493882Z","shell.execute_reply.started":"2022-04-29T02:15:25.221053Z","shell.execute_reply":"2022-04-29T02:15:32.49294Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"To connect the Kaggle Notebook and log in to Weights & Biases, we need to create an API key:\n\n1. New users can sign up for a Free Weights & Biases account for Research and Personal use from the https://wandb.ai/site page. Sign up process takes around 1-2 minutes.\n2. Now get the API key from https://wandb.ai/authorize.\n\nLogin to Weights & Biases from the notebook with the API key by using any of the two methods below:\n\n* Interative:\n    1. Run a cell with wandb.login(). It will ask for the API key, which can be copied and pasted to authenticate.\n\n* Kaggle Secrets:\n    1. The recommended way to use the API key is to use Kaggle Secrets to store the API key. From the top Menu on the Notebook Editor, click on 'Add-ons' and then, select 'Secrets'.\n    2. Select 'Add a new secret' and provide 'wandb_key' for label and it's value as the API key obtained from the previous steps.","metadata":{}},{"cell_type":"code","source":"import wandb\nfrom kaggle_secrets import UserSecretsClient\n\nuser_secrets = UserSecretsClient()\n\n# I have saved my API token with \"wandb_api\" as Label. \n# If you use some other Label make sure to change the same below. \nwandb_api = user_secrets.get_secret(\"wandb_key\") \n\nwandb.login(key=wandb_api)","metadata":{"execution":{"iopub.status.busy":"2022-04-29T02:15:32.495312Z","iopub.execute_input":"2022-04-29T02:15:32.495652Z","iopub.status.idle":"2022-04-29T02:15:34.406489Z","shell.execute_reply.started":"2022-04-29T02:15:32.495612Z","shell.execute_reply":"2022-04-29T02:15:34.405593Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<span style=\"color: #E45D00; font-family: Segoe UI; font-size: 1.9em; font-weight: 300;\">Imports and Seed Everything</span>","metadata":{}},{"cell_type":"code","source":"import sys\nsys.path.insert(0, \"./mmdetection\")    # 将mmdetection文件路径添加到系统环境\n\nimport os\n# Check Pytorch installation\nimport torch, torchvision\nprint(torch.__version__, torch.cuda.is_available())\n\n# Check mmcv installation\nfrom mmcv.ops import get_compiling_cuda_version, get_compiler_version\nprint(get_compiling_cuda_version())\nprint(get_compiler_version())\n\n# Check MMDetection installation\nfrom mmdet.apis import set_random_seed\n\n# Imports\nimport mmdet\nfrom mmdet.apis import set_random_seed\nfrom mmdet.datasets import build_dataset\nfrom mmdet.models import build_detector\nfrom mmdet.apis import train_detector\n\nimport random\nimport numpy as np\nfrom pathlib import Path\nimport copy\nimport json\nfrom pycocotools.coco import COCO","metadata":{"execution":{"iopub.status.busy":"2022-04-29T02:15:34.409273Z","iopub.execute_input":"2022-04-29T02:15:34.409587Z","iopub.status.idle":"2022-04-29T02:15:49.603094Z","shell.execute_reply.started":"2022-04-29T02:15:34.409551Z","shell.execute_reply":"2022-04-29T02:15:49.602171Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"seed = 42\n\n\"\"\"Sets the random seeds.\"\"\"\nset_random_seed(seed, deterministic=False)\nrandom.seed(seed)\nnp.random.seed(seed)\ntorch.manual_seed(seed)\ntorch.cuda.manual_seed(seed)\ntorch.backends.cudnn.deterministic = True\ntorch.backends.cudnn.benchmark = False\nos.environ['PYTHONHASHSEED'] = str(seed)","metadata":{"execution":{"iopub.status.busy":"2022-04-29T02:15:49.605154Z","iopub.execute_input":"2022-04-29T02:15:49.605502Z","iopub.status.idle":"2022-04-29T02:15:49.616438Z","shell.execute_reply.started":"2022-04-29T02:15:49.605467Z","shell.execute_reply":"2022-04-29T02:15:49.615523Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<span style=\"color: #E45D00; font-family: Segoe UI; font-size: 1.9em; font-weight: 300;\">Split Train and Valid Data Set</span>\n","metadata":{}},{"cell_type":"code","source":"!mkdir new_anno","metadata":{"execution":{"iopub.status.busy":"2022-04-29T02:15:49.617856Z","iopub.execute_input":"2022-04-29T02:15:49.618431Z","iopub.status.idle":"2022-04-29T02:15:50.287698Z","shell.execute_reply.started":"2022-04-29T02:15:49.618394Z","shell.execute_reply":"2022-04-29T02:15:50.286606Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"You can change the test_n to get a different split","metadata":{}},{"cell_type":"code","source":"random.seed(seed)\n\ndef create_subset(c, cats, valid_n = 3000,test_n=3000):\n    new_coco = {}\n    cat_ids = c.getCatIds(cats)\n    train_img_ids = set()\n    valid_img_ids = set()\n    test_img_ids = set()\n    for cat in cat_ids[::-1]:                                    # 按照检测种类均匀分配图片\n        img_ids = copy.copy(c.getImgIds(catIds=[cat]))\n        random.shuffle(img_ids)\n        tn = min(3000, int(len(img_ids) / 10))\n        vn = min(3000, int(len(img_ids) / 10))\n        new_test = set(img_ids[:tn])\n        new_valid = set(img_ids[tn:tn + vn])\n        exist_test_ids = new_test.intersection(train_img_ids)    # 找到交集（有些图片在其他物品特征处理的时候已经分到了train中）\n        exist_test_ids_in_valid = new_test.intersection(new_valid)\n        exist_valid_ids = new_valid.intersection(train_img_ids)\n        test_ids = new_test.difference(exist_test_ids).difference(exist_test_ids_in_valid) # 挑出new_test中不是交集的部分\n        valid_ids = new_valid.difference(exist_valid_ids)\n        train_ids = set(img_ids).difference(test_ids).difference(valid_ids)\n        print(tn, vn, len(img_ids), len(new_test), len(test_ids), len(new_valid), len(valid_ids),len(train_ids))\n        train_img_ids.update(train_ids)\n        test_img_ids.update(test_ids)\n        valid_img_ids.update(valid_ids)\n#         print(len(test_img_ids))\n\n    # prune duplicates\n    dup_test = train_img_ids.intersection(test_img_ids)\n    dup_valid = train_img_ids.intersection(valid_img_ids)\n    train_img_ids = train_img_ids - dup_test - valid_img_ids\n    \n    train_anno_ids = set()\n    test_anno_ids = set()\n    valid_anno_ids = set()\n    for cat in cat_ids:\n        train_anno_ids.update(c.getAnnIds(imgIds=list(train_img_ids), catIds=[cat]))\n        test_anno_ids.update(c.getAnnIds(imgIds=list(test_img_ids), catIds=[cat]))\n        valid_anno_ids.update(c.getAnnIds(imgIds=list(valid_img_ids), catIds=[cat]))\n\n    assert len(train_img_ids.intersection(test_img_ids)) == 0, 'img id conflicts with test, {} '.format(train_img_ids.intersection(test_img_ids))\n    assert len(train_anno_ids.intersection(test_anno_ids)) == 0, 'anno id conflicts with test'\n    assert len(train_img_ids.intersection(valid_img_ids)) == 0, 'img id conflicts with valid, {} '.format(train_img_ids.intersection(valid_img_ids))\n    assert len(train_anno_ids.intersection(valid_anno_ids)) == 0, 'anno id conflicts with valid'\n    print('train img ids #:', len(train_img_ids), 'train anno #:', len(train_anno_ids))\n    print('valid img ids #:', len(valid_img_ids), 'valid anno #:', len(valid_anno_ids))\n    print('test img ids #:', len(test_img_ids), 'test anno #:', len(test_anno_ids))\n    new_coco_test = copy.deepcopy(new_coco)\n    new_coco_valid = copy.deepcopy(new_coco)\n\n    new_coco[\"images\"] = c.loadImgs(list(train_img_ids))\n    new_coco[\"annotations\"] = c.loadAnns(list(train_anno_ids))\n    \n    for ann in new_coco[\"annotations\"]:\n        ann.pop('segmentation', None)\n    new_coco[\"categories\"] = c.loadCats(cat_ids)\n    \n    new_coco_valid['images'] = c.loadImgs(list(valid_img_ids))\n    new_coco_valid['annotations'] = c.loadAnns(list(valid_anno_ids))\n    \n    new_coco_test[\"images\"] = c.loadImgs(list(test_img_ids))\n    new_coco_test[\"annotations\"] = c.loadAnns(list(test_anno_ids))\n    for ann in new_coco_test[\"annotations\"]:\n        ann.pop('segmentation', None)\n    for ann in new_coco_valid[\"annotations\"]:\n        ann.pop('segmentation', None)\n    new_coco_test[\"categories\"] = c.loadCats(cat_ids)\n    new_coco_valid['categories'] = c.loadCats(cat_ids)\n    print('new train split, images:', len(new_coco[\"images\"]), 'annos:', len(new_coco[\"annotations\"]))\n    print('new valid split, images:', len(new_coco_valid[\"images\"]), 'annos:', len(new_coco_valid[\"annotations\"]))\n    print('new test split, images:', len(new_coco_test[\"images\"]), 'annos:', len(new_coco_test[\"annotations\"]))\n    return new_coco, new_coco_valid ,new_coco_test\n\ncoco = COCO('../input/wood-bbox-normal/bbox_coco_dataset2.json')\nnc, nc_valid, nc_test = create_subset(coco, [\"Live knot\", \"Dead knot\", \"Knot with crack\", \"Crack\",\n                                           \"Resin\", \"Marrow\", \"Quartzity\", \"Knot missing\",\n                                           \"Blue stain\", \"Overgrown\"])\n\nwith open('./new_anno/new_train.json', 'w') as f:\n    json.dump(nc, f)\nwith open('./new_anno/new_valid.json', 'w') as f:\n    json.dump(nc_valid, f)\nwith open('./new_anno/new_test.json', 'w') as f:\n    json.dump(nc_test, f)","metadata":{"execution":{"iopub.status.busy":"2022-04-29T02:15:50.291325Z","iopub.execute_input":"2022-04-29T02:15:50.291596Z","iopub.status.idle":"2022-04-29T02:15:52.813649Z","shell.execute_reply.started":"2022-04-29T02:15:50.291568Z","shell.execute_reply":"2022-04-29T02:15:52.812772Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"coco.getCatIds()","metadata":{"execution":{"iopub.status.busy":"2022-04-29T02:15:52.81493Z","iopub.execute_input":"2022-04-29T02:15:52.815266Z","iopub.status.idle":"2022-04-29T02:15:52.822941Z","shell.execute_reply.started":"2022-04-29T02:15:52.815232Z","shell.execute_reply":"2022-04-29T02:15:52.822065Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"coco = COCO('../input/wood-bbox-normal/bbox_coco_dataset2.json')\ncoco.getImgIds(catIds=[10])","metadata":{"execution":{"iopub.status.busy":"2022-04-29T02:15:52.824241Z","iopub.execute_input":"2022-04-29T02:15:52.824775Z","iopub.status.idle":"2022-04-29T02:15:53.390658Z","shell.execute_reply.started":"2022-04-29T02:15:52.824738Z","shell.execute_reply":"2022-04-29T02:15:53.389802Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"coco.loadImgs(ids = [17571, 17572, 13414, 11366, 9556, 15157])","metadata":{"execution":{"iopub.status.busy":"2022-04-29T02:15:53.391929Z","iopub.execute_input":"2022-04-29T02:15:53.39229Z","iopub.status.idle":"2022-04-29T02:15:53.401571Z","shell.execute_reply.started":"2022-04-29T02:15:53.392252Z","shell.execute_reply":"2022-04-29T02:15:53.400639Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"coco.getAnnIds(imgIds= [17571])","metadata":{"execution":{"iopub.status.busy":"2022-04-29T02:15:53.402603Z","iopub.execute_input":"2022-04-29T02:15:53.403134Z","iopub.status.idle":"2022-04-29T02:15:53.412207Z","shell.execute_reply.started":"2022-04-29T02:15:53.403036Z","shell.execute_reply":"2022-04-29T02:15:53.41139Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"coco.loadAnns(ids = [38453, 38454, 38455, 38456, 38457])","metadata":{"execution":{"iopub.status.busy":"2022-04-29T02:15:53.413527Z","iopub.execute_input":"2022-04-29T02:15:53.414041Z","iopub.status.idle":"2022-04-29T02:15:53.423583Z","shell.execute_reply.started":"2022-04-29T02:15:53.414005Z","shell.execute_reply":"2022-04-29T02:15:53.422245Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<span style=\"color: #E45D00; font-family: Segoe UI; font-size: 1.9em; font-weight: 300;\">🔨 Prepare the MMDetection Config</span>","metadata":{}},{"cell_type":"code","source":"from mmcv import Config\n\n# baseline_cfg_path = \"/kaggle/working/mmdetection/configs/cascade_rcnn/cascade_rcnn_x101_32x4d_fpn_1x_coco.py\"\n# baseline_cfg_path = \"/kaggle/working/mmdetection/configs/swin/cascade_rcnn_swin-t-p4-w7_fpn_1x_coco.py\"\nbaseline_cfg_path = \"/kaggle/working/mmdetection/configs/cascade_rcnn/cascade_rcnn_r50_fpn_1x_coco.py\"\n\ncfg = Config.fromfile(baseline_cfg_path)","metadata":{"execution":{"iopub.status.busy":"2022-04-29T02:15:53.424596Z","iopub.execute_input":"2022-04-29T02:15:53.42686Z","iopub.status.idle":"2022-04-29T02:15:53.453405Z","shell.execute_reply.started":"2022-04-29T02:15:53.426831Z","shell.execute_reply":"2022-04-29T02:15:53.452562Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.6em; font-weight: 300;\">General Training Settings</span>\n\n","metadata":{}},{"cell_type":"code","source":"# model_name = 'cascade_rcnn_swin-t-p4-w7_fpn_1x_coco'\nmodel_name = 'cascade_rcnn_r50_fpn_1x'\njob = 8\n\n# Folder to store model logs and weight files\njob_folder = f'/kaggle/working/job{job}_{model_name}'\ncfg.work_dir = job_folder\n\n# Change the wandb username and project name below\nwnb_username = 'sunstar0708'\nwnb_project_name = 'wood_surface_defect'\n\ncfg.device = mmdet.utils.get_device()\n\n# Set seed thus the results are more reproducible\ncfg.seed = seed\n\n# You should change this if you use different model\n# cfg.load_from = 'https://download.openmmlab.com/mmdetection/v2.0/swin/mask_rcnn_swin-t-p4-w7_fpn_1x_coco/mask_rcnn_swin-t-p4-w7_fpn_1x_coco_20210902_120937-9d6b7cfa.pth'\n# cfg.load_from = 'https://download.openmmlab.com/mmdetection/v2.0/mask_rcnn/mask_rcnn_r50_fpn_1x_coco/mask_rcnn_r50_fpn_1x_coco_20200205-d4b0c5d6.pth'\n# cfg.load_from = 'https://download.openmmlab.com/mmdetection/v2.0/cascade_rcnn/cascade_rcnn_r50_fpn_1x_coco/cascade_rcnn_r50_fpn_1x_coco_20200316-3dc56deb.pth'\ncfg.load_from = '/kaggle/input/epoch90/epoch_80.pth'\n# cfg.load_from = ''\nif not os.path.exists(job_folder):\n    os.makedirs(job_folder)\n\nprint(\"Job folder:\", job_folder)","metadata":{"execution":{"iopub.status.busy":"2022-04-29T02:15:53.454861Z","iopub.execute_input":"2022-04-29T02:15:53.45544Z","iopub.status.idle":"2022-04-29T02:15:53.463376Z","shell.execute_reply.started":"2022-04-29T02:15:53.455404Z","shell.execute_reply":"2022-04-29T02:15:53.462274Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"12 epochs !","metadata":{}},{"cell_type":"code","source":"for i in cfg.model.roi_head.bbox_head:\n    print(i)","metadata":{"execution":{"iopub.status.busy":"2022-04-29T02:15:53.465945Z","iopub.execute_input":"2022-04-29T02:15:53.466308Z","iopub.status.idle":"2022-04-29T02:15:53.476809Z","shell.execute_reply.started":"2022-04-29T02:15:53.46627Z","shell.execute_reply":"2022-04-29T02:15:53.475891Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Set the number of classes\nfor i in cfg.model.roi_head.bbox_head:\n    i.num_classes = 10\n\n# Set focal loss\n# for i in cfg.model.roi_head.bbox_head:\n#     i.num_classes = 10\n#     i.loss_cls = dict(\n#                 type='FocalLoss',\n#                 use_sigmoid=True,\n#                 gamma=2.0,\n#                 alpha=0.25,\n#                 loss_weight=1.0)\n\ncfg.gpu_ids = [0]\n\ncfg.runner.max_epochs = 10 # Epochs for the runner that runs the workflow \ncfg.total_epochs = 10\n\n# Learning rate of optimizers. The LR is divided by 8 since the config file is originally for 8 GPUs\ncfg.optimizer.lr = 0.02/8\n\n## Learning rate scheduler config used to register LrUpdater hook\ncfg.lr_config = dict(\n    policy='CosineAnnealing', # The policy of scheduler, also support CosineAnnealing, Cyclic, etc. Refer to details of supported LrUpdater from https://github.com/open-mmlab/mmcv/blob/master/mmcv/runner/hooks/lr_updater.py#L9.\n    by_epoch=False,\n    warmup='linear', # The warmup policy, also support `exp` and `constant`.\n    warmup_iters=1000, # The number of iterations for warmup\n    warmup_ratio=0.001, # The ratio of the starting learning rate used for warmup\n    min_lr=1e-07)\n\n# config to register logger hook\ncfg.log_config.interval = 40 # Interval to print the log\n\n# Config to set the checkpoint hook, Refer to https://github.com/open-mmlab/mmcv/blob/master/mmcv/runner/hooks/checkpoint.py for implementation.\ncfg.checkpoint_config.interval = 1 # The save interval is 1","metadata":{"execution":{"iopub.status.busy":"2022-04-29T02:15:53.478174Z","iopub.execute_input":"2022-04-29T02:15:53.478537Z","iopub.status.idle":"2022-04-29T02:15:53.486463Z","shell.execute_reply.started":"2022-04-29T02:15:53.4785Z","shell.execute_reply":"2022-04-29T02:15:53.485499Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.6em; font-weight: 300;\">Configure Datasets for Training and Evaluation</span>","metadata":{}},{"cell_type":"code","source":"cfg.dataset_type = 'CocoDataset' # Dataset type, this will be used to define the dataset\ncfg.classes = (\"Live knot\", \"Dead knot\", \"Knot with crack\", \"Crack\",\n           \"Resin\", \"Marrow\", \"Quartzity\", \"Knot missing\",\n           \"Blue stain\", \"Overgrown\")\n\ndata_images = '/kaggle/input/wood-surface-defects/IMAGE'\n\ncfg.data.train.img_prefix = data_images\ncfg.data.train.classes = cfg.classes\ncfg.data.train.ann_file = '/kaggle/working/new_anno/new_train.json'\ncfg.data.train.type='CocoDataset'\n\ncfg.data.val.img_prefix = data_images\ncfg.data.val.classes = cfg.classes\ncfg.data.val.ann_file = '/kaggle/working/new_anno/new_valid.json'\ncfg.data.val.type='CocoDataset'\n\ncfg.data.test.img_prefix = data_images\ncfg.data.test.classes = cfg.classes\ncfg.data.test.ann_file = '/kaggle/working/new_anno/new_test.json'\ncfg.data.test.type='CocoDataset'\n\ncfg.data.samples_per_gpu = 8  # Batch size of a single GPU used in training\ncfg.data.workers_per_gpu = 4  # Worker to pre-fetch data for each single GPU\n# cfg.data.train_dataloader = dict(samples_per_gpu = 8, workers_per_gpu = 4)\ncfg.data.val_dataloader = dict(samples_per_gpu=8, workers_per_gpu=4)\ncfg.data.test_dataloader = dict(samples_per_gpu=8, workers_per_gpu=4)","metadata":{"execution":{"iopub.status.busy":"2022-04-29T02:15:53.488558Z","iopub.execute_input":"2022-04-29T02:15:53.489189Z","iopub.status.idle":"2022-04-29T02:15:53.499422Z","shell.execute_reply.started":"2022-04-29T02:15:53.489152Z","shell.execute_reply":"2022-04-29T02:15:53.498653Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.6em; font-weight: 300;\">Setting Metric for Evaluation</span>","metadata":{}},{"cell_type":"code","source":"# The config to build the evaluation hook, refer to https://github.com/open-mmlab/mmdetection/blob/master/mmdet/core/evaluation/eval_hooks.py#L7 for more details.\ncfg.evaluation.metric = 'bbox' # Metrics used during evaluation\n\n# Set the epoch intervel to perform evaluation\ncfg.evaluation.interval = 1\n\ncfg.evaluation.save_best='bbox_mAP'","metadata":{"execution":{"iopub.status.busy":"2022-04-29T02:15:53.503252Z","iopub.execute_input":"2022-04-29T02:15:53.503713Z","iopub.status.idle":"2022-04-29T02:15:53.511444Z","shell.execute_reply.started":"2022-04-29T02:15:53.503661Z","shell.execute_reply":"2022-04-29T02:15:53.51065Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.6em; font-weight: 300;\">Prepare the Pre-processing & Augmentation Pipelines</span>","metadata":{}},{"cell_type":"markdown","source":"You can choose different data augmentation strategies","metadata":{}},{"cell_type":"code","source":"# albu_train_transforms = [\n#     dict(type='ShiftScaleRotate', shift_limit=0.0625,\n#          scale_limit=0.15, rotate_limit=15, p=0.4),\n#     dict(type='RandomBrightnessContrast', brightness_limit=0.2,\n#          contrast_limit=0.2, p=0.5),\n#     dict(type='IAAAffine', shear=(-10.0, 10.0), p=0.4),\n#     dict(type=\"Blur\", p=1.0, blur_limit=7),\n#     dict(type='CLAHE', p=0.5),\n#     dict(type='Equalize', mode='cv', p=0.4),\n#     dict(\n#         type=\"OneOf\",\n#         transforms=[\n#             dict(type=\"GaussianBlur\", p=1.0, blur_limit=7),\n#             dict(type=\"MedianBlur\", p=1.0, blur_limit=7),\n#         ],\n#         p=0.4,\n#     ),\n#     ]\n\n# cfg.train_pipeline = [\n#     dict(type='LoadImageFromFile'),\n#     dict(type='LoadAnnotations', with_bbox=True, with_mask=True),\n#     dict(type='Resize', img_scale=(1333, 800), keep_ratio=True),\n#     dict(type='RandomFlip', flip_ratio=0.5),\n#     dict(\n#         type='Albu',\n#         transforms=albu_train_transforms,\n#         bbox_params=dict(\n#         type='BboxParams',\n#         format='pascal_voc',\n#         label_fields=['gt_labels'],\n#         min_visibility=0.0,\n#         filter_lost_elements=True),\n#         keymap=dict(img='image', gt_bboxes='bboxes'),\n#         update_pad_shape=False,\n#         skip_img_without_anno=True),\n#     dict(\n#         type='Normalize',\n#         mean=[123.675, 116.28, 103.53],\n#         std=[58.395, 57.12, 57.375],\n#         to_rgb=True),\n#     dict(type='Pad', size_divisor=32),\n#     dict(type='DefaultFormatBundle'),\n#     dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels'])\n# ]\n","metadata":{"execution":{"iopub.status.busy":"2022-04-29T02:15:53.513237Z","iopub.execute_input":"2022-04-29T02:15:53.513893Z","iopub.status.idle":"2022-04-29T02:15:53.520072Z","shell.execute_reply.started":"2022-04-29T02:15:53.513856Z","shell.execute_reply":"2022-04-29T02:15:53.519233Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.6em; font-weight: 300;\">Weights & Biases Integration for Experiment Tracking and Logging</span>","metadata":{}},{"cell_type":"code","source":"cfg.log_config.hooks = [dict(type='TextLoggerHook'),\n                        dict(type='WandbLoggerHook',\n                             init_kwargs=dict(project=wnb_project_name,\n                                              name=f'exp-{model_name}-job{job}',\n                                              entity=wnb_username))\n                       ]","metadata":{"execution":{"iopub.status.busy":"2022-04-29T02:15:53.521556Z","iopub.execute_input":"2022-04-29T02:15:53.522381Z","iopub.status.idle":"2022-04-29T02:15:53.530535Z","shell.execute_reply.started":"2022-04-29T02:15:53.522343Z","shell.execute_reply":"2022-04-29T02:15:53.529767Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.6em; font-weight: 300;\">Save Config File</span>","metadata":{}},{"cell_type":"code","source":"cfg_path = f'{job_folder}/job{job}_{Path(baseline_cfg_path).name}'\nprint(cfg_path)\n\n# Save config file for inference later\ncfg.dump(cfg_path)\nprint(f'Config:\\n{cfg.pretty_text}')","metadata":{"execution":{"iopub.status.busy":"2022-04-29T02:15:53.532467Z","iopub.execute_input":"2022-04-29T02:15:53.533192Z","iopub.status.idle":"2022-04-29T02:15:54.702209Z","shell.execute_reply.started":"2022-04-29T02:15:53.533156Z","shell.execute_reply":"2022-04-29T02:15:54.700508Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<span style=\"color: #E45D00; font-family: Segoe UI; font-size: 1.9em; font-weight: 300;\">🚀 Build Dataset and Start Training</span>","metadata":{}},{"cell_type":"code","source":"model = build_detector(cfg.model,\n                       train_cfg=cfg.get('train_cfg'),\n                       test_cfg=cfg.get('valid_cfg'))\nmodel.init_weights()","metadata":{"scrolled":true,"execution":{"iopub.status.busy":"2022-04-29T02:15:54.703433Z","iopub.execute_input":"2022-04-29T02:15:54.703786Z","iopub.status.idle":"2022-04-29T02:16:01.741923Z","shell.execute_reply.started":"2022-04-29T02:15:54.703747Z","shell.execute_reply":"2022-04-29T02:16:01.741162Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"datasets = [build_dataset(cfg.data.train)]","metadata":{"execution":{"iopub.status.busy":"2022-04-29T02:16:01.743173Z","iopub.execute_input":"2022-04-29T02:16:01.743498Z","iopub.status.idle":"2022-04-29T02:16:02.127703Z","shell.execute_reply.started":"2022-04-29T02:16:01.743461Z","shell.execute_reply":"2022-04-29T02:16:02.126847Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"build_dataset(cfg.data.test)","metadata":{"execution":{"iopub.status.busy":"2022-04-29T02:16:02.128982Z","iopub.execute_input":"2022-04-29T02:16:02.129325Z","iopub.status.idle":"2022-04-29T02:16:02.295074Z","shell.execute_reply.started":"2022-04-29T02:16:02.129289Z","shell.execute_reply":"2022-04-29T02:16:02.294009Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"build_dataset(cfg.data.val)","metadata":{"execution":{"iopub.status.busy":"2022-04-29T02:16:02.296561Z","iopub.execute_input":"2022-04-29T02:16:02.296933Z","iopub.status.idle":"2022-04-29T02:16:02.86185Z","shell.execute_reply.started":"2022-04-29T02:16:02.296893Z","shell.execute_reply":"2022-04-29T02:16:02.861003Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_detector(model, datasets[0], cfg, distributed = False, validate = True)","metadata":{"scrolled":true,"execution":{"iopub.status.busy":"2022-04-29T02:16:02.865767Z","iopub.execute_input":"2022-04-29T02:16:02.867971Z","iopub.status.idle":"2022-04-29T11:10:07.625118Z","shell.execute_reply.started":"2022-04-29T02:16:02.867928Z","shell.execute_reply":"2022-04-29T11:10:07.624039Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<span style=\"color: #E45D00; font-family: Segoe UI; font-size: 1.9em; font-weight: 300;\">📰 Inference and Visualize Output</span>","metadata":{}},{"cell_type":"code","source":"# !ls ./job8_cascade_rcnn_r50_fpn_1x_focal_loss","metadata":{"execution":{"iopub.status.busy":"2022-04-16T11:33:48.005719Z","iopub.execute_input":"2022-04-16T11:33:48.006109Z","iopub.status.idle":"2022-04-16T11:33:48.787681Z","shell.execute_reply.started":"2022-04-16T11:33:48.006072Z","shell.execute_reply":"2022-04-16T11:33:48.786687Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import os\n# os.chdir('/kaggle/working')\n# print(os.getcwd())\n# print(os.listdir(\"/kaggle/working\"))\n# from IPython.display import FileLink\n# FileLink('./job8_cascade_rcnn_r50_fpn_1x_focal_loss/epoch_10.pth')","metadata":{"execution":{"iopub.status.busy":"2022-04-16T11:40:24.082221Z","iopub.execute_input":"2022-04-16T11:40:24.082588Z","iopub.status.idle":"2022-04-16T11:40:24.092339Z","shell.execute_reply.started":"2022-04-16T11:40:24.082555Z","shell.execute_reply":"2022-04-16T11:40:24.091355Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import numpy as np\n# from tqdm import tqdm\n# import json  # for dumping json serialized results\n# import zipfile  # for creating submission zip file\n# import pandas as pd\n# import cv2\n# import os\n# from matplotlib import pyplot as plt\n# from mmdet.apis import inference_detector, init_detector, show_result_pyplot","metadata":{"execution":{"iopub.status.busy":"2022-04-17T03:28:20.03782Z","iopub.execute_input":"2022-04-17T03:28:20.038172Z","iopub.status.idle":"2022-04-17T03:28:20.044145Z","shell.execute_reply.started":"2022-04-17T03:28:20.038139Z","shell.execute_reply":"2022-04-17T03:28:20.042276Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# checkpoint = \"/kaggle/input/epoch75/epoch_75.pth\"\n\n# model_test = init_detector(cfg, checkpoint, device = \"cuda:0\")","metadata":{"execution":{"iopub.status.busy":"2022-04-17T03:28:37.02308Z","iopub.execute_input":"2022-04-17T03:28:37.023413Z","iopub.status.idle":"2022-04-17T03:28:46.289608Z","shell.execute_reply.started":"2022-04-17T03:28:37.023381Z","shell.execute_reply":"2022-04-17T03:28:46.288646Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# class_name = [\"Live knot\", \"Dead knot\", \"Knot with crack\", \"Crack\",\\\n#                     \"Resin\", \"Marrow\", \"Quartzity\", \"Knot missing\",\\\n#                     \"Blue stain\", \"Overgrown\"]\n# class_name_CH = [\"活节\", \"死节\", \"节疤\", \"裂纹\", \"树脂\", \"骨髓\", \"石英\", \"漏节\", \"蓝变\", \"繁盛\"]","metadata":{"execution":{"iopub.status.busy":"2022-04-17T03:28:52.306532Z","iopub.execute_input":"2022-04-17T03:28:52.306886Z","iopub.status.idle":"2022-04-17T03:28:52.312918Z","shell.execute_reply.started":"2022-04-17T03:28:52.306856Z","shell.execute_reply":"2022-04-17T03:28:52.311999Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# def get_xyxy_from_pic(img_name, model, score_thresh = 0.7):\n#     xy_list = []\n#     categorys = []\n#     img_base = \"/kaggle/input/wood-surface-defects/IMAGE/\"\n#     img = img_base + img_name\n#     result = inference_detector(model_test, img)\n#     for i in range(10):\n#         if len(result[i]) != 0:\n#             for j in result[i]:\n#                 j = np.array(j).tolist()\n#                 if j[-1] >= score_thresh:\n#                     categorys.append(class_name[i])\n#                     x_min, y_min, x_max, y_max = j[0], j[1], j[2], j[3]\n#                     xy_list.append([int(x_min), int(y_min), int(x_max), int(y_max)])\n#     return categorys, xy_list","metadata":{"execution":{"iopub.status.busy":"2022-04-17T03:29:22.744134Z","iopub.execute_input":"2022-04-17T03:29:22.744467Z","iopub.status.idle":"2022-04-17T03:29:22.752083Z","shell.execute_reply.started":"2022-04-17T03:29:22.744437Z","shell.execute_reply":"2022-04-17T03:29:22.751188Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# def draw_rect(img, xy_list):\n#     for i, xy in enumerate(xy_list[1]):\n#         cv2.rectangle(img, (xy[0], xy[1]), (xy[2], xy[3]), (0, 0, 255), 2)\n#         cv2.putText(img, text = xy_list[0][i], org = (xy[0], xy[3] + 30 if xy[3] + 30 < 1024 else xy[1] - 20), fontFace = cv2.FONT_HERSHEY_SIMPLEX, fontScale = 1,color = (255,255,255), thickness = 2)","metadata":{"execution":{"iopub.status.busy":"2022-04-17T03:29:25.211871Z","iopub.execute_input":"2022-04-17T03:29:25.212197Z","iopub.status.idle":"2022-04-17T03:29:25.218444Z","shell.execute_reply.started":"2022-04-17T03:29:25.212166Z","shell.execute_reply":"2022-04-17T03:29:25.217605Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# dataset_path = \"/kaggle/input/wood-surface-defects/IMAGE\"\n# img_name = \"166600058.jpg\"\n# img = cv2.imread(os.path.join(dataset_path, img_name))","metadata":{"execution":{"iopub.status.busy":"2022-04-17T03:29:56.348402Z","iopub.execute_input":"2022-04-17T03:29:56.348765Z","iopub.status.idle":"2022-04-17T03:29:56.409254Z","shell.execute_reply.started":"2022-04-17T03:29:56.348733Z","shell.execute_reply":"2022-04-17T03:29:56.408453Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# xy_list = get_xyxy_from_pic(img_name, model_test)\n# plt.figure(figsize=(35, 13))\n# draw_rect(img, xy_list)\n# plt.imshow(img)\n# print(xy_list[0])","metadata":{"execution":{"iopub.status.busy":"2022-04-17T03:29:57.502016Z","iopub.execute_input":"2022-04-17T03:29:57.502337Z","iopub.status.idle":"2022-04-17T03:29:59.810386Z","shell.execute_reply.started":"2022-04-17T03:29:57.502307Z","shell.execute_reply":"2022-04-17T03:29:59.809523Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}