forked from PhotonVision/photonvision
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5 from laviRZ/filtering
Add filtering and other QoL features. Notebooks, colab, unpacking by version
- Loading branch information
Showing
9 changed files
with
289 additions
and
157 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# YOLOv5 Training and Conversion to RKNN - Team 5990 TRIGON\n<img src =\"https://avatars.githubusercontent.com/u/45858082?s=280&v=4\" />","metadata":{}},{"cell_type":"code","source":"%cd {root_path}\nimport os\nroot_path = os.getcwd()\n\n!git clone https://github.com/airockchip/yolov5/\n%cd yolov5\n!git checkout d25a07534c14f44296f9444bab2aa5c601cdaaab\n\n!pip install -qr requirements.txt","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Downloading the dataset\nInput your Roboflow API key below. It can be obtained [here](https://app.roboflow.com/settings/api).\nYou can use your own dataset, the rest of the notebook should work with any number of classes, as long as the project is of \"object detection\" type.","metadata":{}},{"cell_type":"code","source":"!mkdir {root_path}/datasets\n%cd {root_path}/datasets\n\n!pip install roboflow -q\n\nfrom roboflow import Roboflow\nrf = Roboflow(api_key=\"api_key\")\nproject = rf.workspace(\"trigon5990\").project(\"conesandcubes\")\ndataset = project.version(6).download(\"yolov5\")\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport re\nfrom IPython.core.magic import register_line_cell_magic\n\n@register_line_cell_magic\ndef writetemplate(line, cell):\n with open(line, 'w') as f:\n f.write(cell.format(**globals()))\n print(\"Wrote successfully to \" + line)\n\n@register_line_cell_magic\ndef replaceAllInFile(line, cell):\n filename = line.strip()\n replacements = eval(cell) # Assuming input is a valid Python expression\n with open(filename, 'r') as f:\n file_content = f.read()\n for replaced, with_this in replacements:\n file_content = re.sub(replaced, with_this, file_content)\n with open(filename, 'w') as f:\n f.write(file_content)\n print(f\"Replaced successfully in {filename}\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%cat {dataset.location}/data.yaml","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### This is needed because the default format of the directories in roboflow datasets is kinda broken:","metadata":{}},{"cell_type":"code","source":"%%replaceAllInFile {dataset.location}/data.yaml\n\n[\n ('test: ..', 'test: ' + dataset.location),\n ('train: ', 'train: ' + root_path + '/datasets/'),\n ('val: ', 'val: ' + root_path + '/datasets/'),\n]\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# define number of classes based on YAML\nimport yaml\nwith open(dataset.location + \"/data.yaml\", 'r') as stream:\n num_classes = str(yaml.safe_load(stream)['nc'])\nprint(f\"num_classes: {num_classes}\")\n%cd {root_path}/yolov5","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Training\nYou can adjust the following settings:\n- model: one of [yolov5n, yolov5s, yolov5m, yolov5l, yolov5x]\n- image_size: The input size of the images fed to the model. Should be a multiple of 32.\n- batch: Number of samples per epoch. You should set this to the highest number possible without the training taking too much memory (it would crash if that happens, which is ok, just lower the number and try again)\n- epochs: How many iterations to train for\n- patience: After how many epochs without improvement to stop the training","metadata":{}},{"cell_type":"code","source":"%cd {root_path}/yolov5\n!wandb disabled\nmodel = \"yolov5n\"\nimage_size = 640\n!python train.py --img {image_size} --batch 256 --epochs 700 --patience 50 --data {dataset.location}/data.yaml --cfg {model}.yaml --weights '' --device 0 --cache {\"--single-cls\" if num_classes == '1' else \"\"}","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"latest_modified_time = 0\nlatest = None\n\nfor foldername, subfolders, filenames in os.walk(root_path):\n for filename in filenames:\n if filename == \"best.pt\":\n file_path = os.path.join(foldername, filename)\n modified_time = os.path.getmtime(file_path)\n if modified_time > latest_modified_time:\n latest_modified_time = modified_time\n latest = file_path\nprint(latest, latest_modified_time)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Exporting to ONNX\nThis is an intermediate step between the PyTorch model and the RKNN model.","metadata":{}},{"cell_type":"code","source":"%cd {root_path}/yolov5\n!python export.py --rknpu --weight {latest}","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ex_path = '.'.join(latest.split('.')[:-1] + ['onnx'])\nprint(ex_path)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Installing RKNN Toolkit 2","metadata":{}},{"cell_type":"code","source":"!wget https://github.com/rockchip-linux/rknn-toolkit2/raw/2c2d03def0c0908c86985b8190e973976ecec74c/rknn-toolkit2/packages/rknn_toolkit2-1.6.0+81f21f4d-cp310-cp310-linux_x86_64.whl\n!pip install ./rknn_toolkit2-1.6.0+81f21f4d-cp310-cp310-linux_x86_64.whl","metadata":{"scrolled":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%cd {root_path}\n!git clone https://github.com/airockchip/rknn_model_zoo/\n%cd rknn_model_zoo\n!git checkout eaa94d6f57ca553d493bf3bd7399a070452d2774\n%cd examples/yolov5/python","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%writefile imgs.txt\nimgs/1.jpg\nimgs/2.jpg\nimgs/3.jpg\nimgs/4.jpg\nimgs/5.jpg\nimgs/6.jpg\nimgs/7.jpg\nimgs/8.jpg\nimgs/9.jpg\nimgs/10.jpg\nimgs/11.jpg\nimgs/12.jpg\nimgs/13.jpg\nimgs/14.jpg\nimgs/15.jpg\nimgs/16.jpg\nimgs/17.jpg\nimgs/18.jpg\nimgs/19.jpg\nimgs/20.jpg\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport shutil\nimport random\nimport glob\n\ndef copy_and_rename_images(source_folder, destination_folder, n):\n if not os.path.exists(source_folder):\n print(f\"Source folder '{source_folder}' does not exist.\")\n return\n if not os.path.exists(destination_folder):\n os.makedirs(destination_folder)\n image_files = glob.glob(os.path.join(source_folder, '*.jpg'))\n selected_images = random.sample(image_files, min(n, len(image_files)))\n for i, image_path in enumerate(selected_images, start=1):\n destination_path = os.path.join(destination_folder, f'{i}.jpg')\n shutil.copy(image_path, destination_path)\n print(f\"{min(n, len(image_files))} random images copied from '{source_folder}' to '{destination_folder}' and renamed.\")\ncopy_and_rename_images(dataset.location+\"/test/images\" , \"imgs\", 20)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%replaceAllInFile {root_path}/rknn_model_zoo/examples/yolov5/python/convert.py\n[('../../../datasets/COCO/coco_subset_20.txt', 'imgs.txt')]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Quantization\nHere you choose whether to perform quantization, which makes the model lighter and faster, by converting all 32/16 bit floates in the model into 8 bit ints, which costs performance.","metadata":{}},{"cell_type":"code","source":"to_quantize = True # @param {type: \"boolean\"}","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Exporting to RKNN - Final step🎉","metadata":{}},{"cell_type":"code","source":"%cd {root_path}/rknn_model_zoo/examples/yolov5/python\nquant_code = \"i8\" if to_quantize else \"fp\"\noutput_model = f\"{root_path}/{dataset.name}-{model}-{image_size}-{quant_code}.rknn\"\n!python convert.py {ex_path} rk3588 {quant_code} {output_model}","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# YOLOv8 Training and Conversion to RKNN - Team 5990 TRIGON\n<img src =\"https://avatars.githubusercontent.com/u/45858082?s=280&v=4\" />","metadata":{}},{"cell_type":"code","source":"%cd {root_path}\nimport os\nroot_path = os.getcwd()\n\n!git clone https://github.com/airockchip/ultralytics_yolov8 ultralytics\n%cd ultralytics\n!git checkout 5b7ddd8f821c8f6edb389aa30cfbc88bd903867b\n\n!pip install -e .\n\nfrom IPython import display\ndisplay.clear_output()\n\nimport ultralytics\nultralytics.checks()","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Downloading the dataset\nInput your Roboflow API key below. It can be obtained [here](https://app.roboflow.com/settings/api).\nYou can use your own dataset, the rest of the notebook should work with any number of classes, as long as the project is of \"object detection\" type.","metadata":{}},{"cell_type":"code","source":"!mkdir {root_path}/datasets\n%cd {root_path}/datasets\n\n!pip install roboflow -q\n\nfrom roboflow import Roboflow\nrf = Roboflow(api_key=\"api_key\")\nproject = rf.workspace(\"trigon5990\").project(\"conesandcubes\")\ndataset = project.version(6).download(\"yolov8\")\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport re\nfrom IPython.core.magic import register_line_cell_magic\n\n@register_line_cell_magic\ndef writetemplate(line, cell):\n with open(line, 'w') as f:\n f.write(cell.format(**globals()))\n print(\"Wrote successfully to \" + line)\n\n@register_line_cell_magic\ndef replaceAllInFile(line, cell):\n filename = line.strip()\n replacements = eval(cell) # Assuming input is a valid Python expression\n with open(filename, 'r') as f:\n file_content = f.read()\n for replaced, with_this in replacements:\n file_content = re.sub(replaced, with_this, file_content)\n with open(filename, 'w') as f:\n f.write(file_content)\n print(f\"Replaced successfully in {filename}\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%cat {dataset.location}/data.yaml","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### This is needed because the default format of the directories in roboflow datasets is kinda broken:","metadata":{}},{"cell_type":"code","source":"%%replaceAllInFile {dataset.location}/data.yaml\n\n[\n ('test: ..', 'test: ' + dataset.location),\n ('train: ', 'train: ' + root_path + '/datasets/'),\n ('val: ', 'val: ' + root_path + '/datasets/'),\n]\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# define number of classes based on YAML\nimport yaml\nwith open(dataset.location + \"/data.yaml\", 'r') as stream:\n num_classes = str(yaml.safe_load(stream)['nc'])\nprint(f\"num_classes: {num_classes}\")\n%cd {root_path}/ultralytics","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%writetemplate custom_yolov8.yaml\n# Ultralytics YOLO 🚀, AGPL-3.0 license\n# YOLOv8 object detection model with P3-P5 outputs. For Usage examples see https://docs.ultralytics.com/tasks/detect\n\n# Parameters\nnc: {num_classes} # number of classes\nscales: # model compound scaling constants, i.e. 'model=yolov8n.yaml' will call yolov8.yaml with scale 'n'\n # [depth, width, max_channels]\n n: [0.33, 0.25, 1024] # YOLOv8n summary: 225 layers, 3157200 parameters, 3157184 gradients, 8.9 GFLOPs\n s: [0.33, 0.50, 1024] # YOLOv8s summary: 225 layers, 11166560 parameters, 11166544 gradients, 28.8 GFLOPs\n m: [0.67, 0.75, 768] # YOLOv8m summary: 295 layers, 25902640 parameters, 25902624 gradients, 79.3 GFLOPs\n l: [1.00, 1.00, 512] # YOLOv8l summary: 365 layers, 43691520 parameters, 43691504 gradients, 165.7 GFLOPs\n x: [1.00, 1.25, 512] # YOLOv8x summary: 365 layers, 68229648 parameters, 68229632 gradients, 258.5 GFLOPs\nactivation: nn.ReLU()\n# YOLOv8.0n backbone\nbackbone:\n # [from, repeats, module, args]\n - [-1, 1, Conv, [64, 3, 2]] # 0-P1/2\n - [-1, 1, Conv, [128, 3, 2]] # 1-P2/4\n - [-1, 3, C2f, [128, True]]\n - [-1, 1, Conv, [256, 3, 2]] # 3-P3/8\n - [-1, 6, C2f, [256, True]]\n - [-1, 1, Conv, [512, 3, 2]] # 5-P4/16\n - [-1, 6, C2f, [512, True]]\n - [-1, 1, Conv, [1024, 3, 2]] # 7-P5/32\n - [-1, 3, C2f, [1024, True]]\n - [-1, 1, SPPF, [1024, 5]] # 9\n\n# YOLOv8.0n head\nhead:\n - [-1, 1, nn.Upsample, [None, 2, 'nearest']]\n - [[-1, 6], 1, Concat, [1]] # cat backbone P4\n - [-1, 3, C2f, [512]] # 12\n\n - [-1, 1, nn.Upsample, [None, 2, 'nearest']]\n - [[-1, 4], 1, Concat, [1]] # cat backbone P3\n - [-1, 3, C2f, [256]] # 15 (P3/8-small)\n\n - [-1, 1, Conv, [256, 3, 2]]\n - [[-1, 12], 1, Concat, [1]] # cat head P4\n - [-1, 3, C2f, [512]] # 18 (P4/16-medium)\n\n - [-1, 1, Conv, [512, 3, 2]]\n - [[-1, 9], 1, Concat, [1]] # cat head P5\n - [-1, 3, C2f, [1024]] # 21 (P5/32-large)\n\n - [[15, 18, 21], 1, Detect, [nc]] # Detect(P3, P4, P5)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Training\nYou can adjust the following settings:\n- model: one of [yolov8n, yolov8s, yolov8m, yolov8l, yolov8x]\n- image_size: The input size of the images fed to the model. Should be a multiple of 32.\n- batch: Number of samples per epoch. You should set this to the highest number possible without the training taking too much memory (it would crash if that happens, which is ok, just lower the number and try again)\n- epochs: How many iterations to train for\n- patience: After how many epochs without improvement to stop the training","metadata":{}},{"cell_type":"code","source":"%cd {root_path}/ultralytics\nmodel = \"yolov8n\"\nimage_size = 640\n!yolo batch=192 epochs=700 patience=50 device=0 cache=ram task=detect mode=train model=./custom_{model}.yaml data={dataset.location}/data.yaml imgsz={image_size} plots=False pretrained=False single_cls={num_classes == '1'}","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"latest_modified_time = 0\nlatest = None\n\nfor foldername, subfolders, filenames in os.walk(root_path):\n for filename in filenames:\n if filename == \"best.pt\":\n file_path = os.path.join(foldername, filename)\n modified_time = os.path.getmtime(file_path)\n if modified_time > latest_modified_time:\n latest_modified_time = modified_time\n latest = file_path\nprint(latest)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Exporting to ONNX\nThis is an intermediate step between the PyTorch model and the RKNN model.","metadata":{}},{"cell_type":"code","source":"%cd {root_path}/ultralytics\n!yolo mode=export format=rknn model={latest}","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ex_path = '.'.join(latest.split('.')[:-1]) + '.onnx'\nprint(ex_path)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Installing RKNN Toolkit 2","metadata":{}},{"cell_type":"code","source":"!wget https://github.com/rockchip-linux/rknn-toolkit2/raw/2c2d03def0c0908c86985b8190e973976ecec74c/rknn-toolkit2/packages/rknn_toolkit2-1.6.0+81f21f4d-cp310-cp310-linux_x86_64.whl\n!pip install ./rknn_toolkit2-1.6.0+81f21f4d-cp310-cp310-linux_x86_64.whl","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%cd {root_path}\n!git clone https://github.com/airockchip/rknn_model_zoo/\n%cd rknn_model_zoo\n!git checkout eaa94d6f57ca553d493bf3bd7399a070452d2774\n%cd examples/yolov8/python","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%writefile imgs.txt\nimgs/1.jpg\nimgs/2.jpg\nimgs/3.jpg\nimgs/4.jpg\nimgs/5.jpg\nimgs/6.jpg\nimgs/7.jpg\nimgs/8.jpg\nimgs/9.jpg\nimgs/10.jpg\nimgs/11.jpg\nimgs/12.jpg\nimgs/13.jpg\nimgs/14.jpg\nimgs/15.jpg\nimgs/16.jpg\nimgs/17.jpg\nimgs/18.jpg\nimgs/19.jpg\nimgs/20.jpg","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport shutil\nimport random\nimport glob\n\ndef copy_and_rename_images(source_folder, destination_folder, n):\n if not os.path.exists(source_folder):\n print(f\"Source folder '{source_folder}' does not exist.\")\n return\n if not os.path.exists(destination_folder):\n os.makedirs(destination_folder)\n image_files = glob.glob(os.path.join(source_folder, '*.jpg'))\n selected_images = random.sample(image_files, min(n, len(image_files)))\n for i, image_path in enumerate(selected_images, start=1):\n destination_path = os.path.join(destination_folder, f'{i}.jpg')\n shutil.copy(image_path, destination_path)\n print(f\"{min(n, len(image_files))} random images copied from '{source_folder}' to '{destination_folder}' and renamed.\")\ncopy_and_rename_images(dataset.location+\"/test/images\" , \"imgs\", 20)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%replaceAllInFile {root_path}/rknn_model_zoo/examples/yolov8/python/convert.py\n[\n ('../../../datasets/COCO/coco_subset_20.txt', 'imgs.txt'),\n]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Quantization\nHere you choose whether to perform quantization, which makes the model lighter and faster, by converting all 32/16 bit floates in the model into 8 bit ints, which costs performance.","metadata":{}},{"cell_type":"code","source":"to_quantize = True # @param {type: \"boolean\"}","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Exporting to RKNN - Final step🎉","metadata":{}},{"cell_type":"code","source":"%cd {root_path}/rknn_model_zoo/examples/yolov8/python\nquant_code = \"i8\" if to_quantize else \"fp\"\noutput_model = f\"{root_path}/{dataset.name}-{model}-{image_size}-{quant_code}.rknn\"\n!python convert.py {ex_path} rk3588 {quant_code} {output_model}","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]} |
Oops, something went wrong.