Skip to content

Commit

Permalink
Ultralytics Code Refactor https://ultralytics.com/actions (#2246)
Browse files Browse the repository at this point in the history
* Refactor code for speed and clarity

* Update export.py

* Update hubconf.py
  • Loading branch information
glenn-jocher committed Jul 8, 2024
1 parent 2af2504 commit b5b53ba
Show file tree
Hide file tree
Showing 6 changed files with 1,470 additions and 85 deletions.
138 changes: 133 additions & 5 deletions benchmarks.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,40 @@ def run(
pt_only=False, # test PyTorch only
hard_fail=False, # throw error on benchmark failure
):
"""Run YOLOv3 benchmarks on multiple export formats and validate performance metrics."""
"""
Run YOLOv3 benchmarks on multiple export formats and validate performance metrics.
Args:
weights (str | Path): Path to the weights file. Defaults to 'yolov5s.pt'.
imgsz (int): Inference image size in pixels. Defaults to 640.
batch_size (int): Batch size for inference. Defaults to 1.
data (str | Path): Path to the dataset configuration file (dataset.yaml). Defaults to 'data/coco128.yaml'.
device (str): Device to be used for inference, e.g., '0' or '0,1,2,3' for GPU or 'cpu' for CPU. Defaults to ''.
half (bool): Use FP16 half-precision for inference. Defaults to False.
test (bool): Test exports only without running benchmarks. Defaults to False.
pt_only (bool): Run benchmarks only for PyTorch format. Defaults to False.
hard_fail (bool): Raise an error if any benchmark test fails. Defaults to False.
Returns:
None
Notes:
This function iterates over multiple export formats, performs the export, and then validates the model's
performance using appropriate validation functions for detection and segmentation models. The results are logged,
and optionally, benchmarks can be configured to raise errors on failures using the `hard_fail` argument.
Examples:
```python
# Run benchmarks on the default 'yolov5s.pt' model with an image size of 640 pixels
run()
# Run benchmarks on a specific model with GPU and half-precision enabled
run(weights='custom_model.pt', device='0', half=True)
# Test only PyTorch export
run(pt_only=True)
```
"""
y, t = [], time.time()
device = select_device(device)
model_type = type(attempt_load(weights, fuse=False)) # DetectionModel, SegmentationModel, etc.
Expand Down Expand Up @@ -125,7 +158,45 @@ def test(
pt_only=False, # test PyTorch only
hard_fail=False, # throw error on benchmark failure
):
"""Run YOLOv3 export tests for various formats and log the results, including export success status."""
"""
Run YOLOv3 export tests for various formats and log the results, including export success status.
Args:
weights (str | Path): Path to the weights file. Defaults to ROOT / "yolov5s.pt".
imgsz (int): Inference size in pixels. Defaults to 640.
batch_size (int): Number of images per batch. Defaults to 1.
data (str | Path): Path to the dataset yaml file. Defaults to ROOT / "data/coco128.yaml".
device (str): Device for inference. Accepts cuda device (e.g., "0" or "0,1,2,3") or "cpu". Defaults to "".
half (bool): Use FP16 half-precision inference. Defaults to False.
test (bool): Run export tests only, no inference. Defaults to False.
pt_only (bool): Run tests on PyTorch format only. Defaults to False.
hard_fail (bool): Raise an error on benchmark failure. Defaults to False.
Returns:
pd.DataFrame: A DataFrame containing the export formats and their success status. (pd.DataFrame)
Examples:
```python
from ultralytics import test
results = test(
weights="path/to/yolov5s.pt",
imgsz=640,
batch_size=1,
data="path/to/coco128.yaml",
device="0",
half=False,
test=True,
pt_only=False,
hard_fail=True,
)
print(results)
```
Notes:
Ensure all required packages are installed as specified in the Ultralytics YOLOv3 documentation:
https://github.com/ultralytics/ultralytics
"""
y, t = [], time.time()
device = select_device(device)
for i, (name, f, suffix, gpu) in export.export_formats().iterrows(): # index, (name, file, suffix, gpu-capable)
Expand All @@ -151,8 +222,38 @@ def test(


def parse_opt():
"""Parses command line arguments for model inference configurations, including weights, image size, and device
options.
"""
Parses command line arguments for YOLOv3 inference and export configuration.
Args:
--weights (str): Path to the weights file. Default is 'ROOT / "yolov3-tiny.pt"'.
--imgsz | --img | --img-size (int): Inference image size in pixels. Default is 640.
--batch-size (int): Batch size for inference. Default is 1.
--data (str): Path to the dataset configuration file (dataset.yaml). Default is 'ROOT / "data/coco128.yaml"'.
--device (str): CUDA device identifier, e.g., '0' for single GPU, '0,1,2,3' for multiple GPUs, or 'cpu' for CPU
inference. Default is "".
--half (bool): If set, use FP16 half-precision inference. Default is False.
--test (bool): If set, only test exports without running inference. Default is False.
--pt-only (bool): If set, test only the PyTorch model without exporting to other formats. Default is False.
--hard-fail (str | bool): If set, raise an exception on benchmark failure. Can also be a string representing
the minimum metric floor for success. Default is False.
Returns:
argparse.Namespace: The parsed arguments as a namespace object.
Example:
To run inference on the YOLOv3-tiny model with a different image size:
```python
$ python benchmarks.py --weights yolov3-tiny.pt --imgsz 512 --device 0
```
Notes:
The `--hard-fail` argument can be a boolean or a string. If a string is provided, it should be an expression that
represents the minimum acceptable metric value, such as '0.29' for mAP (mean Average Precision).
Links:
https://github.com/ultralytics/ultralytics
"""
parser = argparse.ArgumentParser()
parser.add_argument("--weights", type=str, default=ROOT / "yolov3-tiny.pt", help="weights path")
Expand All @@ -171,7 +272,34 @@ def parse_opt():


def main(opt):
"""Executes tests or main pipeline on provided options, determining behavior based on `opt.test`."""
"""
Executes the export and benchmarking pipeline for YOLOv3 models, testing multiple export formats and validating
performance metrics.
Args:
opt (argparse.Namespace): Parsed command line arguments, including options for weights, image size, batch size,
dataset path, device, half-precision inference, test mode, PyTorch-only testing, and hard fail conditions.
Returns:
pd.DataFrame: A DataFrame containing benchmarking results with columns:
- Format: Name of the export format
- Size (MB): File size of the exported model
- mAP50-95: Mean Average Precision for the model
- Inference time (ms): Time taken for inference
Notes:
The function runs the main pipeline by exporting the YOLOv3 model to various formats and running benchmarks to
evaluate performance. If `opt.test` is set to True, it only tests the export process and logs the results.
Example:
Running the function from command line with required arguments:
```python
$ python benchmarks.py --weights yolov5s.pt --img 640
```
For more details, visit the Ultralytics YOLOv3 repository on [GitHub](https://github.com/ultralytics/ultralytics).
"""
test(**vars(opt)) if opt.test else run(**vars(opt))


Expand Down
139 changes: 136 additions & 3 deletions detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,60 @@ def run(
dnn=False, # use OpenCV DNN for ONNX inference
vid_stride=1, # video frame-rate stride
):
"""Performs YOLOv3 detection on various input sources including images, videos, streams, and YouTube URLs."""
"""
Performs YOLOv3 detection on various input sources including images, videos, streams, and YouTube URLs.
Args:
weights (str | Path): Path to the model weights file or a Triton URL (default: 'yolov5s.pt').
source (str | Path): Source of input data such as a file, directory, URL, glob pattern, or device identifier
(default: 'data/images').
data (str | Path): Path to the dataset YAML file (default: 'data/coco128.yaml').
imgsz (tuple[int, int]): Inference size as a tuple (height, width) (default: (640, 640)).
conf_thres (float): Confidence threshold for detection (default: 0.25).
iou_thres (float): Intersection Over Union (IOU) threshold for Non-Max Suppression (NMS) (default: 0.45).
max_det (int): Maximum number of detections per image (default: 1000).
device (str): CUDA device identifier, e.g., '0', '0,1,2,3', or 'cpu' (default: '').
view_img (bool): Whether to display results during inference (default: False).
save_txt (bool): Whether to save detection results to text files (default: False).
save_conf (bool): Whether to save detection confidences in the text labels (default: False).
save_crop (bool): Whether to save cropped detection boxes (default: False).
nosave (bool): Whether to prevent saving images or videos with detections (default: False).
classes (list[int] | None): List of class indices to filter, e.g., [0, 2, 3] (default: None).
agnostic_nms (bool): Whether to perform class-agnostic NMS (default: False).
augment (bool): Whether to apply augmented inference (default: False).
visualize (bool): Whether to visualize feature maps (default: False).
update (bool): Whether to update all models (default: False).
project (str | Path): Path to the project directory where results will be saved (default: 'runs/detect').
name (str): Name for the specific run within the project directory (default: 'exp').
exist_ok (bool): Whether to allow existing project/name directory without incrementing run index (default: False).
line_thickness (int): Thickness of bounding box lines in pixels (default: 3).
hide_labels (bool): Whether to hide labels in the results (default: False).
hide_conf (bool): Whether to hide confidences in the results (default: False).
half (bool): Whether to use half-precision (FP16) for inference (default: False).
dnn (bool): Whether to use OpenCV DNN for ONNX inference (default: False).
vid_stride (int): Stride for video frame rate (default: 1).
Returns:
None
Notes:
This function supports a variety of input sources such as image files, video files, directories, URL patterns,
webcam streams, and YouTube links. It also supports multiple model formats including PyTorch, ONNX, OpenVINO,
TensorRT, CoreML, TensorFlow, PaddlePaddle, and others. The results can be visualized in real-time or saved to
specified directories. Use command-line arguments to modify the behavior of the function.
Examples:
```python
# Run YOLOv3 inference on an image
run(weights='yolov5s.pt', source='data/images/bus.jpg')
# Run YOLOv3 inference on a video
run(weights='yolov5s.pt', source='data/videos/video.mp4', view_img=True)
# Run YOLOv3 inference on a webcam
run(weights='yolov5s.pt', source='0', view_img=True)
```
"""
source = str(source)
save_img = not nosave and not source.endswith(".txt") # save inference images
is_file = Path(source).suffix[1:] in (IMG_FORMATS + VID_FORMATS)
Expand Down Expand Up @@ -233,7 +286,41 @@ def run(


def parse_opt():
"""Parses and returns command-line options for model inference configurations."""
"""
Parses and returns command-line options for model inference configurations.
Args:
--weights (list[str]): Model path or triton URL. Default: `ROOT / "yolov3-tiny.pt"`.
--source (str): File/directory/URL/glob/screen/0(webcam) for input data. Default: `ROOT / "data/images"`.
--data (str): (Optional) Path to dataset.yaml. Default: `ROOT / "data/coco128.yaml"`.
--imgsz (list[int]): Inference size as height, width. Accepts multiple values. Default: `[640]`.
--conf-thres (float): Confidence threshold for predictions. Default: `0.25`.
--iou-thres (float): IoU threshold for Non-Maximum Suppression (NMS). Default: `0.45`.
--max-det (int): Maximum number of detections per image. Default: `1000`.
--device (str): CUDA device to run the model on, e.g., `0` or `0,1,2,3` or `cpu`. Default: `""`.
--view-img (bool): Display results on the screen. Default: `False`.
--save-txt (bool): Save results to text files. Default: `False`.
--save-conf (bool): Save confidence scores in text labels. Default: `False`.
--save-crop (bool): Save cropped prediction boxes. Default: `False`.
--nosave (bool): Do not save images/videos. Default: `False`.
--classes (list[int]): Filter results by class, e.g., `--classes 0` or `--classes 0 2 3`. Default: `None`.
--agnostic-nms (bool): Perform class-agnostic NMS. Default: `False`.
--augment (bool): Perform augmented inference. Default: `False`.
--visualize (bool): Visualize features. Default: `False`.
--update (bool): Update all models. Default: `False`.
--project (str): Directory to save results, saved as "project/name". Default: `ROOT / "runs/detect"`.
--name (str): Directory name for saving results, e.g., "exp" in "project/name". Default: `"exp"`.
--exist-ok (bool): Allow results to be saved in an existing directory without incrementing. Default: `False`.
--line-thickness (int): Thickness of bounding box lines (in pixels). Default: `3`.
--hide-labels (bool): Hide labels on detected objects. Default: `False`.
--hide-conf (bool): Hide confidence scores on labels. Default: `False`.
--half (bool): Use FP16 half-precision inference. Default: `False`.
--dnn (bool): Use OpenCV DNN backend for ONNX inference. Default: `False`.
--vid-stride (int): Frame-rate stride for video input. Default: `1`.
Returns:
argparse.Namespace: Parsed command-line arguments for inference configurations.
"""
parser = argparse.ArgumentParser()
parser.add_argument(
"--weights", nargs="+", type=str, default=ROOT / "yolov3-tiny.pt", help="model path or triton URL"
Expand Down Expand Up @@ -271,7 +358,53 @@ def parse_opt():


def main(opt):
"""Entry point for running the model; checks requirements and calls `run` with parsed options."""
"""
Entry point for running the model; checks requirements and calls `run` with parsed options.
Args:
opt (argparse.Namespace): Parsed command-line options, which include:
- weights (str | list of str): Path to the model weights or Triton server URL.
- source (str): Input source, can be a file, directory, URL, glob, screen, or webcam index.
- data (str): Path to the dataset configuration file (.yaml).
- imgsz (tuple of int): Inference image size as (height, width).
- conf_thres (float): Confidence threshold for detections.
- iou_thres (float): Intersection over Union (IoU) threshold for Non-Maximum Suppression (NMS).
- max_det (int): Maximum number of detections per image.
- device (str): Device to run inference on; options are CUDA device id(s) or 'cpu'
- view_img (bool): Flag to display inference results.
- save_txt (bool): Save detection results in .txt format.
- save_conf (bool): Save detection confidences in .txt labels.
- save_crop (bool): Save cropped bounding box predictions.
- nosave (bool): Do not save images/videos with detections.
- classes (list of int): Filter results by class, e.g., --class 0 2 3.
- agnostic_nms (bool): Use class-agnostic NMS.
- augment (bool): Enable augmented inference.
- visualize (bool): Visualize feature maps.
- update (bool): Update the model during inference.
- project (str): Directory to save results.
- name (str): Name for the results directory.
- exist_ok (bool): Allow existing project/name directories without incrementing.
- line_thickness (int): Thickness of bounding box lines.
- hide_labels (bool): Hide class labels on bounding boxes.
- hide_conf (bool): Hide confidence scores on bounding boxes.
- half (bool): Use FP16 half-precision inference.
- dnn (bool): Use OpenCV DNN backend for ONNX inference.
- vid_stride (int): Video frame-rate stride.
Returns:
None
Example:
```python
if __name__ == "__main__":
opt = parse_opt()
main(opt)
```
Notes:
Run this function as the entry point for using YOLOv3 for object detection on a variety of input sources such
as images, videos, directories, webcams, streams, etc. This function ensures all requirements are checked and
subsequently initiates the detection process by calling the `run` function with appropriate options.
"""
check_requirements(ROOT / "requirements.txt", exclude=("tensorboard", "thop"))
run(**vars(opt))

Expand Down
Loading

0 comments on commit b5b53ba

Please sign in to comment.