{"metadata":{"kernelspec":{"name":"python3","display_name":"Python 3","language":"python"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"accelerator":"GPU","colab":{"gpuType":"T4","provenance":[]},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":9837767,"sourceType":"datasetVersion","datasetId":6034775},{"sourceId":11021033,"sourceType":"datasetVersion","datasetId":6836747}],"dockerImageVersionId":30648,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Needs 24 GB of GPU memory for batch sizes of 1 ","metadata":{}},{"cell_type":"markdown","source":"## Install MMDetection\nInstalling mmdetection from wheel files.\n","metadata":{"id":"tJxJHruNLb7Y"}},{"cell_type":"code","source":"import IPython.display as display\n!pip install pycocotools==2.0.6\n!pip install torch==1.12.1 torchvision==0.13.1 --extra-index-url https://download.pytorch.org/whl/cu116\n!pip install mmcv==2.0.1 -f https://download.openmmlab.com/mmcv/dist/cu116/torch1.12/index.html\n!pip install openmim==0.3.9\n!pip install yapf==0.40.1\n!pip install --upgrade requests urllib3 charset_normalizer\ndisplay.clear_output()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-16T20:31:49.959283Z","iopub.execute_input":"2025-03-16T20:31:49.959632Z","iopub.status.idle":"2025-03-16T20:35:43.806003Z","shell.execute_reply.started":"2025-03-16T20:31:49.959603Z","shell.execute_reply":"2025-03-16T20:35:43.804827Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"## checking if everyting matches with the wheel files\n!git clone https://github.com/open-mmlab/mmdetection.git\n%cd mmdetection\n!pip install -v -e .\ndisplay.clear_output()","metadata":{"id":"Wi4LPmsR66sy","outputId":"8a4d76d8-a420-4ca8-b338-f80e323d30ba","trusted":true,"execution":{"iopub.status.busy":"2025-03-16T20:35:43.808278Z","iopub.execute_input":"2025-03-16T20:35:43.808940Z","iopub.status.idle":"2025-03-16T20:36:04.830713Z","shell.execute_reply.started":"2025-03-16T20:35:43.808897Z","shell.execute_reply":"2025-03-16T20:36:04.829683Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pwd","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-16T20:36:04.831922Z","iopub.execute_input":"2025-03-16T20:36:04.832187Z","iopub.status.idle":"2025-03-16T20:36:05.865362Z","shell.execute_reply.started":"2025-03-16T20:36:04.832163Z","shell.execute_reply":"2025-03-16T20:36:05.864218Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport os\nimport matplotlib.pyplot as plt\nfrom collections import Counter\nfrom decimal import Decimal\nimport csv\nimport random\nfrom PIL import Image\nimport cv2\nimport tqdm \nimport shutil\nimport json\nimport pickle","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-16T20:36:05.867547Z","iopub.execute_input":"2025-03-16T20:36:05.867918Z","iopub.status.idle":"2025-03-16T20:36:06.651073Z","shell.execute_reply.started":"2025-03-16T20:36:05.867886Z","shell.execute_reply":"2025-03-16T20:36:06.650352Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from mmengine.utils import get_git_hash\nfrom mmengine.utils.dl_utils import collect_env as collect_base_env\n\nimport mmdet\n\n\ndef collect_env():\n    \"\"\"Collect the information of the running environments.\"\"\"\n    env_info = collect_base_env()\n    env_info['MMDetection'] = f'{mmdet.__version__}+{get_git_hash()[:7]}'\n    return env_info\n\n\nif __name__ == '__main__':\n    for name, val in collect_env().items():\n        print(f'{name}: {val}')","metadata":{"id":"_YeUiqAoCaoV","outputId":"02f9cfe1-892a-43a5-cc9e-c1a4b21968ac","trusted":true,"execution":{"iopub.status.busy":"2025-03-16T20:36:06.652426Z","iopub.execute_input":"2025-03-16T20:36:06.652898Z","iopub.status.idle":"2025-03-16T20:36:08.980719Z","shell.execute_reply.started":"2025-03-16T20:36:06.652867Z","shell.execute_reply":"2025-03-16T20:36:08.979652Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!ls","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-16T20:36:08.981905Z","iopub.execute_input":"2025-03-16T20:36:08.982346Z","iopub.status.idle":"2025-03-16T20:36:10.025359Z","shell.execute_reply.started":"2025-03-16T20:36:08.982316Z","shell.execute_reply":"2025-03-16T20:36:10.024470Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Reorganize the dataset\nThe dataset should be in COCO format. The data and the annotation json are in the same root directory.","metadata":{}},{"cell_type":"code","source":"# Download the data and unzip it\n!mkdir data\n!mkdir data/crop-weed\n\n!cp -r /kaggle/input/crop-and-weed/dataset/images/train ./data/crop-weed/\n!cp -r /kaggle/input/crop-and-weed/dataset/images/val ./data/crop-weed/\n!cp  /kaggle/input/crop-weed-coco/annotations.json ./data/crop-weed/\n!cp  /kaggle/input/crop-weed-coco/val_annotations.json ./data/crop-weed/","metadata":{"id":"sbJhEsckU8UX","outputId":"8d52ad6d-e762-4179-f0fa-52c731267f86","trusted":true,"execution":{"iopub.status.busy":"2025-03-16T20:36:10.026718Z","iopub.execute_input":"2025-03-16T20:36:10.026991Z","iopub.status.idle":"2025-03-16T20:36:27.917798Z","shell.execute_reply.started":"2025-03-16T20:36:10.026964Z","shell.execute_reply":"2025-03-16T20:36:27.916429Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Prepare a config\n\nWe need a config to describe the model we are training. In this case we use the config of Co-DINO with Swin-L backbone. The config can be found in this repo: \nhttps://github.com/open-mmlab/mmdetection/blob/main/projects/CO-DETR/configs/codino/co_dino_5scale_swin_l_16xb1_16e_o365tococo.py\n\n\n","metadata":{"id":"yc9UDp1vU8UZ"}},{"cell_type":"code","source":"config_balloon = \"\"\"\n# Inherit and overwrite part of the config based on this config\n_base_ = './co_dino_5scale_r50_lsj_8xb2_1x_coco.py'\n\npretrained = 'https://github.com/SwinTransformer/storage/releases/download/v1.0.0/swin_large_patch4_window12_384_22k.pth'  # noqa\nload_from = 'https://download.openmmlab.com/mmdetection/v3.0/codetr/co_dino_5scale_swin_large_16e_o365tococo-614254c9.pth'  # noqa\n\ntrain_batch_size_per_gpu = 1\ntrain_num_workers = 1\n# root directory where the data folder and annotation json are found\ndata_root = 'data/crop-weed/'\nimage_size = (512, 512)\nmax_epochs = 10\nstage2_num_epochs = 1\nbase_lr = 0.00008\n\n# meta information about the number of classes and their annotation color in the inference output\nmetainfo = {\n    'classes': ('crop','weed'),\n    'palette': [\n    (220, 20, 60),  # Red\n    (255, 165, 0),  # Orange\n]\n}\n# model settings\n# number of classes must match the dataset's number of classes\nmodel = dict(\n    backbone=dict(\n        _delete_=True,\n        type='SwinTransformer',\n        pretrain_img_size=384,\n        embed_dims=192,\n        depths=[2, 2, 18, 2],\n        num_heads=[6, 12, 24, 48],\n        window_size=12,\n        mlp_ratio=4,\n        qkv_bias=True,\n        qk_scale=None,\n        drop_rate=0.,\n        attn_drop_rate=0.,\n        drop_path_rate=0.3,\n        patch_norm=True,\n        out_indices=(0, 1, 2, 3),\n        # Please only add indices that would be used\n        # in FPN, otherwise some parameter will not be used\n        with_cp=True,\n        convert_weights=True,\n        init_cfg=dict(type='Pretrained', checkpoint=pretrained)),\n    neck=dict(in_channels=[192, 384, 768, 1536]),\n    query_head=dict(\n        num_classes=2,dn_cfg=dict(box_noise_scale=0.4, group_cfg=dict(num_dn_queries=500)),\n        transformer=dict(encoder=dict(with_cp=6))))\n\ntrain_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(type='RandomFlip', prob=0.5),\n    dict(\n        type='RandomChoice',\n        transforms=[\n            [\n                dict(\n                    type='RandomChoiceResize',\n                    scales=[(128, 128), (256, 256)],\n                    keep_ratio=True)\n            ],\n            [\n                dict(\n                    type='RandomChoiceResize',\n                    # The radio of all image in train dataset < 7\n                    # follow the original implement\n                    scales=[(128,128), (256, 256)],\n                    keep_ratio=True),\n                dict(\n                    type='RandomCrop',\n                    crop_type='absolute_range',\n                    crop_size=(64, 64),\n                    allow_negative_crop=True),\n                dict(\n                    type='RandomChoiceResize',\n                    # The radio of all image in train dataset < 7\n                    # follow the original implement\n                    scales=[(128,128), (256, 256)],\n                    keep_ratio=True)\n            ]\n        ]),\n    dict(type='PackDetInputs')\n]\n\ntrain_dataloader = dict(\n    batch_size=train_batch_size_per_gpu,\n    num_workers=train_num_workers,\n    dataset=dict(\n        data_root=data_root,\n        metainfo=metainfo,\n        data_prefix=dict(img='train/'),\n        ann_file='annotations.json'))\nprint(train_dataloader)\n\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='Resize', scale=(512, 512), keep_ratio=True),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(\n        type='PackDetInputs',\n        meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'scale_factor'))\n]\n\n# This notebook uses the train data as validation. If you want to use a separate validation dataset, \n# you must put the paths for validation instead train in the val_dataloader\nval_dataloader = dict(\n    dataset=dict(\n        data_root=data_root,\n        metainfo=metainfo,\n        data_prefix=dict(img='val/'),\n        ann_file='val_annotations.json'))\ntest_dataloader = val_dataloader\n\n# Modify metric related settings\n# for validation set, change the train.json to the name of the validation json.\nval_evaluator = dict(ann_file=data_root + 'val_annotations.json')\ntest_evaluator = val_evaluator\n\noptim_wrapper = dict(type='OptimWrapper', optimizer=dict(lr=1e-4))\n\n\n\ntrain_cfg = dict(max_epochs=max_epochs)\n# out_dir is the directory where the checkpoints are saved\ndefault_hooks = dict(checkpoint=dict(type='CheckpointHook', save_best='auto',out_dir='../checkpoints_codetr_final'))\nparam_scheduler = [\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=max_epochs,\n        by_epoch=True,\n        milestones=[8],\n        gamma=0.1)\n]\n\n\"\"\"\n\nwith open('./projects/CO-DETR/configs/codino/co_dino_5scale_swin_l_16xb1_16e_o365tococo.py', 'w') as f:\n    f.write(config_balloon)","metadata":{"id":"XjTW6XydU8Ua","execution":{"iopub.status.busy":"2025-03-16T20:36:27.919807Z","iopub.execute_input":"2025-03-16T20:36:27.920481Z","iopub.status.idle":"2025-03-16T20:36:27.928522Z","shell.execute_reply.started":"2025-03-16T20:36:27.920442Z","shell.execute_reply":"2025-03-16T20:36:27.927731Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"config_balloon = \"\"\"\n# Inherit and overwrite part of the config based on this config\n_base_ = ['co_dino_5scale_r50_8xb2_1x_coco.py']\n\npretrained = 'https://github.com/SwinTransformer/storage/releases/download/v1.0.0/swin_large_patch4_window12_384_22k.pth'  # noqa\nload_from = 'https://download.openmmlab.com/mmdetection/v3.0/codetr/co_dino_5scale_swin_large_16e_o365tococo-614254c9.pth'  # noqa\n\ntrain_batch_size_per_gpu = 1\ntrain_num_workers = 1\n# root directory where the data folder and annotation json are found\ndata_root = 'data/crop-weed/'\nimage_size = (512, 512)\nmax_epochs = 20\nstage2_num_epochs = 1\nbase_lr = 0.00008\n\n# meta information about the number of classes and their annotation color in the inference output\nmetainfo = {\n    'classes': ('crop','weed'),\n    'palette': [\n    (220, 20, 60),  # Red\n    (0, 128, 0),    # Green\n]\n}\n# model settings\n# number of classes must match the dataset's number of classes\nmodel = dict(\n    backbone=dict(\n        _delete_=True,\n        type='SwinTransformer',\n        pretrain_img_size=384,\n        embed_dims=192,\n        depths=[2, 2, 18, 2],\n        num_heads=[6, 12, 24, 48],\n        window_size=12,\n        mlp_ratio=4,\n        qkv_bias=True,\n        qk_scale=None,\n        drop_rate=0.,\n        attn_drop_rate=0.,\n        drop_path_rate=0.3,\n        patch_norm=True,\n        out_indices=(0, 1, 2, 3),\n        # Please only add indices that would be used\n        # in FPN, otherwise some parameter will not be used\n        with_cp=True,\n        convert_weights=True,\n        init_cfg=dict(type='Pretrained', checkpoint=pretrained)),\n    neck=dict(in_channels=[192, 384, 768, 1536]),\n    query_head=dict(\n        num_classes=2,dn_cfg=dict(box_noise_scale=0.4, group_cfg=dict(num_dn_queries=500)),\n        transformer=dict(encoder=dict(with_cp=6))))\n\ntrain_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(type='RandomFlip', prob=0.5),\n    dict(\n        type='RandomChoice',\n        transforms=[\n            [\n                dict(\n                    type='RandomChoiceResize',\n                    scales=[ (512, 512), (256,256)],\n                    keep_ratio=True)\n            ],\n            [\n                dict(\n                    type='RandomChoiceResize',\n                    # The radio of all image in train dataset < 7\n                    # follow the original implement\n                    scales=[ (512, 512), (256,256)],\n                    keep_ratio=True),\n                dict(\n                    type='RandomCrop',\n                    crop_type='absolute_range',\n                    crop_size=(128, 128),\n                    allow_negative_crop=True),\n                dict(\n                    type='RandomChoiceResize',\n                    scales=[ (512, 512), (256,256)],\n                    keep_ratio=True)\n            ]\n        ]),\n    dict(type='PackDetInputs')\n]\n\ntrain_dataloader = dict(\n    batch_size=train_batch_size_per_gpu,\n    num_workers=train_num_workers,\n    dataset=dict(\n        data_root=data_root,\n        metainfo=metainfo,\n        data_prefix=dict(img='train/'),\n        ann_file='annotations.json',\n        pipeline=train_pipeline))\n\n#print(train_dataloader)\n\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='Resize', scale=(512, 512), keep_ratio=True),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(\n        type='PackDetInputs',\n        meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'scale_factor'))\n]\n\n# This notebook uses the train data as validation. If you want to use a separate validation dataset, \n# you must put the paths for validation instead train in the val_dataloader\nval_dataloader = dict(\n    dataset=dict(\n        data_root=data_root,\n        metainfo=metainfo,\n        data_prefix=dict(img='val/'),\n        ann_file='val_annotations.json',\n        pipeline=test_pipeline))\ntest_dataloader = val_dataloader\n\n# Modify metric related settings\n# for validation set, change the train.json to the name of the validation json.\nval_evaluator = dict(ann_file=data_root + 'val_annotations.json')\ntest_evaluator = val_evaluator\n\noptim_wrapper = dict(optimizer=dict(lr=1e-4))\n\n\ntrain_cfg = dict(max_epochs=max_epochs)\n# out_dir is the directory where the checkpoints are saved\ndefault_hooks = dict(checkpoint=dict(type='CheckpointHook', save_best='auto',out_dir='../checkpoints_codetr_final'))\nparam_scheduler = [\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=max_epochs,\n        by_epoch=True,\n        milestones=[8],\n        gamma=0.1)\n]\n\n\"\"\"\n\nwith open('./projects/CO-DETR/configs/codino/co_dino_5scale_swin_l_16xb1_16e_o365tococo.py', 'w') as f:\n    f.write(config_balloon)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-16T21:25:47.653557Z","iopub.execute_input":"2025-03-16T21:25:47.654330Z","iopub.status.idle":"2025-03-16T21:25:47.662156Z","shell.execute_reply.started":"2025-03-16T21:25:47.654293Z","shell.execute_reply":"2025-03-16T21:25:47.661225Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pwd","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-16T20:36:27.929914Z","iopub.execute_input":"2025-03-16T20:36:27.930501Z","iopub.status.idle":"2025-03-16T20:36:28.965047Z","shell.execute_reply.started":"2025-03-16T20:36:27.930469Z","shell.execute_reply":"2025-03-16T20:36:28.963871Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!python tools/train.py ./projects/CO-DETR/configs/codino/co_dino_5scale_swin_l_16xb1_16e_o365tococo.py","metadata":{"id":"5LNm7LxwZG2w","outputId":"5c77544f-ef00-4640-bdac-6719f5cf3b8d","scrolled":true,"execution":{"iopub.status.busy":"2025-03-16T21:25:52.021346Z","iopub.execute_input":"2025-03-16T21:25:52.021704Z","iopub.status.idle":"2025-03-16T21:27:41.619828Z","shell.execute_reply.started":"2025-03-16T21:25:52.021677Z","shell.execute_reply":"2025-03-16T21:27:41.618633Z"},"trusted":true},"outputs":[],"execution_count":null}]}