├── ultralytics ├── nn │ └── __init__.py ├── yolo │ ├── engine │ │ └── __init__.py │ ├── data │ │ ├── dataloaders │ │ │ └── __init__.py │ │ ├── __init__.py │ │ ├── scripts │ │ │ ├── get_coco128.sh │ │ │ ├── download_weights.sh │ │ │ ├── get_imagenet.sh │ │ │ └── get_coco.sh │ │ ├── dataset_wrappers.py │ │ ├── datasets │ │ │ ├── GlobalWheat2020.yaml │ │ │ ├── coco128.yaml │ │ │ ├── coco128-seg.yaml │ │ │ ├── SKU-110K.yaml │ │ │ ├── Argoverse.yaml │ │ │ ├── coco.yaml │ │ │ ├── VisDrone.yaml │ │ │ ├── VOC.yaml │ │ │ └── xView.yaml │ │ └── build.py │ ├── __init__.py │ ├── utils │ │ ├── callbacks │ │ │ ├── __init__.py │ │ │ ├── tensorboard.py │ │ │ ├── comet.py │ │ │ ├── clearml.py │ │ │ ├── hub.py │ │ │ └── base.py │ │ ├── loss.py │ │ ├── dist.py │ │ ├── autobatch.py │ │ └── files.py │ ├── v8 │ │ ├── detect │ │ │ ├── __init__.py │ │ │ └── predict.py │ │ ├── segment │ │ │ ├── __init__.py │ │ │ └── predict.py │ │ ├── classify │ │ │ ├── __init__.py │ │ │ ├── val.py │ │ │ └── predict.py │ │ └── __init__.py │ ├── configs │ │ ├── __init__.py │ │ └── hydra_patch.py │ └── cli.py ├── assets │ ├── bus.jpg │ └── zidane.jpg ├── __init__.py ├── models │ ├── v8 │ │ ├── cls │ │ │ ├── yolov8l-cls.yaml │ │ │ ├── yolov8m-cls.yaml │ │ │ ├── yolov8n-cls.yaml │ │ │ ├── yolov8s-cls.yaml │ │ │ └── yolov8x-cls.yaml │ │ ├── yolov8l.yaml │ │ ├── yolov8m.yaml │ │ ├── yolov8x.yaml │ │ ├── yolov8n.yaml │ │ ├── yolov8s.yaml │ │ ├── seg │ │ │ ├── yolov8l-seg.yaml │ │ │ ├── yolov8m-seg.yaml │ │ │ ├── yolov8x-seg.yaml │ │ │ ├── yolov8n-seg.yaml │ │ │ └── yolov8s-seg.yaml │ │ └── yolov8x6.yaml │ ├── v3 │ │ ├── yolov3-tiny.yaml │ │ ├── yolov3.yaml │ │ └── yolov3-spp.yaml │ ├── v5 │ │ ├── yolov5l.yaml │ │ ├── yolov5m.yaml │ │ ├── yolov5n.yaml │ │ ├── yolov5x.yaml │ │ └── yolov5s.yaml │ └── README.md └── hub │ ├── auth.py │ ├── session.py │ └── __init__.py ├── docs ├── CNAME ├── reference │ ├── model.md │ ├── exporter.md │ ├── base_val.md │ ├── base_pred.md │ ├── base_trainer.md │ ├── nn.md │ └── ops.md ├── assets │ └── favicon.ico ├── stylesheets │ └── style.css ├── app.md ├── engine.md ├── quickstart.md ├── cli.md ├── README.md ├── python.md ├── hub.md └── index.md ├── MANIFEST.in ├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── question.yml │ ├── feature-request.yml │ └── bug-report.yml ├── translate-readme.yml ├── dependabot.yml └── workflows │ ├── cla.yml │ ├── docker.yaml │ └── ci.yaml ├── CITATION.cff ├── requirements.txt ├── .pre-commit-config.yaml ├── docker ├── Dockerfile-cpu ├── Dockerfile-arm64 └── Dockerfile ├── setup.cfg ├── tests ├── test_cli.py ├── test_python.py └── test_engine.py ├── setup.py ├── mkdocs.yml └── .gitignore /ultralytics/nn/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | docs.ultralytics.com -------------------------------------------------------------------------------- /ultralytics/yolo/engine/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ultralytics/yolo/data/dataloaders/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/reference/model.md: -------------------------------------------------------------------------------- 1 | ::: ultralytics.yolo.engine.model 2 | -------------------------------------------------------------------------------- /ultralytics/yolo/__init__.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | from . import v8 4 | -------------------------------------------------------------------------------- /docs/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CashRussell/ultralytics/HEAD/docs/assets/favicon.ico -------------------------------------------------------------------------------- /docs/reference/exporter.md: -------------------------------------------------------------------------------- 1 | ### Exporter API Reference 2 | 3 | :::ultralytics.yolo.engine.exporter.Exporter -------------------------------------------------------------------------------- /ultralytics/assets/bus.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CashRussell/ultralytics/HEAD/ultralytics/assets/bus.jpg -------------------------------------------------------------------------------- /ultralytics/yolo/utils/callbacks/__init__.py: -------------------------------------------------------------------------------- 1 | from .base import add_integration_callbacks, default_callbacks 2 | -------------------------------------------------------------------------------- /ultralytics/assets/zidane.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CashRussell/ultralytics/HEAD/ultralytics/assets/zidane.jpg -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include *.md 2 | include requirements.txt 3 | include LICENSE 4 | include setup.py 5 | recursive-include ultralytics *.yaml 6 | -------------------------------------------------------------------------------- /ultralytics/yolo/v8/detect/__init__.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | from .predict import DetectionPredictor, predict 4 | from .train import DetectionTrainer, train 5 | from .val import DetectionValidator, val 6 | -------------------------------------------------------------------------------- /ultralytics/yolo/v8/segment/__init__.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | from .predict import SegmentationPredictor, predict 4 | from .train import SegmentationTrainer, train 5 | from .val import SegmentationValidator, val 6 | -------------------------------------------------------------------------------- /ultralytics/yolo/data/__init__.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | from .base import BaseDataset 4 | from .build import build_classification_dataloader, build_dataloader 5 | from .dataset import ClassificationDataset, SemanticDataset, YOLODataset 6 | from .dataset_wrappers import MixAndRectDataset 7 | -------------------------------------------------------------------------------- /docs/reference/base_val.md: -------------------------------------------------------------------------------- 1 | All task Validators are inherited from `BaseValidator` class that contains the model validation routine boilerplate. You 2 | can override any function of these Trainers to suit your needs. 3 | 4 | --- 5 | 6 | ### BaseValidator API Reference 7 | 8 | :::ultralytics.yolo.engine.validator.BaseValidator -------------------------------------------------------------------------------- /docs/reference/base_pred.md: -------------------------------------------------------------------------------- 1 | All task Predictors are inherited from `BasePredictors` class that contains the model validation routine boilerplate. 2 | You can override any function of these Trainers to suit your needs. 3 | 4 | --- 5 | 6 | ### BasePredictor API Reference 7 | 8 | :::ultralytics.yolo.engine.predictor.BasePredictor -------------------------------------------------------------------------------- /ultralytics/yolo/v8/classify/__init__.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | from ultralytics.yolo.v8.classify.predict import ClassificationPredictor, predict 4 | from ultralytics.yolo.v8.classify.train import ClassificationTrainer, train 5 | from ultralytics.yolo.v8.classify.val import ClassificationValidator, val 6 | -------------------------------------------------------------------------------- /docs/reference/base_trainer.md: -------------------------------------------------------------------------------- 1 | All task Trainers are inherited from `BaseTrainer` class that contains the model training and optimzation routine 2 | boilerplate. You can override any function of these Trainers to suit your needs. 3 | 4 | --- 5 | 6 | ### BaseTrainer API Reference 7 | 8 | :::ultralytics.yolo.engine.trainer.BaseTrainer -------------------------------------------------------------------------------- /ultralytics/__init__.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | __version__ = "8.0.5" 4 | 5 | from ultralytics.hub import checks 6 | from ultralytics.yolo.engine.model import YOLO 7 | from ultralytics.yolo.utils import ops 8 | 9 | __all__ = ["__version__", "YOLO", "hub", "checks"] # allow simpler import 10 | -------------------------------------------------------------------------------- /ultralytics/yolo/v8/__init__.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | from pathlib import Path 4 | 5 | from ultralytics.yolo.v8 import classify, detect, segment 6 | 7 | ROOT = Path(__file__).parents[0] # yolov8 ROOT 8 | 9 | __all__ = ["classify", "segment", "detect"] 10 | 11 | from ultralytics.yolo.configs import hydra_patch # noqa (patch hydra cli) 12 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | contact_links: 3 | - name: 📄Docs 4 | url: https://docs.ultralytics.com/ 5 | about: Full Ultralytics YOLOv8 Documentation 6 | - name: 💬 Forum 7 | url: https://community.ultralytics.com/ 8 | about: Ask on Ultralytics Community Forum 9 | - name: Stack Overflow 10 | url: https://stackoverflow.com/search?q=YOLOv8 11 | about: Ask on Stack Overflow with 'YOLOv8' tag 12 | -------------------------------------------------------------------------------- /docs/reference/nn.md: -------------------------------------------------------------------------------- 1 | # nn Module 2 | 3 | Ultralytics nn module contains 3 main components: 4 | 5 | 1. **AutoBackend**: A module that can run inference on all popular model formats 6 | 2. **BaseModel**: `BaseModel` class defines the operations supported by tasks like Detection and Segmentation 7 | 3. **modules**: Optimized and reusable neural network blocks built on PyTorch. 8 | 9 | ## AutoBackend 10 | 11 | :::ultralytics.nn.autobackend.AutoBackend 12 | 13 | ## BaseModel 14 | 15 | :::ultralytics.nn.tasks.BaseModel 16 | 17 | ## Modules 18 | 19 | TODO -------------------------------------------------------------------------------- /ultralytics/yolo/data/scripts/get_coco128.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Ultralytics YOLO 🚀, GPL-3.0 license 3 | # Download COCO128 dataset https://www.kaggle.com/ultralytics/coco128 (first 128 images from COCO train2017) 4 | # Example usage: bash data/scripts/get_coco128.sh 5 | # parent 6 | # ├── yolov5 7 | # └── datasets 8 | # └── coco128 ← downloads here 9 | 10 | # Download/unzip images and labels 11 | d='../datasets' # unzip directory 12 | url=https://github.com/ultralytics/yolov5/releases/download/v1.0/ 13 | f='coco128.zip' # or 'coco128-segments.zip', 68 MB 14 | echo 'Downloading' $url$f ' ...' 15 | curl -L $url$f -o $f -# && unzip -q $f -d $d && rm $f & 16 | 17 | wait # finish background tasks 18 | -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | preferred-citation: 3 | type: software 4 | message: If you use this software, please cite it as below. 5 | authors: 6 | - family-names: Jocher 7 | given-names: Glenn 8 | orcid: "https://orcid.org/0000-0001-5950-6979" 9 | - family-names: Chaurasia 10 | given-names: Ayush 11 | orcid: "https://orcid.org/0000-0002-7603-6750" 12 | - family-names: Qiu 13 | given-names: Jing 14 | orcid: "https://orcid.org/0000-0003-3783-7069" 15 | title: "YOLO by Ultralytics" 16 | version: 8.0.0 17 | # doi: 10.5281/zenodo.3908559 # TODO 18 | date-released: 2023-1-10 19 | license: GPL-3.0 20 | url: "https://github.com/ultralytics/ultralytics" 21 | -------------------------------------------------------------------------------- /ultralytics/yolo/data/scripts/download_weights.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Ultralytics YOLO 🚀, GPL-3.0 license 3 | # Download latest models from https://github.com/ultralytics/yolov5/releases 4 | # Example usage: bash data/scripts/download_weights.sh 5 | # parent 6 | # └── yolov5 7 | # ├── yolov5s.pt ← downloads here 8 | # ├── yolov5m.pt 9 | # └── ... 10 | 11 | python - < 15 | Please search the [issues](https://github.com/ultralytics/ultralytics/issues) and [discussions](https://github.com/ultralytics/ultralytics/discussions) to see if a similar question already exists. 16 | options: 17 | - label: > 18 | I have searched the YOLOv8 [issues](https://github.com/ultralytics/ultralytics/issues) and [discussions](https://github.com/ultralytics/ultralytics/discussions) and found no similar questions. 19 | required: true 20 | 21 | - type: textarea 22 | attributes: 23 | label: Question 24 | description: What is your question? 25 | placeholder: | 26 | 💡 ProTip! Include as much information as possible (screenshots, logs, tracebacks etc.) to receive the most helpful response. 27 | validations: 28 | required: true 29 | 30 | - type: textarea 31 | attributes: 32 | label: Additional 33 | description: Anything else you would like to share? 34 | -------------------------------------------------------------------------------- /ultralytics/yolo/configs/__init__.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | from pathlib import Path 4 | from typing import Dict, Union 5 | 6 | from omegaconf import DictConfig, OmegaConf 7 | 8 | from ultralytics.yolo.configs.hydra_patch import check_config_mismatch 9 | 10 | 11 | def get_config(config: Union[str, DictConfig], overrides: Union[str, Dict] = None): 12 | """ 13 | Load and merge configuration data from a file or dictionary. 14 | 15 | Args: 16 | config (Union[str, DictConfig]): Configuration data in the form of a file name or a DictConfig object. 17 | overrides (Union[str, Dict], optional): Overrides in the form of a file name or a dictionary. Default is None. 18 | 19 | Returns: 20 | OmegaConf.Namespace: Training arguments namespace. 21 | """ 22 | if overrides is None: 23 | overrides = {} 24 | if isinstance(config, (str, Path)): 25 | config = OmegaConf.load(config) 26 | elif isinstance(config, Dict): 27 | config = OmegaConf.create(config) 28 | # override 29 | if isinstance(overrides, str): 30 | overrides = OmegaConf.load(overrides) 31 | elif isinstance(overrides, Dict): 32 | overrides = OmegaConf.create(overrides) 33 | 34 | check_config_mismatch(dict(overrides).keys(), dict(config).keys()) 35 | 36 | return OmegaConf.merge(config, overrides) 37 | -------------------------------------------------------------------------------- /ultralytics/models/v8/yolov8l.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 1.00 # scales module repeats 6 | width_multiple: 1.00 # scales convolution channels 7 | 8 | # YOLOv8.0l backbone 9 | backbone: 10 | # [from, repeats, module, args] 11 | - [-1, 1, Conv, [64, 3, 2]] # 0-P1/2 12 | - [-1, 1, Conv, [128, 3, 2]] # 1-P2/4 13 | - [-1, 3, C2f, [128, True]] 14 | - [-1, 1, Conv, [256, 3, 2]] # 3-P3/8 15 | - [-1, 6, C2f, [256, True]] 16 | - [-1, 1, Conv, [512, 3, 2]] # 5-P4/16 17 | - [-1, 6, C2f, [512, True]] 18 | - [-1, 1, Conv, [512, 3, 2]] # 7-P5/32 19 | - [-1, 3, C2f, [512, True]] 20 | - [-1, 1, SPPF, [512, 5]] # 9 21 | 22 | # YOLOv8.0l head 23 | head: 24 | - [-1, 1, nn.Upsample, [None, 2, 'nearest']] 25 | - [[-1, 6], 1, Concat, [1]] # cat backbone P4 26 | - [-1, 3, C2f, [512]] # 13 27 | 28 | - [-1, 1, nn.Upsample, [None, 2, 'nearest']] 29 | - [[-1, 4], 1, Concat, [1]] # cat backbone P3 30 | - [-1, 3, C2f, [256]] # 17 (P3/8-small) 31 | 32 | - [-1, 1, Conv, [256, 3, 2]] 33 | - [[-1, 12], 1, Concat, [1]] # cat head P4 34 | - [-1, 3, C2f, [512]] # 20 (P4/16-medium) 35 | 36 | - [-1, 1, Conv, [512, 3, 2]] 37 | - [[-1, 9], 1, Concat, [1]] # cat head P5 38 | - [-1, 3, C2f, [512]] # 23 (P5/32-large) 39 | 40 | - [[15, 18, 21], 1, Detect, [nc]] # Detect(P3, P4, P5) 41 | -------------------------------------------------------------------------------- /ultralytics/models/v8/yolov8m.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 0.67 # scales module repeats 6 | width_multiple: 0.75 # scales convolution channels 7 | 8 | # YOLOv8.0m backbone 9 | backbone: 10 | # [from, repeats, module, args] 11 | - [-1, 1, Conv, [64, 3, 2]] # 0-P1/2 12 | - [-1, 1, Conv, [128, 3, 2]] # 1-P2/4 13 | - [-1, 3, C2f, [128, True]] 14 | - [-1, 1, Conv, [256, 3, 2]] # 3-P3/8 15 | - [-1, 6, C2f, [256, True]] 16 | - [-1, 1, Conv, [512, 3, 2]] # 5-P4/16 17 | - [-1, 6, C2f, [512, True]] 18 | - [-1, 1, Conv, [768, 3, 2]] # 7-P5/32 19 | - [-1, 3, C2f, [768, True]] 20 | - [-1, 1, SPPF, [768, 5]] # 9 21 | 22 | # YOLOv8.0m head 23 | head: 24 | - [-1, 1, nn.Upsample, [None, 2, 'nearest']] 25 | - [[-1, 6], 1, Concat, [1]] # cat backbone P4 26 | - [-1, 3, C2f, [512]] # 13 27 | 28 | - [-1, 1, nn.Upsample, [None, 2, 'nearest']] 29 | - [[-1, 4], 1, Concat, [1]] # cat backbone P3 30 | - [-1, 3, C2f, [256]] # 17 (P3/8-small) 31 | 32 | - [-1, 1, Conv, [256, 3, 2]] 33 | - [[-1, 12], 1, Concat, [1]] # cat head P4 34 | - [-1, 3, C2f, [512]] # 20 (P4/16-medium) 35 | 36 | - [-1, 1, Conv, [512, 3, 2]] 37 | - [[-1, 9], 1, Concat, [1]] # cat head P5 38 | - [-1, 3, C2f, [768]] # 23 (P5/32-large) 39 | 40 | - [[15, 18, 21], 1, Detect, [nc]] # Detect(P3, P4, P5) 41 | -------------------------------------------------------------------------------- /ultralytics/models/v8/yolov8x.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 1.00 # scales module repeats 6 | width_multiple: 1.25 # scales convolution channels 7 | 8 | # YOLOv8.0x backbone 9 | backbone: 10 | # [from, repeats, module, args] 11 | - [-1, 1, Conv, [64, 3, 2]] # 0-P1/2 12 | - [-1, 1, Conv, [128, 3, 2]] # 1-P2/4 13 | - [-1, 3, C2f, [128, True]] 14 | - [-1, 1, Conv, [256, 3, 2]] # 3-P3/8 15 | - [-1, 6, C2f, [256, True]] 16 | - [-1, 1, Conv, [512, 3, 2]] # 5-P4/16 17 | - [-1, 6, C2f, [512, True]] 18 | - [-1, 1, Conv, [512, 3, 2]] # 7-P5/32 19 | - [-1, 3, C2f, [512, True]] 20 | - [-1, 1, SPPF, [512, 5]] # 9 21 | 22 | # YOLOv8.0x head 23 | head: 24 | - [-1, 1, nn.Upsample, [None, 2, 'nearest']] 25 | - [[-1, 6], 1, Concat, [1]] # cat backbone P4 26 | - [-1, 3, C2f, [512]] # 13 27 | 28 | - [-1, 1, nn.Upsample, [None, 2, 'nearest']] 29 | - [[-1, 4], 1, Concat, [1]] # cat backbone P3 30 | - [-1, 3, C2f, [256]] # 17 (P3/8-small) 31 | 32 | - [-1, 1, Conv, [256, 3, 2]] 33 | - [[-1, 12], 1, Concat, [1]] # cat head P4 34 | - [-1, 3, C2f, [512]] # 20 (P4/16-medium) 35 | 36 | - [-1, 1, Conv, [512, 3, 2]] 37 | - [[-1, 9], 1, Concat, [1]] # cat head P5 38 | - [-1, 3, C2f, [512]] # 23 (P5/32-large) 39 | 40 | - [[15, 18, 21], 1, Detect, [nc]] # Detect(P3, P4, P5) 41 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # Ultralytics requirements 2 | # Usage: pip install -r requirements.txt 3 | 4 | # Base ---------------------------------------- 5 | hydra-core>=1.2.0 6 | matplotlib>=3.2.2 7 | numpy>=1.18.5 8 | opencv-python>=4.1.1 9 | Pillow>=7.1.2 10 | PyYAML>=5.3.1 11 | requests>=2.23.0 12 | scipy>=1.4.1 13 | torch>=1.7.0 14 | torchvision>=0.8.1 15 | tqdm>=4.64.0 16 | 17 | # Logging ------------------------------------- 18 | tensorboard>=2.4.1 19 | # clearml 20 | # comet 21 | 22 | # Plotting ------------------------------------ 23 | pandas>=1.1.4 24 | seaborn>=0.11.0 25 | 26 | # Export -------------------------------------- 27 | # coremltools>=6.0 # CoreML export 28 | # onnx>=1.12.0 # ONNX export 29 | # onnx-simplifier>=0.4.1 # ONNX simplifier 30 | # nvidia-pyindex # TensorRT export 31 | # nvidia-tensorrt # TensorRT export 32 | # scikit-learn==0.19.2 # CoreML quantization 33 | # tensorflow>=2.4.1 # TF exports (-cpu, -aarch64, -macos) 34 | # tensorflowjs>=3.9.0 # TF.js export 35 | # openvino-dev # OpenVINO export 36 | 37 | # Extras -------------------------------------- 38 | ipython # interactive notebook 39 | psutil # system utilization 40 | thop>=0.1.1 # FLOPs computation 41 | # albumentations>=1.0.3 42 | # pycocotools>=2.0.6 # COCO mAP 43 | # roboflow 44 | 45 | # HUB ----------------------------------------- 46 | GitPython>=3.1.24 47 | -------------------------------------------------------------------------------- /ultralytics/models/v8/yolov8n.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 0.33 # scales module repeats 6 | width_multiple: 0.25 # scales convolution channels 7 | 8 | # YOLOv8.0n backbone 9 | backbone: 10 | # [from, repeats, module, args] 11 | - [-1, 1, Conv, [64, 3, 2]] # 0-P1/2 12 | - [-1, 1, Conv, [128, 3, 2]] # 1-P2/4 13 | - [-1, 3, C2f, [128, True]] 14 | - [-1, 1, Conv, [256, 3, 2]] # 3-P3/8 15 | - [-1, 6, C2f, [256, True]] 16 | - [-1, 1, Conv, [512, 3, 2]] # 5-P4/16 17 | - [-1, 6, C2f, [512, True]] 18 | - [-1, 1, Conv, [1024, 3, 2]] # 7-P5/32 19 | - [-1, 3, C2f, [1024, True]] 20 | - [-1, 1, SPPF, [1024, 5]] # 9 21 | 22 | # YOLOv8.0n head 23 | head: 24 | - [-1, 1, nn.Upsample, [None, 2, 'nearest']] 25 | - [[-1, 6], 1, Concat, [1]] # cat backbone P4 26 | - [-1, 3, C2f, [512]] # 13 27 | 28 | - [-1, 1, nn.Upsample, [None, 2, 'nearest']] 29 | - [[-1, 4], 1, Concat, [1]] # cat backbone P3 30 | - [-1, 3, C2f, [256]] # 17 (P3/8-small) 31 | 32 | - [-1, 1, Conv, [256, 3, 2]] 33 | - [[-1, 12], 1, Concat, [1]] # cat head P4 34 | - [-1, 3, C2f, [512]] # 20 (P4/16-medium) 35 | 36 | - [-1, 1, Conv, [512, 3, 2]] 37 | - [[-1, 9], 1, Concat, [1]] # cat head P5 38 | - [-1, 3, C2f, [1024]] # 23 (P5/32-large) 39 | 40 | - [[15, 18, 21], 1, Detect, [nc]] # Detect(P3, P4, P5) 41 | -------------------------------------------------------------------------------- /ultralytics/models/v8/yolov8s.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 0.33 # scales module repeats 6 | width_multiple: 0.50 # scales convolution channels 7 | 8 | # YOLOv8.0s backbone 9 | backbone: 10 | # [from, repeats, module, args] 11 | - [-1, 1, Conv, [64, 3, 2]] # 0-P1/2 12 | - [-1, 1, Conv, [128, 3, 2]] # 1-P2/4 13 | - [-1, 3, C2f, [128, True]] 14 | - [-1, 1, Conv, [256, 3, 2]] # 3-P3/8 15 | - [-1, 6, C2f, [256, True]] 16 | - [-1, 1, Conv, [512, 3, 2]] # 5-P4/16 17 | - [-1, 6, C2f, [512, True]] 18 | - [-1, 1, Conv, [1024, 3, 2]] # 7-P5/32 19 | - [-1, 3, C2f, [1024, True]] 20 | - [-1, 1, SPPF, [1024, 5]] # 9 21 | 22 | # YOLOv8.0s head 23 | head: 24 | - [-1, 1, nn.Upsample, [None, 2, 'nearest']] 25 | - [[-1, 6], 1, Concat, [1]] # cat backbone P4 26 | - [-1, 3, C2f, [512]] # 13 27 | 28 | - [-1, 1, nn.Upsample, [None, 2, 'nearest']] 29 | - [[-1, 4], 1, Concat, [1]] # cat backbone P3 30 | - [-1, 3, C2f, [256]] # 17 (P3/8-small) 31 | 32 | - [-1, 1, Conv, [256, 3, 2]] 33 | - [[-1, 12], 1, Concat, [1]] # cat head P4 34 | - [-1, 3, C2f, [512]] # 20 (P4/16-medium) 35 | 36 | - [-1, 1, Conv, [512, 3, 2]] 37 | - [[-1, 9], 1, Concat, [1]] # cat head P5 38 | - [-1, 3, C2f, [1024]] # 23 (P5/32-large) 39 | 40 | - [[15, 18, 21], 1, Detect, [nc]] # Detect(P3, P4, P5) 41 | -------------------------------------------------------------------------------- /ultralytics/models/v8/seg/yolov8l-seg.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 1.00 # scales module repeats 6 | width_multiple: 1.00 # scales convolution channels 7 | 8 | # YOLOv8.0l backbone 9 | backbone: 10 | # [from, repeats, module, args] 11 | - [-1, 1, Conv, [64, 3, 2]] # 0-P1/2 12 | - [-1, 1, Conv, [128, 3, 2]] # 1-P2/4 13 | - [-1, 3, C2f, [128, True]] 14 | - [-1, 1, Conv, [256, 3, 2]] # 3-P3/8 15 | - [-1, 6, C2f, [256, True]] 16 | - [-1, 1, Conv, [512, 3, 2]] # 5-P4/16 17 | - [-1, 6, C2f, [512, True]] 18 | - [-1, 1, Conv, [512, 3, 2]] # 7-P5/32 19 | - [-1, 3, C2f, [512, True]] 20 | - [-1, 1, SPPF, [512, 5]] # 9 21 | 22 | # YOLOv8.0l head 23 | head: 24 | - [-1, 1, nn.Upsample, [None, 2, 'nearest']] 25 | - [[-1, 6], 1, Concat, [1]] # cat backbone P4 26 | - [-1, 3, C2f, [512]] # 13 27 | 28 | - [-1, 1, nn.Upsample, [None, 2, 'nearest']] 29 | - [[-1, 4], 1, Concat, [1]] # cat backbone P3 30 | - [-1, 3, C2f, [256]] # 17 (P3/8-small) 31 | 32 | - [-1, 1, Conv, [256, 3, 2]] 33 | - [[-1, 12], 1, Concat, [1]] # cat head P4 34 | - [-1, 3, C2f, [512]] # 20 (P4/16-medium) 35 | 36 | - [-1, 1, Conv, [512, 3, 2]] 37 | - [[-1, 9], 1, Concat, [1]] # cat head P5 38 | - [-1, 3, C2f, [512]] # 23 (P5/32-large) 39 | 40 | - [[15, 18, 21], 1, Segment, [nc, 32, 256]] # Detect(P3, P4, P5) 41 | -------------------------------------------------------------------------------- /ultralytics/models/v8/seg/yolov8m-seg.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 0.67 # scales module repeats 6 | width_multiple: 0.75 # scales convolution channels 7 | 8 | # YOLOv8.0m backbone 9 | backbone: 10 | # [from, repeats, module, args] 11 | - [-1, 1, Conv, [64, 3, 2]] # 0-P1/2 12 | - [-1, 1, Conv, [128, 3, 2]] # 1-P2/4 13 | - [-1, 3, C2f, [128, True]] 14 | - [-1, 1, Conv, [256, 3, 2]] # 3-P3/8 15 | - [-1, 6, C2f, [256, True]] 16 | - [-1, 1, Conv, [512, 3, 2]] # 5-P4/16 17 | - [-1, 6, C2f, [512, True]] 18 | - [-1, 1, Conv, [768, 3, 2]] # 7-P5/32 19 | - [-1, 3, C2f, [768, True]] 20 | - [-1, 1, SPPF, [768, 5]] # 9 21 | 22 | # YOLOv8.0m head 23 | head: 24 | - [-1, 1, nn.Upsample, [None, 2, 'nearest']] 25 | - [[-1, 6], 1, Concat, [1]] # cat backbone P4 26 | - [-1, 3, C2f, [512]] # 13 27 | 28 | - [-1, 1, nn.Upsample, [None, 2, 'nearest']] 29 | - [[-1, 4], 1, Concat, [1]] # cat backbone P3 30 | - [-1, 3, C2f, [256]] # 17 (P3/8-small) 31 | 32 | - [-1, 1, Conv, [256, 3, 2]] 33 | - [[-1, 12], 1, Concat, [1]] # cat head P4 34 | - [-1, 3, C2f, [512]] # 20 (P4/16-medium) 35 | 36 | - [-1, 1, Conv, [512, 3, 2]] 37 | - [[-1, 9], 1, Concat, [1]] # cat head P5 38 | - [-1, 3, C2f, [768]] # 23 (P5/32-large) 39 | 40 | - [[15, 18, 21], 1, Segment, [nc, 32, 256]] # Detect(P3, P4, P5) 41 | -------------------------------------------------------------------------------- /ultralytics/models/v8/seg/yolov8x-seg.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 1.00 # scales module repeats 6 | width_multiple: 1.25 # scales convolution channels 7 | 8 | # YOLOv8.0x backbone 9 | backbone: 10 | # [from, repeats, module, args] 11 | - [-1, 1, Conv, [64, 3, 2]] # 0-P1/2 12 | - [-1, 1, Conv, [128, 3, 2]] # 1-P2/4 13 | - [-1, 3, C2f, [128, True]] 14 | - [-1, 1, Conv, [256, 3, 2]] # 3-P3/8 15 | - [-1, 6, C2f, [256, True]] 16 | - [-1, 1, Conv, [512, 3, 2]] # 5-P4/16 17 | - [-1, 6, C2f, [512, True]] 18 | - [-1, 1, Conv, [512, 3, 2]] # 7-P5/32 19 | - [-1, 3, C2f, [512, True]] 20 | - [-1, 1, SPPF, [512, 5]] # 9 21 | 22 | # YOLOv8.0x head 23 | head: 24 | - [-1, 1, nn.Upsample, [None, 2, 'nearest']] 25 | - [[-1, 6], 1, Concat, [1]] # cat backbone P4 26 | - [-1, 3, C2f, [512]] # 13 27 | 28 | - [-1, 1, nn.Upsample, [None, 2, 'nearest']] 29 | - [[-1, 4], 1, Concat, [1]] # cat backbone P3 30 | - [-1, 3, C2f, [256]] # 17 (P3/8-small) 31 | 32 | - [-1, 1, Conv, [256, 3, 2]] 33 | - [[-1, 12], 1, Concat, [1]] # cat head P4 34 | - [-1, 3, C2f, [512]] # 20 (P4/16-medium) 35 | 36 | - [-1, 1, Conv, [512, 3, 2]] 37 | - [[-1, 9], 1, Concat, [1]] # cat head P5 38 | - [-1, 3, C2f, [512]] # 23 (P5/32-large) 39 | 40 | - [[15, 18, 21], 1, Segment, [nc, 32, 256]] # Detect(P3, P4, P5) 41 | -------------------------------------------------------------------------------- /ultralytics/models/v8/seg/yolov8n-seg.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 0.33 # scales module repeats 6 | width_multiple: 0.25 # scales convolution channels 7 | 8 | # YOLOv8.0n backbone 9 | backbone: 10 | # [from, repeats, module, args] 11 | - [-1, 1, Conv, [64, 3, 2]] # 0-P1/2 12 | - [-1, 1, Conv, [128, 3, 2]] # 1-P2/4 13 | - [-1, 3, C2f, [128, True]] 14 | - [-1, 1, Conv, [256, 3, 2]] # 3-P3/8 15 | - [-1, 6, C2f, [256, True]] 16 | - [-1, 1, Conv, [512, 3, 2]] # 5-P4/16 17 | - [-1, 6, C2f, [512, True]] 18 | - [-1, 1, Conv, [1024, 3, 2]] # 7-P5/32 19 | - [-1, 3, C2f, [1024, True]] 20 | - [-1, 1, SPPF, [1024, 5]] # 9 21 | 22 | # YOLOv8.0n head 23 | head: 24 | - [-1, 1, nn.Upsample, [None, 2, 'nearest']] 25 | - [[-1, 6], 1, Concat, [1]] # cat backbone P4 26 | - [-1, 3, C2f, [512]] # 13 27 | 28 | - [-1, 1, nn.Upsample, [None, 2, 'nearest']] 29 | - [[-1, 4], 1, Concat, [1]] # cat backbone P3 30 | - [-1, 3, C2f, [256]] # 17 (P3/8-small) 31 | 32 | - [-1, 1, Conv, [256, 3, 2]] 33 | - [[-1, 12], 1, Concat, [1]] # cat head P4 34 | - [-1, 3, C2f, [512]] # 20 (P4/16-medium) 35 | 36 | - [-1, 1, Conv, [512, 3, 2]] 37 | - [[-1, 9], 1, Concat, [1]] # cat head P5 38 | - [-1, 3, C2f, [1024]] # 23 (P5/32-large) 39 | 40 | - [[15, 18, 21], 1, Segment, [nc, 32, 256]] # Detect(P3, P4, P5) 41 | -------------------------------------------------------------------------------- /ultralytics/models/v8/seg/yolov8s-seg.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 0.33 # scales module repeats 6 | width_multiple: 0.50 # scales convolution channels 7 | 8 | # YOLOv8.0s backbone 9 | backbone: 10 | # [from, repeats, module, args] 11 | - [-1, 1, Conv, [64, 3, 2]] # 0-P1/2 12 | - [-1, 1, Conv, [128, 3, 2]] # 1-P2/4 13 | - [-1, 3, C2f, [128, True]] 14 | - [-1, 1, Conv, [256, 3, 2]] # 3-P3/8 15 | - [-1, 6, C2f, [256, True]] 16 | - [-1, 1, Conv, [512, 3, 2]] # 5-P4/16 17 | - [-1, 6, C2f, [512, True]] 18 | - [-1, 1, Conv, [1024, 3, 2]] # 7-P5/32 19 | - [-1, 3, C2f, [1024, True]] 20 | - [-1, 1, SPPF, [1024, 5]] # 9 21 | 22 | # YOLOv8.0s head 23 | head: 24 | - [-1, 1, nn.Upsample, [None, 2, 'nearest']] 25 | - [[-1, 6], 1, Concat, [1]] # cat backbone P4 26 | - [-1, 3, C2f, [512]] # 13 27 | 28 | - [-1, 1, nn.Upsample, [None, 2, 'nearest']] 29 | - [[-1, 4], 1, Concat, [1]] # cat backbone P3 30 | - [-1, 3, C2f, [256]] # 17 (P3/8-small) 31 | 32 | - [-1, 1, Conv, [256, 3, 2]] 33 | - [[-1, 12], 1, Concat, [1]] # cat head P4 34 | - [-1, 3, C2f, [512]] # 20 (P4/16-medium) 35 | 36 | - [-1, 1, Conv, [512, 3, 2]] 37 | - [[-1, 9], 1, Concat, [1]] # cat head P5 38 | - [-1, 3, C2f, [1024]] # 23 (P5/32-large) 39 | 40 | - [[15, 18, 21], 1, Segment, [nc, 32, 256]] # Detect(P3, P4, P5) 41 | -------------------------------------------------------------------------------- /docs/app.md: -------------------------------------------------------------------------------- 1 | # Ultralytics HUB App for YOLOv8 2 | 3 |
4 | 5 | 6 |
7 |
8 | 9 | Welcome to the Ultralytics HUB app for demonstrating YOLOv5 and YOLOv8 models! In this app, available on the [Apple App 10 | Store](https://apps.apple.com/xk/app/ultralytics/id1583935240) and the 11 | [Google Play Store](https://play.google.com/store/apps/details?id=com.ultralytics.ultralytics_app), you will be able 12 | to see the power and capabilities of YOLOv5, a state-of-the-art object detection model developed by Ultralytics. 13 | 14 | **To install simply scan the QR code above**. The App currently features YOLOv5 models, with YOLOv8 models coming soon. 15 | 16 | With YOLOv5, you can detect and classify objects in images and videos with high accuracy and speed. The model has been 17 | trained on a large dataset and is able to detect a wide range of objects, including cars, pedestrians, and traffic 18 | signs. 19 | 20 | In this app, you will be able to try out YOLOv5 on your own images and videos, and see the model in action. You can also 21 | learn more about how YOLOv5 works and how it can be used in real-world applications. 22 | 23 | We hope you enjoy using YOLOv5 and seeing its capabilities firsthand. Thank you for choosing Ultralytics for your object 24 | detection needs! -------------------------------------------------------------------------------- /ultralytics/models/v5/yolov5l.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 1.0 # model depth multiple 6 | width_multiple: 1.0 # layer channel multiple 7 | 8 | # YOLOv5 v6.0 backbone 9 | backbone: 10 | # [from, number, module, args] 11 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 12 | [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 13 | [-1, 3, C3, [128]], 14 | [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 15 | [-1, 6, C3, [256]], 16 | [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 17 | [-1, 9, C3, [512]], 18 | [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 19 | [-1, 3, C3, [1024]], 20 | [-1, 1, SPPF, [1024, 5]], # 9 21 | ] 22 | 23 | # YOLOv5 v6.0 head 24 | head: 25 | [[-1, 1, Conv, [512, 1, 1]], 26 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 27 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 28 | [-1, 3, C3, [512, False]], # 13 29 | 30 | [-1, 1, Conv, [256, 1, 1]], 31 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 32 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 33 | [-1, 3, C3, [256, False]], # 17 (P3/8-small) 34 | 35 | [-1, 1, Conv, [256, 3, 2]], 36 | [[-1, 14], 1, Concat, [1]], # cat head P4 37 | [-1, 3, C3, [512, False]], # 20 (P4/16-medium) 38 | 39 | [-1, 1, Conv, [512, 3, 2]], 40 | [[-1, 10], 1, Concat, [1]], # cat head P5 41 | [-1, 3, C3, [1024, False]], # 23 (P5/32-large) 42 | 43 | [[17, 20, 23], 1, Detect, [nc]], # Detect(P3, P4, P5) 44 | ] -------------------------------------------------------------------------------- /ultralytics/models/v5/yolov5m.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 0.67 # model depth multiple 6 | width_multiple: 0.75 # layer channel multiple 7 | 8 | # YOLOv5 v6.0 backbone 9 | backbone: 10 | # [from, number, module, args] 11 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 12 | [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 13 | [-1, 3, C3, [128]], 14 | [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 15 | [-1, 6, C3, [256]], 16 | [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 17 | [-1, 9, C3, [512]], 18 | [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 19 | [-1, 3, C3, [1024]], 20 | [-1, 1, SPPF, [1024, 5]], # 9 21 | ] 22 | 23 | # YOLOv5 v6.0 head 24 | head: 25 | [[-1, 1, Conv, [512, 1, 1]], 26 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 27 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 28 | [-1, 3, C3, [512, False]], # 13 29 | 30 | [-1, 1, Conv, [256, 1, 1]], 31 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 32 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 33 | [-1, 3, C3, [256, False]], # 17 (P3/8-small) 34 | 35 | [-1, 1, Conv, [256, 3, 2]], 36 | [[-1, 14], 1, Concat, [1]], # cat head P4 37 | [-1, 3, C3, [512, False]], # 20 (P4/16-medium) 38 | 39 | [-1, 1, Conv, [512, 3, 2]], 40 | [[-1, 10], 1, Concat, [1]], # cat head P5 41 | [-1, 3, C3, [1024, False]], # 23 (P5/32-large) 42 | 43 | [[17, 20, 23], 1, Detect, [nc]], # Detect(P3, P4, P5) 44 | ] -------------------------------------------------------------------------------- /ultralytics/models/v5/yolov5n.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 0.33 # model depth multiple 6 | width_multiple: 0.25 # layer channel multiple 7 | 8 | # YOLOv5 v6.0 backbone 9 | backbone: 10 | # [from, number, module, args] 11 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 12 | [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 13 | [-1, 3, C3, [128]], 14 | [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 15 | [-1, 6, C3, [256]], 16 | [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 17 | [-1, 9, C3, [512]], 18 | [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 19 | [-1, 3, C3, [1024]], 20 | [-1, 1, SPPF, [1024, 5]], # 9 21 | ] 22 | 23 | # YOLOv5 v6.0 head 24 | head: 25 | [[-1, 1, Conv, [512, 1, 1]], 26 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 27 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 28 | [-1, 3, C3, [512, False]], # 13 29 | 30 | [-1, 1, Conv, [256, 1, 1]], 31 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 32 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 33 | [-1, 3, C3, [256, False]], # 17 (P3/8-small) 34 | 35 | [-1, 1, Conv, [256, 3, 2]], 36 | [[-1, 14], 1, Concat, [1]], # cat head P4 37 | [-1, 3, C3, [512, False]], # 20 (P4/16-medium) 38 | 39 | [-1, 1, Conv, [512, 3, 2]], 40 | [[-1, 10], 1, Concat, [1]], # cat head P5 41 | [-1, 3, C3, [1024, False]], # 23 (P5/32-large) 42 | 43 | [[17, 20, 23], 1, Detect, [nc]], # Detect(P3, P4, P5) 44 | ] -------------------------------------------------------------------------------- /ultralytics/models/v5/yolov5x.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 1.33 # model depth multiple 6 | width_multiple: 1.25 # layer channel multiple 7 | 8 | # YOLOv5 v6.0 backbone 9 | backbone: 10 | # [from, number, module, args] 11 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 12 | [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 13 | [-1, 3, C3, [128]], 14 | [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 15 | [-1, 6, C3, [256]], 16 | [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 17 | [-1, 9, C3, [512]], 18 | [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 19 | [-1, 3, C3, [1024]], 20 | [-1, 1, SPPF, [1024, 5]], # 9 21 | ] 22 | 23 | # YOLOv5 v6.0 head 24 | head: 25 | [[-1, 1, Conv, [512, 1, 1]], 26 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 27 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 28 | [-1, 3, C3, [512, False]], # 13 29 | 30 | [-1, 1, Conv, [256, 1, 1]], 31 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 32 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 33 | [-1, 3, C3, [256, False]], # 17 (P3/8-small) 34 | 35 | [-1, 1, Conv, [256, 3, 2]], 36 | [[-1, 14], 1, Concat, [1]], # cat head P4 37 | [-1, 3, C3, [512, False]], # 20 (P4/16-medium) 38 | 39 | [-1, 1, Conv, [512, 3, 2]], 40 | [[-1, 10], 1, Concat, [1]], # cat head P5 41 | [-1, 3, C3, [1024, False]], # 23 (P5/32-large) 42 | 43 | [[17, 20, 23], 1, Detect, [nc]], # Detect(P3, P4, P5) 44 | ] -------------------------------------------------------------------------------- /ultralytics/models/v5/yolov5s.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 0.33 # model depth multiple 6 | width_multiple: 0.50 # layer channel multiple 7 | 8 | 9 | # YOLOv5 v6.0 backbone 10 | backbone: 11 | # [from, number, module, args] 12 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 13 | [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 14 | [-1, 3, C3, [128]], 15 | [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 16 | [-1, 6, C3, [256]], 17 | [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 18 | [-1, 9, C3, [512]], 19 | [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 20 | [-1, 3, C3, [1024]], 21 | [-1, 1, SPPF, [1024, 5]], # 9 22 | ] 23 | 24 | # YOLOv5 v6.0 head 25 | head: 26 | [[-1, 1, Conv, [512, 1, 1]], 27 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 28 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 29 | [-1, 3, C3, [512, False]], # 13 30 | 31 | [-1, 1, Conv, [256, 1, 1]], 32 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 33 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 34 | [-1, 3, C3, [256, False]], # 17 (P3/8-small) 35 | 36 | [-1, 1, Conv, [256, 3, 2]], 37 | [[-1, 14], 1, Concat, [1]], # cat head P4 38 | [-1, 3, C3, [512, False]], # 20 (P4/16-medium) 39 | 40 | [-1, 1, Conv, [512, 3, 2]], 41 | [[-1, 10], 1, Concat, [1]], # cat head P5 42 | [-1, 3, C3, [1024, False]], # 23 (P5/32-large) 43 | 44 | [[17, 20, 23], 1, Detect, [nc]], # Detect(P3, P4, P5) 45 | ] -------------------------------------------------------------------------------- /ultralytics/yolo/data/dataset_wrappers.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | import collections 4 | from copy import deepcopy 5 | 6 | from .augment import LetterBox 7 | 8 | 9 | class MixAndRectDataset: 10 | """A wrapper of multiple images mixed dataset. 11 | 12 | Args: 13 | dataset (:obj:`BaseDataset`): The dataset to be mixed. 14 | transforms (Sequence[dict]): config dict to be composed. 15 | """ 16 | 17 | def __init__(self, dataset): 18 | self.dataset = dataset 19 | self.imgsz = dataset.imgsz 20 | 21 | def __len__(self): 22 | return len(self.dataset) 23 | 24 | def __getitem__(self, index): 25 | labels = deepcopy(self.dataset[index]) 26 | for transform in self.dataset.transforms.tolist(): 27 | # mosaic and mixup 28 | if hasattr(transform, "get_indexes"): 29 | indexes = transform.get_indexes(self.dataset) 30 | if not isinstance(indexes, collections.abc.Sequence): 31 | indexes = [indexes] 32 | mix_labels = [deepcopy(self.dataset[index]) for index in indexes] 33 | labels["mix_labels"] = mix_labels 34 | if self.dataset.rect and isinstance(transform, LetterBox): 35 | transform.new_shape = self.dataset.batch_shapes[self.dataset.batch[index]] 36 | labels = transform(labels) 37 | if "mix_labels" in labels: 38 | labels.pop("mix_labels") 39 | return labels 40 | -------------------------------------------------------------------------------- /.github/workflows/cla.yml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | name: "CLA Assistant" 4 | on: 5 | issue_comment: 6 | types: 7 | - created 8 | pull_request_target: 9 | types: 10 | - reopened 11 | - opened 12 | - synchronize 13 | 14 | jobs: 15 | CLA: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: "CLA Assistant" 19 | if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I sign the CLA') || github.event_name == 'pull_request_target' 20 | uses: contributor-assistant/github-action@v2.2.0 21 | env: 22 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 23 | # must be repository secret token 24 | PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} 25 | with: 26 | path-to-signatures: 'signatures/version1/cla.json' 27 | path-to-document: 'https://github.com/ultralytics/assets/blob/main/documents/CLA.md' # CLA document 28 | # branch should not be protected 29 | branch: 'main' 30 | allowlist: dependabot[bot],github-actions,[pre-commit*,pre-commit*,bot* 31 | 32 | remote-organization-name: ultralytics 33 | remote-repository-name: cla 34 | custom-pr-sign-comment: 'I have read the CLA Document and I sign the CLA' 35 | custom-allsigned-prcomment: All Contributors have signed the CLA. ✅ 36 | #custom-notsigned-prcomment: 'pull request comment with Introductory message to ask new contributors to sign' 37 | -------------------------------------------------------------------------------- /ultralytics/models/v3/yolov3.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 1.0 # model depth multiple 6 | width_multiple: 1.0 # layer channel multiple 7 | 8 | # darknet53 backbone 9 | backbone: 10 | # [from, number, module, args] 11 | [[-1, 1, Conv, [32, 3, 1]], # 0 12 | [-1, 1, Conv, [64, 3, 2]], # 1-P1/2 13 | [-1, 1, Bottleneck, [64]], 14 | [-1, 1, Conv, [128, 3, 2]], # 3-P2/4 15 | [-1, 2, Bottleneck, [128]], 16 | [-1, 1, Conv, [256, 3, 2]], # 5-P3/8 17 | [-1, 8, Bottleneck, [256]], 18 | [-1, 1, Conv, [512, 3, 2]], # 7-P4/16 19 | [-1, 8, Bottleneck, [512]], 20 | [-1, 1, Conv, [1024, 3, 2]], # 9-P5/32 21 | [-1, 4, Bottleneck, [1024]], # 10 22 | ] 23 | 24 | # YOLOv3 head 25 | head: 26 | [[-1, 1, Bottleneck, [1024, False]], 27 | [-1, 1, Conv, [512, 1, 1]], 28 | [-1, 1, Conv, [1024, 3, 1]], 29 | [-1, 1, Conv, [512, 1, 1]], 30 | [-1, 1, Conv, [1024, 3, 1]], # 15 (P5/32-large) 31 | 32 | [-2, 1, Conv, [256, 1, 1]], 33 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 34 | [[-1, 8], 1, Concat, [1]], # cat backbone P4 35 | [-1, 1, Bottleneck, [512, False]], 36 | [-1, 1, Bottleneck, [512, False]], 37 | [-1, 1, Conv, [256, 1, 1]], 38 | [-1, 1, Conv, [512, 3, 1]], # 22 (P4/16-medium) 39 | 40 | [-2, 1, Conv, [128, 1, 1]], 41 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 42 | [[-1, 6], 1, Concat, [1]], # cat backbone P3 43 | [-1, 1, Bottleneck, [256, False]], 44 | [-1, 2, Bottleneck, [256, False]], # 27 (P3/8-small) 45 | 46 | [[27, 22, 15], 1, Detect, [nc]], # Detect(P3, P4, P5) 47 | ] 48 | -------------------------------------------------------------------------------- /ultralytics/models/v3/yolov3-spp.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 1.0 # model depth multiple 6 | width_multiple: 1.0 # layer channel multiple 7 | 8 | # darknet53 backbone 9 | backbone: 10 | # [from, number, module, args] 11 | [[-1, 1, Conv, [32, 3, 1]], # 0 12 | [-1, 1, Conv, [64, 3, 2]], # 1-P1/2 13 | [-1, 1, Bottleneck, [64]], 14 | [-1, 1, Conv, [128, 3, 2]], # 3-P2/4 15 | [-1, 2, Bottleneck, [128]], 16 | [-1, 1, Conv, [256, 3, 2]], # 5-P3/8 17 | [-1, 8, Bottleneck, [256]], 18 | [-1, 1, Conv, [512, 3, 2]], # 7-P4/16 19 | [-1, 8, Bottleneck, [512]], 20 | [-1, 1, Conv, [1024, 3, 2]], # 9-P5/32 21 | [-1, 4, Bottleneck, [1024]], # 10 22 | ] 23 | 24 | # YOLOv3-SPP head 25 | head: 26 | [[-1, 1, Bottleneck, [1024, False]], 27 | [-1, 1, SPP, [512, [5, 9, 13]]], 28 | [-1, 1, Conv, [1024, 3, 1]], 29 | [-1, 1, Conv, [512, 1, 1]], 30 | [-1, 1, Conv, [1024, 3, 1]], # 15 (P5/32-large) 31 | 32 | [-2, 1, Conv, [256, 1, 1]], 33 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 34 | [[-1, 8], 1, Concat, [1]], # cat backbone P4 35 | [-1, 1, Bottleneck, [512, False]], 36 | [-1, 1, Bottleneck, [512, False]], 37 | [-1, 1, Conv, [256, 1, 1]], 38 | [-1, 1, Conv, [512, 3, 1]], # 22 (P4/16-medium) 39 | 40 | [-2, 1, Conv, [128, 1, 1]], 41 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 42 | [[-1, 6], 1, Concat, [1]], # cat backbone P3 43 | [-1, 1, Bottleneck, [256, False]], 44 | [-1, 2, Bottleneck, [256, False]], # 27 (P3/8-small) 45 | 46 | [[27, 22, 15], 1, Detect, [nc]], # Detect(P3, P4, P5) 47 | ] 48 | -------------------------------------------------------------------------------- /ultralytics/models/v8/yolov8x6.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 1.00 # scales module repeats 6 | width_multiple: 1.25 # scales convolution channels 7 | 8 | # YOLOv8.0x6 backbone 9 | backbone: 10 | # [from, repeats, module, args] 11 | - [-1, 1, Conv, [64, 3, 2]] # 0-P1/2 12 | - [-1, 1, Conv, [128, 3, 2]] # 1-P2/4 13 | - [-1, 3, C2f, [128, True]] 14 | - [-1, 1, Conv, [256, 3, 2]] # 3-P3/8 15 | - [-1, 6, C2f, [256, True]] 16 | - [-1, 1, Conv, [512, 3, 2]] # 5-P4/16 17 | - [-1, 6, C2f, [512, True]] 18 | - [-1, 1, Conv, [512, 3, 2]] # 7-P5/32 19 | - [-1, 3, C2f, [512, True]] 20 | - [-1, 1, Conv, [512, 3, 2]] # 9-P6/64 21 | - [-1, 3, C2f, [512, True]] 22 | - [-1, 1, SPPF, [512, 5]] # 11 23 | 24 | # YOLOv8.0x6 head 25 | head: 26 | - [-1, 1, nn.Upsample, [None, 2, 'nearest']] 27 | - [[-1, 8], 1, Concat, [1]] # cat backbone P5 28 | - [-1, 3, C2, [512, False]] # 14 29 | 30 | - [-1, 1, nn.Upsample, [None, 2, 'nearest']] 31 | - [[-1, 6], 1, Concat, [1]] # cat backbone P4 32 | - [-1, 3, C2, [512, False]] # 17 33 | 34 | - [-1, 1, nn.Upsample, [None, 2, 'nearest']] 35 | - [[-1, 4], 1, Concat, [1]] # cat backbone P3 36 | - [-1, 3, C2, [256, False]] # 20 (P3/8-small) 37 | 38 | - [-1, 1, Conv, [256, 3, 2]] 39 | - [[-1, 17], 1, Concat, [1]] # cat head P4 40 | - [-1, 3, C2, [512, False]] # 23 (P4/16-medium) 41 | 42 | - [-1, 1, Conv, [512, 3, 2]] 43 | - [[-1, 14], 1, Concat, [1]] # cat head P5 44 | - [-1, 3, C2, [512, False]] # 26 (P5/32-large) 45 | 46 | - [-1, 1, Conv, [512, 3, 2]] 47 | - [[-1, 11], 1, Concat, [1]] # cat head P6 48 | - [-1, 3, C2, [512, False]] # 29 (P6/64-xlarge) 49 | 50 | - [[20, 23, 26, 29], 1, Detect, [nc]] # Detect(P3, P4, P5, P6) 51 | -------------------------------------------------------------------------------- /ultralytics/yolo/utils/callbacks/comet.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | from ultralytics.yolo.utils.torch_utils import get_flops, get_num_params 4 | 5 | try: 6 | import comet_ml 7 | 8 | except (ModuleNotFoundError, ImportError): 9 | comet_ml = None 10 | 11 | 12 | def on_pretrain_routine_start(trainer): 13 | experiment = comet_ml.Experiment(project_name=trainer.args.project or "YOLOv8",) 14 | experiment.log_parameters(dict(trainer.args)) 15 | 16 | 17 | def on_train_epoch_end(trainer): 18 | experiment = comet_ml.get_global_experiment() 19 | experiment.log_metrics(trainer.label_loss_items(trainer.tloss, prefix="train"), step=trainer.epoch + 1) 20 | if trainer.epoch == 1: 21 | for f in trainer.save_dir.glob('train_batch*.jpg'): 22 | experiment.log_image(f, name=f.stem, step=trainer.epoch + 1) 23 | 24 | 25 | def on_fit_epoch_end(trainer): 26 | experiment = comet_ml.get_global_experiment() 27 | experiment.log_metrics(trainer.metrics, step=trainer.epoch + 1) 28 | if trainer.epoch == 0: 29 | model_info = { 30 | "model/parameters": get_num_params(trainer.model), 31 | "model/GFLOPs": round(get_flops(trainer.model), 3), 32 | "model/speed(ms)": round(trainer.validator.speed[1], 3)} 33 | experiment.log_metrics(model_info, step=trainer.epoch + 1) 34 | 35 | 36 | def on_train_end(trainer): 37 | experiment = comet_ml.get_global_experiment() 38 | experiment.log_model("YOLOv8", file_or_folder=trainer.best, file_name="best.pt", overwrite=True) 39 | 40 | 41 | callbacks = { 42 | "on_pretrain_routine_start": on_pretrain_routine_start, 43 | "on_train_epoch_end": on_train_epoch_end, 44 | "on_fit_epoch_end": on_fit_epoch_end, 45 | "on_train_end": on_train_end} if comet_ml else {} 46 | -------------------------------------------------------------------------------- /.github/workflows/docker.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | # Builds ultralytics/ultralytics:latest images on DockerHub https://hub.docker.com/r/ultralytics 3 | 4 | name: Publish Docker Images 5 | 6 | on: 7 | push: 8 | branches: [main] 9 | 10 | jobs: 11 | docker: 12 | if: github.repository == 'ultralytics/ultralytics' 13 | name: Push Docker image to Docker Hub 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout repo 17 | uses: actions/checkout@v3 18 | 19 | - name: Set up QEMU 20 | uses: docker/setup-qemu-action@v2 21 | 22 | - name: Set up Docker Buildx 23 | uses: docker/setup-buildx-action@v2 24 | 25 | - name: Login to Docker Hub 26 | uses: docker/login-action@v2 27 | with: 28 | username: ${{ secrets.DOCKERHUB_USERNAME }} 29 | password: ${{ secrets.DOCKERHUB_TOKEN }} 30 | 31 | - name: Build and push arm64 image 32 | uses: docker/build-push-action@v3 33 | continue-on-error: true 34 | with: 35 | context: . 36 | platforms: linux/arm64 37 | file: docker/Dockerfile-arm64 38 | push: true 39 | tags: ultralytics/ultralytics:latest-arm64 40 | 41 | - name: Build and push CPU image 42 | uses: docker/build-push-action@v3 43 | continue-on-error: true 44 | with: 45 | context: . 46 | file: docker/Dockerfile-cpu 47 | push: true 48 | tags: ultralytics/ultralytics:latest-cpu 49 | 50 | - name: Build and push GPU image 51 | uses: docker/build-push-action@v3 52 | continue-on-error: true 53 | with: 54 | context: . 55 | file: docker/Dockerfile 56 | push: true 57 | tags: ultralytics/ultralytics:latest 58 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | # Define hooks for code formations 2 | # Will be applied on any updated commit files if a user has installed and linked commit hook 3 | 4 | default_language_version: 5 | python: python3.8 6 | 7 | exclude: 'docs/' 8 | # Define bot property if installed via https://github.com/marketplace/pre-commit-ci 9 | ci: 10 | autofix_prs: true 11 | autoupdate_commit_msg: '[pre-commit.ci] pre-commit suggestions' 12 | autoupdate_schedule: monthly 13 | # submodules: true 14 | 15 | repos: 16 | - repo: https://github.com/pre-commit/pre-commit-hooks 17 | rev: v4.3.0 18 | hooks: 19 | # - id: end-of-file-fixer 20 | - id: trailing-whitespace 21 | - id: check-case-conflict 22 | - id: check-yaml 23 | - id: check-toml 24 | - id: pretty-format-json 25 | - id: check-docstring-first 26 | 27 | - repo: https://github.com/asottile/pyupgrade 28 | rev: v2.37.3 29 | hooks: 30 | - id: pyupgrade 31 | name: Upgrade code 32 | args: [ --py37-plus ] 33 | 34 | - repo: https://github.com/PyCQA/isort 35 | rev: 5.10.1 36 | hooks: 37 | - id: isort 38 | name: Sort imports 39 | 40 | - repo: https://github.com/pre-commit/mirrors-yapf 41 | rev: v0.32.0 42 | hooks: 43 | - id: yapf 44 | name: YAPF formatting 45 | 46 | - repo: https://github.com/executablebooks/mdformat 47 | rev: 0.7.16 48 | hooks: 49 | - id: mdformat 50 | name: MD formatting 51 | additional_dependencies: 52 | - mdformat-gfm 53 | - mdformat-black 54 | # exclude: "README.md|README.zh-CN.md|CONTRIBUTING.md" 55 | 56 | - repo: https://github.com/PyCQA/flake8 57 | rev: 5.0.4 58 | hooks: 59 | - id: flake8 60 | name: PEP8 61 | 62 | #- repo: https://github.com/asottile/yesqa 63 | # rev: v1.4.0 64 | # hooks: 65 | # - id: yesqa -------------------------------------------------------------------------------- /ultralytics/yolo/data/scripts/get_imagenet.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Ultralytics YOLO 🚀, GPL-3.0 license 3 | # Download ILSVRC2012 ImageNet dataset https://image-net.org 4 | # Example usage: bash data/scripts/get_imagenet.sh 5 | # parent 6 | # ├── yolov5 7 | # └── datasets 8 | # └── imagenet ← downloads here 9 | 10 | # Arguments (optional) Usage: bash data/scripts/get_imagenet.sh --train --val 11 | if [ "$#" -gt 0 ]; then 12 | for opt in "$@"; do 13 | case "${opt}" in 14 | --train) train=true ;; 15 | --val) val=true ;; 16 | esac 17 | done 18 | else 19 | train=true 20 | val=true 21 | fi 22 | 23 | # Make dir 24 | d='../datasets/imagenet' # unzip directory 25 | mkdir -p $d && cd $d 26 | 27 | # Download/unzip train 28 | if [ "$train" == "true" ]; then 29 | wget https://image-net.org/data/ILSVRC/2012/ILSVRC2012_img_train.tar # download 138G, 1281167 images 30 | mkdir train && mv ILSVRC2012_img_train.tar train/ && cd train 31 | tar -xf ILSVRC2012_img_train.tar && rm -f ILSVRC2012_img_train.tar 32 | find . -name "*.tar" | while read NAME; do 33 | mkdir -p "${NAME%.tar}" 34 | tar -xf "${NAME}" -C "${NAME%.tar}" 35 | rm -f "${NAME}" 36 | done 37 | cd .. 38 | fi 39 | 40 | # Download/unzip val 41 | if [ "$val" == "true" ]; then 42 | wget https://image-net.org/data/ILSVRC/2012/ILSVRC2012_img_val.tar # download 6.3G, 50000 images 43 | mkdir val && mv ILSVRC2012_img_val.tar val/ && cd val && tar -xf ILSVRC2012_img_val.tar 44 | wget -qO- https://raw.githubusercontent.com/soumith/imagenetloader.torch/master/valprep.sh | bash # move into subdirs 45 | fi 46 | 47 | # Delete corrupted image (optional: PNG under JPEG name that may cause dataloaders to fail) 48 | # rm train/n04266014/n04266014_10835.JPEG 49 | 50 | # TFRecords (optional) 51 | # wget https://raw.githubusercontent.com/tensorflow/models/master/research/slim/datasets/imagenet_lsvrc_2015_synsets.txt 52 | -------------------------------------------------------------------------------- /docker/Dockerfile-cpu: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | # Builds ultralytics/ultralytics:latest-cpu image on DockerHub https://hub.docker.com/r/ultralytics/ultralytics 3 | # Image is CPU-optimized for ONNX, OpenVINO and PyTorch YOLOv8 deployments 4 | 5 | # Start FROM Ubuntu image https://hub.docker.com/_/ubuntu 6 | FROM ubuntu:20.04 7 | 8 | # Downloads to user config dir 9 | ADD https://ultralytics.com/assets/Arial.ttf https://ultralytics.com/assets/Arial.Unicode.ttf /root/.config/Ultralytics/ 10 | 11 | # Install linux packages 12 | ENV DEBIAN_FRONTEND noninteractive 13 | RUN apt update 14 | RUN TZ=Etc/UTC apt install -y tzdata 15 | RUN apt install --no-install-recommends -y python3-pip git zip curl htop libgl1-mesa-glx libglib2.0-0 libpython3-dev gnupg 16 | # RUN alias python=python3 17 | 18 | # Create working directory 19 | RUN mkdir -p /usr/src/ultralytics 20 | WORKDIR /usr/src/ultralytics 21 | 22 | # Copy contents 23 | # COPY . /usr/src/app (issues as not a .git directory) 24 | RUN git clone https://github.com/ultralytics/ultralytics /usr/src/ultralytics 25 | 26 | # Install pip packages 27 | COPY requirements.txt . 28 | RUN python3 -m pip install --upgrade pip wheel 29 | RUN pip install --no-cache ultralytics albumentations gsutil notebook \ 30 | coremltools onnx onnx-simplifier onnxruntime tensorflow-cpu tensorflowjs \ 31 | # openvino-dev \ 32 | --extra-index-url https://download.pytorch.org/whl/cpu 33 | 34 | # Cleanup 35 | ENV DEBIAN_FRONTEND teletype 36 | 37 | 38 | # Usage Examples ------------------------------------------------------------------------------------------------------- 39 | 40 | # Build and Push 41 | # t=ultralytics/ultralytics:latest-cpu && sudo docker build -f utils/docker/Dockerfile-cpu -t $t . && sudo docker push $t 42 | 43 | # Pull and Run 44 | # t=ultralytics/ultralytics:latest-cpu && sudo docker pull $t && sudo docker run -it --ipc=host -v "$(pwd)"/datasets:/usr/src/datasets $t 45 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | # Project-wide configuration file, can be used for package metadata and other toll configurations 2 | # Example usage: global configuration for PEP8 (via flake8) setting or default pytest arguments 3 | # Local usage: pip install pre-commit, pre-commit run --all-files 4 | 5 | [metadata] 6 | license_file = LICENSE 7 | description_file = README.md 8 | 9 | [tool:pytest] 10 | norecursedirs = 11 | .git 12 | dist 13 | build 14 | addopts = 15 | --doctest-modules 16 | --durations=25 17 | --color=yes 18 | 19 | [flake8] 20 | max-line-length = 120 21 | exclude = .tox,*.egg,build,temp 22 | select = E,W,F 23 | doctests = True 24 | verbose = 2 25 | # https://pep8.readthedocs.io/en/latest/intro.html#error-codes 26 | format = pylint 27 | # see: https://www.flake8rules.com/ 28 | ignore = E731,F405,E402,F401,W504,E127,E231,E501,F403 29 | # E731: Do not assign a lambda expression, use a def 30 | # F405: name may be undefined, or defined from star imports: module 31 | # E402: module level import not at top of file 32 | # F401: module imported but unused 33 | # W504: line break after binary operator 34 | # E127: continuation line over-indented for visual indent 35 | # E231: missing whitespace after ‘,’, ‘;’, or ‘:’ 36 | # E501: line too long 37 | # F403: ‘from module import *’ used; unable to detect undefined names 38 | 39 | [isort] 40 | # https://pycqa.github.io/isort/docs/configuration/options.html 41 | line_length = 120 42 | # see: https://pycqa.github.io/isort/docs/configuration/multi_line_output_modes.html 43 | multi_line_output = 0 44 | 45 | [yapf] 46 | based_on_style = pep8 47 | spaces_before_comment = 2 48 | COLUMN_LIMIT = 120 49 | COALESCE_BRACKETS = True 50 | SPACES_AROUND_POWER_OPERATOR = True 51 | SPACE_BETWEEN_ENDING_COMMA_AND_CLOSING_BRACKET = False 52 | SPLIT_BEFORE_CLOSING_BRACKET = False 53 | SPLIT_BEFORE_FIRST_ARGUMENT = False 54 | # EACH_DICT_ENTRY_ON_SEPARATE_LINE = False 55 | -------------------------------------------------------------------------------- /docker/Dockerfile-arm64: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | # Builds ultralytics/ultralytics:latest-arm64 image on DockerHub https://hub.docker.com/r/ultralytics/ultralytics 3 | # Image is aarch64-compatible for Apple M1 and other ARM architectures i.e. Jetson Nano and Raspberry Pi 4 | 5 | # Start FROM Ubuntu image https://hub.docker.com/_/ubuntu 6 | FROM arm64v8/ubuntu:20.04 7 | 8 | # Downloads to user config dir 9 | ADD https://ultralytics.com/assets/Arial.ttf https://ultralytics.com/assets/Arial.Unicode.ttf /root/.config/Ultralytics/ 10 | 11 | # Install linux packages 12 | ENV DEBIAN_FRONTEND noninteractive 13 | RUN apt update 14 | RUN TZ=Etc/UTC apt install -y tzdata 15 | RUN apt install --no-install-recommends -y python3-pip git zip curl htop gcc libgl1-mesa-glx libglib2.0-0 libpython3-dev 16 | # RUN alias python=python3 17 | 18 | # Create working directory 19 | RUN mkdir -p /usr/src/ultralytics 20 | WORKDIR /usr/src/ultralytics 21 | 22 | # Copy contents 23 | # COPY . /usr/src/app (issues as not a .git directory) 24 | RUN git clone https://github.com/ultralytics/ultralytics /usr/src/ultralytics 25 | 26 | # Install pip packages 27 | COPY requirements.txt . 28 | RUN python3 -m pip install --upgrade pip wheel 29 | RUN pip install --no-cache ultralytics gsutil notebook \ 30 | tensorflow-aarch64 31 | # tensorflowjs \ 32 | # onnx onnx-simplifier onnxruntime \ 33 | # coremltools openvino-dev \ 34 | 35 | # Cleanup 36 | ENV DEBIAN_FRONTEND teletype 37 | 38 | 39 | # Usage Examples ------------------------------------------------------------------------------------------------------- 40 | 41 | # Build and Push 42 | # t=ultralytics/ultralytics:latest-arm64 && sudo docker build --platform linux/arm64 -f utils/docker/Dockerfile-arm64 -t $t . && sudo docker push $t 43 | 44 | # Pull and Run 45 | # t=ultralytics/ultralytics:latest-arm64 && sudo docker pull $t && sudo docker run -it --ipc=host -v "$(pwd)"/datasets:/usr/src/datasets $t 46 | -------------------------------------------------------------------------------- /ultralytics/yolo/data/scripts/get_coco.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Ultralytics YOLO 🚀, GPL-3.0 license 3 | # Download COCO 2017 dataset http://cocodataset.org 4 | # Example usage: bash data/scripts/get_coco.sh 5 | # parent 6 | # ├── yolov5 7 | # └── datasets 8 | # └── coco ← downloads here 9 | 10 | # Arguments (optional) Usage: bash data/scripts/get_coco.sh --train --val --test --segments 11 | if [ "$#" -gt 0 ]; then 12 | for opt in "$@"; do 13 | case "${opt}" in 14 | --train) train=true ;; 15 | --val) val=true ;; 16 | --test) test=true ;; 17 | --segments) segments=true ;; 18 | --sama) sama=true ;; 19 | esac 20 | done 21 | else 22 | train=true 23 | val=true 24 | test=false 25 | segments=false 26 | sama=false 27 | fi 28 | 29 | # Download/unzip labels 30 | d='../datasets' # unzip directory 31 | url=https://github.com/ultralytics/yolov5/releases/download/v1.0/ 32 | if [ "$segments" == "true" ]; then 33 | f='coco2017labels-segments.zip' # 169 MB 34 | elif [ "$sama" == "true" ]; then 35 | f='coco2017labels-segments-sama.zip' # 199 MB https://www.sama.com/sama-coco-dataset/ 36 | else 37 | f='coco2017labels.zip' # 46 MB 38 | fi 39 | echo 'Downloading' $url$f ' ...' 40 | curl -L $url$f -o $f -# && unzip -q $f -d $d && rm $f & 41 | 42 | # Download/unzip images 43 | d='../datasets/coco/images' # unzip directory 44 | url=http://images.cocodataset.org/zips/ 45 | if [ "$train" == "true" ]; then 46 | f='train2017.zip' # 19G, 118k images 47 | echo 'Downloading' $url$f '...' 48 | curl -L $url$f -o $f -# && unzip -q $f -d $d && rm $f & 49 | fi 50 | if [ "$val" == "true" ]; then 51 | f='val2017.zip' # 1G, 5k images 52 | echo 'Downloading' $url$f '...' 53 | curl -L $url$f -o $f -# && unzip -q $f -d $d && rm $f & 54 | fi 55 | if [ "$test" == "true" ]; then 56 | f='test2017.zip' # 7G, 41k images (optional) 57 | echo 'Downloading' $url$f '...' 58 | curl -L $url$f -o $f -# && unzip -q $f -d $d && rm $f & 59 | fi 60 | wait # finish background tasks 61 | -------------------------------------------------------------------------------- /ultralytics/models/README.md: -------------------------------------------------------------------------------- 1 | ## Models 2 | 3 | Welcome to the Ultralytics Models directory! Here you will find a wide variety of pre-configured model configuration 4 | files (`*.yaml`s) that can be used to create custom YOLO models. The models in this directory have been expertly crafted 5 | and fine-tuned by the Ultralytics team to provide the best performance for a wide range of object detection and image 6 | segmentation tasks. 7 | 8 | These model configurations cover a wide range of scenarios, from simple object detection to more complex tasks like 9 | instance segmentation and object tracking. They are also designed to run efficiently on a variety of hardware platforms, 10 | from CPUs to GPUs. Whether you are a seasoned machine learning practitioner or just getting started with YOLO, this 11 | directory provides a great starting point for your custom model development needs. 12 | 13 | To get started, simply browse through the models in this directory and find one that best suits your needs. Once you've 14 | selected a model, you can use the provided `*.yaml` file to train and deploy your custom YOLO model with ease. See full 15 | details at the Ultralytics [Docs](https://docs.ultralytics.com), and if you need help or have any questions, feel free 16 | to reach out to the Ultralytics team for support. So, don't wait, start creating your custom YOLO model now! 17 | 18 | ### Usage 19 | 20 | Model `*.yaml` files may be used directly in the Command Line Interface (CLI) with a `yolo` command: 21 | 22 | ```bash 23 | yolo task=detect mode=train model=yolov8n.yaml data=coco128.yaml epochs=100 24 | ``` 25 | 26 | They may also be used directly in a Python environment, and accepts the same 27 | [arguments](https://docs.ultralytics.com/config/) as in the CLI example above: 28 | 29 | ```python 30 | from ultralytics import YOLO 31 | 32 | model = YOLO("yolov8n.yaml") # build a YOLOv8n model from scratch 33 | 34 | model.info() # display model information 35 | model.train(data="coco128.yaml", epochs=100) # train the model 36 | ``` 37 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.yml: -------------------------------------------------------------------------------- 1 | name: 🚀 Feature Request 2 | description: Suggest a YOLOv8 idea 3 | # title: " " 4 | labels: [enhancement] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | Thank you for submitting a YOLOv8 🚀 Feature Request! 10 | 11 | - type: checkboxes 12 | attributes: 13 | label: Search before asking 14 | description: > 15 | Please search the [issues](https://github.com/ultralytics/ultralytics/issues) to see if a similar feature request already exists. 16 | options: 17 | - label: > 18 | I have searched the YOLOv8 [issues](https://github.com/ultralytics/ultralytics/issues) and found no similar feature requests. 19 | required: true 20 | 21 | - type: textarea 22 | attributes: 23 | label: Description 24 | description: A short description of your feature. 25 | placeholder: | 26 | What new feature would you like to see in YOLOv8? 27 | validations: 28 | required: true 29 | 30 | - type: textarea 31 | attributes: 32 | label: Use case 33 | description: | 34 | Describe the use case of your feature request. It will help us understand and prioritize the feature request. 35 | placeholder: | 36 | How would this feature be used, and who would use it? 37 | 38 | - type: textarea 39 | attributes: 40 | label: Additional 41 | description: Anything else you would like to share? 42 | 43 | - type: checkboxes 44 | attributes: 45 | label: Are you willing to submit a PR? 46 | description: > 47 | (Optional) We encourage you to submit a [Pull Request](https://github.com/ultralytics/ultralytics/pulls) (PR) to help improve YOLOv8 for everyone, especially if you have a good understanding of how to implement a fix or feature. 48 | See the YOLOv8 [Contributing Guide](https://github.com/ultralytics/ultralytics/blob/main/CONTRIBUTING.md) to get started. 49 | options: 50 | - label: Yes I'd like to help by submitting a PR! 51 | -------------------------------------------------------------------------------- /ultralytics/yolo/cli.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | import shutil 4 | from pathlib import Path 5 | 6 | import hydra 7 | 8 | from ultralytics import hub, yolo 9 | from ultralytics.yolo.configs import get_config 10 | from ultralytics.yolo.utils import DEFAULT_CONFIG, LOGGER, colorstr 11 | 12 | DIR = Path(__file__).parent 13 | 14 | 15 | @hydra.main(version_base=None, config_path=str(DEFAULT_CONFIG.parent.relative_to(DIR)), config_name=DEFAULT_CONFIG.name) 16 | def cli(cfg): 17 | """ 18 | Run a specified task and mode with the given configuration. 19 | 20 | Args: 21 | cfg (DictConfig): Configuration for the task and mode. 22 | """ 23 | # LOGGER.info(f"{colorstr(f'Ultralytics YOLO v{ultralytics.__version__}')}") 24 | if cfg.cfg: 25 | LOGGER.info(f"Overriding default config with {cfg.cfg}") 26 | cfg = get_config(cfg.cfg) 27 | task, mode = cfg.task.lower(), cfg.mode.lower() 28 | 29 | # Special case for initializing the configuration 30 | if task == "init": 31 | shutil.copy2(DEFAULT_CONFIG, Path.cwd()) 32 | LOGGER.info(f""" 33 | {colorstr("YOLO:")} configuration saved to {Path.cwd() / DEFAULT_CONFIG.name}. 34 | To run experiments using custom configuration: 35 | yolo cfg=config_file.yaml 36 | """) 37 | return 38 | 39 | # Mapping from task to module 40 | task_module_map = {"detect": yolo.v8.detect, "segment": yolo.v8.segment, "classify": yolo.v8.classify} 41 | module = task_module_map.get(task) 42 | if not module: 43 | raise SyntaxError(f"task not recognized. Choices are {', '.join(task_module_map.keys())}") 44 | 45 | # Mapping from mode to function 46 | mode_func_map = { 47 | "train": module.train, 48 | "val": module.val, 49 | "predict": module.predict, 50 | "export": yolo.engine.exporter.export, 51 | "checks": hub.checks} 52 | func = mode_func_map.get(mode) 53 | if not func: 54 | raise SyntaxError(f"mode not recognized. Choices are {', '.join(mode_func_map.keys())}") 55 | 56 | func(cfg) 57 | -------------------------------------------------------------------------------- /ultralytics/yolo/data/datasets/GlobalWheat2020.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | # Global Wheat 2020 dataset http://www.global-wheat.com/ by University of Saskatchewan 3 | # Example usage: python train.py --data GlobalWheat2020.yaml 4 | # parent 5 | # ├── yolov5 6 | # └── datasets 7 | # └── GlobalWheat2020 ← downloads here (7.0 GB) 8 | 9 | 10 | # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] 11 | path: ../datasets/GlobalWheat2020 # dataset root dir 12 | train: # train images (relative to 'path') 3422 images 13 | - images/arvalis_1 14 | - images/arvalis_2 15 | - images/arvalis_3 16 | - images/ethz_1 17 | - images/rres_1 18 | - images/inrae_1 19 | - images/usask_1 20 | val: # val images (relative to 'path') 748 images (WARNING: train set contains ethz_1) 21 | - images/ethz_1 22 | test: # test images (optional) 1276 images 23 | - images/utokyo_1 24 | - images/utokyo_2 25 | - images/nau_1 26 | - images/uq_1 27 | 28 | # Classes 29 | names: 30 | 0: wheat_head 31 | 32 | 33 | # Download script/URL (optional) --------------------------------------------------------------------------------------- 34 | download: | 35 | from utils.general import download, Path 36 | 37 | 38 | # Download 39 | dir = Path(yaml['path']) # dataset root dir 40 | urls = ['https://zenodo.org/record/4298502/files/global-wheat-codalab-official.zip', 41 | 'https://github.com/ultralytics/yolov5/releases/download/v1.0/GlobalWheat2020_labels.zip'] 42 | download(urls, dir=dir) 43 | 44 | # Make Directories 45 | for p in 'annotations', 'images', 'labels': 46 | (dir / p).mkdir(parents=True, exist_ok=True) 47 | 48 | # Move 49 | for p in 'arvalis_1', 'arvalis_2', 'arvalis_3', 'ethz_1', 'rres_1', 'inrae_1', 'usask_1', \ 50 | 'utokyo_1', 'utokyo_2', 'nau_1', 'uq_1': 51 | (dir / p).rename(dir / 'images' / p) # move to /images 52 | f = (dir / p).with_suffix('.json') # json file 53 | if f.exists(): 54 | f.rename((dir / 'annotations' / p).with_suffix('.json')) # move to /annotations 55 | -------------------------------------------------------------------------------- /ultralytics/yolo/utils/callbacks/clearml.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | from ultralytics.yolo.utils.torch_utils import get_flops, get_num_params 4 | 5 | try: 6 | import clearml 7 | from clearml import Task 8 | 9 | assert hasattr(clearml, '__version__') 10 | except (ImportError, AssertionError): 11 | clearml = None 12 | 13 | 14 | def _log_images(imgs_dict, group="", step=0): 15 | task = Task.current_task() 16 | if task: 17 | for k, v in imgs_dict.items(): 18 | task.get_logger().report_image(group, k, step, v) 19 | 20 | 21 | def on_pretrain_routine_start(trainer): 22 | # TODO: reuse existing task 23 | task = Task.init(project_name=trainer.args.project or "YOLOv8", 24 | task_name=trainer.args.name, 25 | tags=['YOLOv8'], 26 | output_uri=True, 27 | reuse_last_task_id=False, 28 | auto_connect_frameworks={'pytorch': False}) 29 | task.connect(dict(trainer.args), name='General') 30 | 31 | 32 | def on_train_epoch_end(trainer): 33 | if trainer.epoch == 1: 34 | _log_images({f.stem: str(f) for f in trainer.save_dir.glob('train_batch*.jpg')}, "Mosaic", trainer.epoch) 35 | 36 | 37 | def on_fit_epoch_end(trainer): 38 | if trainer.epoch == 0: 39 | model_info = { 40 | "Parameters": get_num_params(trainer.model), 41 | "GFLOPs": round(get_flops(trainer.model), 3), 42 | "Inference speed (ms/img)": round(trainer.validator.speed[1], 3)} 43 | Task.current_task().connect(model_info, name='Model') 44 | 45 | 46 | def on_train_end(trainer): 47 | Task.current_task().update_output_model(model_path=str(trainer.best), 48 | model_name=trainer.args.name, 49 | auto_delete_file=False) 50 | 51 | 52 | callbacks = { 53 | "on_pretrain_routine_start": on_pretrain_routine_start, 54 | "on_train_epoch_end": on_train_epoch_end, 55 | "on_fit_epoch_end": on_fit_epoch_end, 56 | "on_train_end": on_train_end} if clearml else {} 57 | -------------------------------------------------------------------------------- /tests/test_cli.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | import os 4 | from pathlib import Path 5 | 6 | from ultralytics.yolo.utils import ROOT, SETTINGS 7 | 8 | MODEL = Path(SETTINGS['weights_dir']) / 'yolov8n' 9 | CFG = 'yolov8n' 10 | 11 | 12 | def test_checks(): 13 | os.system('yolo mode=checks') 14 | 15 | 16 | # Train checks --------------------------------------------------------------------------------------------------------- 17 | def test_train_det(): 18 | os.system(f'yolo mode=train task=detect model={CFG}.yaml data=coco128.yaml imgsz=32 epochs=1') 19 | 20 | 21 | def test_train_seg(): 22 | os.system(f'yolo mode=train task=segment model={CFG}-seg.yaml data=coco128-seg.yaml imgsz=32 epochs=1') 23 | 24 | 25 | def test_train_cls(): 26 | os.system(f'yolo mode=train task=classify model={CFG}-cls.yaml data=mnist160 imgsz=32 epochs=1') 27 | 28 | 29 | # Val checks ----------------------------------------------------------------------------------------------------------- 30 | def test_val_detect(): 31 | os.system(f'yolo mode=val task=detect model={MODEL}.pt data=coco128.yaml imgsz=32 epochs=1') 32 | 33 | 34 | def test_val_segment(): 35 | os.system(f'yolo mode=val task=segment model={MODEL}-seg.pt data=coco128-seg.yaml imgsz=32 epochs=1') 36 | 37 | 38 | def test_val_classify(): 39 | pass 40 | 41 | 42 | # Predict checks ------------------------------------------------------------------------------------------------------- 43 | def test_predict_detect(): 44 | os.system(f"yolo mode=predict model={MODEL}.pt source={ROOT / 'assets'}") 45 | 46 | 47 | def test_predict_segment(): 48 | os.system(f"yolo mode=predict model={MODEL}-seg.pt source={ROOT / 'assets'}") 49 | 50 | 51 | def test_predict_classify(): 52 | pass 53 | 54 | 55 | # Export checks -------------------------------------------------------------------------------------------------------- 56 | def test_export_detect_torchscript(): 57 | os.system(f'yolo mode=export model={MODEL}.pt format=torchscript') 58 | 59 | 60 | def test_export_segment_torchscript(): 61 | os.system(f'yolo mode=export model={MODEL}-seg.pt format=torchscript') 62 | 63 | 64 | def test_export_classify_torchscript(): 65 | pass 66 | -------------------------------------------------------------------------------- /ultralytics/yolo/v8/classify/val.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | import hydra 4 | 5 | from ultralytics.yolo.data import build_classification_dataloader 6 | from ultralytics.yolo.engine.validator import BaseValidator 7 | from ultralytics.yolo.utils import DEFAULT_CONFIG 8 | from ultralytics.yolo.utils.metrics import ClassifyMetrics 9 | 10 | 11 | class ClassificationValidator(BaseValidator): 12 | 13 | def __init__(self, dataloader=None, save_dir=None, pbar=None, logger=None, args=None): 14 | super().__init__(dataloader, save_dir, pbar, logger, args) 15 | self.metrics = ClassifyMetrics() 16 | 17 | def get_desc(self): 18 | return ('%22s' + '%11s' * 2) % ('classes', 'top1_acc', 'top5_acc') 19 | 20 | def init_metrics(self, model): 21 | self.pred = [] 22 | self.targets = [] 23 | 24 | def preprocess(self, batch): 25 | batch["img"] = batch["img"].to(self.device, non_blocking=True) 26 | batch["img"] = batch["img"].half() if self.args.half else batch["img"].float() 27 | batch["cls"] = batch["cls"].to(self.device) 28 | return batch 29 | 30 | def update_metrics(self, preds, batch): 31 | self.pred.append(preds.argsort(1, descending=True)[:, :5]) 32 | self.targets.append(batch["cls"]) 33 | 34 | def get_stats(self): 35 | self.metrics.process(self.targets, self.pred) 36 | return self.metrics.results_dict 37 | 38 | def get_dataloader(self, dataset_path, batch_size): 39 | return build_classification_dataloader(path=dataset_path, 40 | imgsz=self.args.imgsz, 41 | batch_size=batch_size, 42 | workers=self.args.workers) 43 | 44 | def print_results(self): 45 | pf = '%22s' + '%11.3g' * len(self.metrics.keys) # print format 46 | self.logger.info(pf % ("all", self.metrics.top1, self.metrics.top5)) 47 | 48 | 49 | @hydra.main(version_base=None, config_path=str(DEFAULT_CONFIG.parent), config_name=DEFAULT_CONFIG.name) 50 | def val(cfg): 51 | cfg.data = cfg.data or "imagenette160" 52 | cfg.model = cfg.model or "resnet18" 53 | validator = ClassificationValidator(args=cfg) 54 | validator(model=cfg.model) 55 | 56 | 57 | if __name__ == "__main__": 58 | val() 59 | -------------------------------------------------------------------------------- /ultralytics/yolo/utils/loss.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | import torch 4 | import torch.nn as nn 5 | import torch.nn.functional as F 6 | 7 | from .metrics import bbox_iou 8 | from .tal import bbox2dist 9 | 10 | 11 | class VarifocalLoss(nn.Module): 12 | # Varifocal loss by Zhang et al. https://arxiv.org/abs/2008.13367 13 | def __init__(self): 14 | super().__init__() 15 | 16 | def forward(self, pred_score, gt_score, label, alpha=0.75, gamma=2.0): 17 | weight = alpha * pred_score.sigmoid().pow(gamma) * (1 - label) + gt_score * label 18 | with torch.cuda.amp.autocast(enabled=False): 19 | loss = (F.binary_cross_entropy_with_logits(pred_score.float(), gt_score.float(), reduction="none") * 20 | weight).sum() 21 | return loss 22 | 23 | 24 | class BboxLoss(nn.Module): 25 | 26 | def __init__(self, reg_max, use_dfl=False): 27 | super().__init__() 28 | self.reg_max = reg_max 29 | self.use_dfl = use_dfl 30 | 31 | def forward(self, pred_dist, pred_bboxes, anchor_points, target_bboxes, target_scores, target_scores_sum, fg_mask): 32 | # IoU loss 33 | weight = torch.masked_select(target_scores.sum(-1), fg_mask).unsqueeze(-1) 34 | iou = bbox_iou(pred_bboxes[fg_mask], target_bboxes[fg_mask], xywh=False, CIoU=True) 35 | loss_iou = ((1.0 - iou) * weight).sum() / target_scores_sum 36 | 37 | # DFL loss 38 | if self.use_dfl: 39 | target_ltrb = bbox2dist(anchor_points, target_bboxes, self.reg_max) 40 | loss_dfl = self._df_loss(pred_dist[fg_mask].view(-1, self.reg_max + 1), target_ltrb[fg_mask]) * weight 41 | loss_dfl = loss_dfl.sum() / target_scores_sum 42 | else: 43 | loss_dfl = torch.tensor(0.0).to(pred_dist.device) 44 | 45 | return loss_iou, loss_dfl 46 | 47 | @staticmethod 48 | def _df_loss(pred_dist, target): 49 | # Return sum of left and right DFL losses 50 | tl = target.long() # target left 51 | tr = tl + 1 # target right 52 | wl = tr - target # weight left 53 | wr = 1 - wl # weight right 54 | return (F.cross_entropy(pred_dist, tl.view(-1), reduction="none").view(tl.shape) * wl + 55 | F.cross_entropy(pred_dist, tr.view(-1), reduction="none").view(tl.shape) * wr).mean(-1, keepdim=True) 56 | -------------------------------------------------------------------------------- /ultralytics/yolo/data/datasets/coco128.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | # COCO128 dataset https://www.kaggle.com/ultralytics/coco128 (first 128 images from COCO train2017) by Ultralytics 3 | # Example usage: python train.py --data coco128.yaml 4 | # parent 5 | # ├── yolov5 6 | # └── datasets 7 | # └── coco128 ← downloads here (7 MB) 8 | 9 | 10 | # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] 11 | path: ../datasets/coco128 # dataset root dir 12 | train: images/train2017 # train images (relative to 'path') 128 images 13 | val: images/train2017 # val images (relative to 'path') 128 images 14 | test: # test images (optional) 15 | 16 | # Classes 17 | names: 18 | 0: person 19 | 1: bicycle 20 | 2: car 21 | 3: motorcycle 22 | 4: airplane 23 | 5: bus 24 | 6: train 25 | 7: truck 26 | 8: boat 27 | 9: traffic light 28 | 10: fire hydrant 29 | 11: stop sign 30 | 12: parking meter 31 | 13: bench 32 | 14: bird 33 | 15: cat 34 | 16: dog 35 | 17: horse 36 | 18: sheep 37 | 19: cow 38 | 20: elephant 39 | 21: bear 40 | 22: zebra 41 | 23: giraffe 42 | 24: backpack 43 | 25: umbrella 44 | 26: handbag 45 | 27: tie 46 | 28: suitcase 47 | 29: frisbee 48 | 30: skis 49 | 31: snowboard 50 | 32: sports ball 51 | 33: kite 52 | 34: baseball bat 53 | 35: baseball glove 54 | 36: skateboard 55 | 37: surfboard 56 | 38: tennis racket 57 | 39: bottle 58 | 40: wine glass 59 | 41: cup 60 | 42: fork 61 | 43: knife 62 | 44: spoon 63 | 45: bowl 64 | 46: banana 65 | 47: apple 66 | 48: sandwich 67 | 49: orange 68 | 50: broccoli 69 | 51: carrot 70 | 52: hot dog 71 | 53: pizza 72 | 54: donut 73 | 55: cake 74 | 56: chair 75 | 57: couch 76 | 58: potted plant 77 | 59: bed 78 | 60: dining table 79 | 61: toilet 80 | 62: tv 81 | 63: laptop 82 | 64: mouse 83 | 65: remote 84 | 66: keyboard 85 | 67: cell phone 86 | 68: microwave 87 | 69: oven 88 | 70: toaster 89 | 71: sink 90 | 72: refrigerator 91 | 73: book 92 | 74: clock 93 | 75: vase 94 | 76: scissors 95 | 77: teddy bear 96 | 78: hair drier 97 | 79: toothbrush 98 | 99 | 100 | # Download script/URL (optional) 101 | download: https://ultralytics.com/assets/coco128.zip -------------------------------------------------------------------------------- /ultralytics/yolo/data/datasets/coco128-seg.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | # COCO128-seg dataset https://www.kaggle.com/ultralytics/coco128 (first 128 images from COCO train2017) by Ultralytics 3 | # Example usage: python train.py --data coco128.yaml 4 | # parent 5 | # ├── yolov5 6 | # └── datasets 7 | # └── coco128-seg ← downloads here (7 MB) 8 | 9 | 10 | # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] 11 | path: ../datasets/coco128-seg # dataset root dir 12 | train: images/train2017 # train images (relative to 'path') 128 images 13 | val: images/train2017 # val images (relative to 'path') 128 images 14 | test: # test images (optional) 15 | 16 | # Classes 17 | names: 18 | 0: person 19 | 1: bicycle 20 | 2: car 21 | 3: motorcycle 22 | 4: airplane 23 | 5: bus 24 | 6: train 25 | 7: truck 26 | 8: boat 27 | 9: traffic light 28 | 10: fire hydrant 29 | 11: stop sign 30 | 12: parking meter 31 | 13: bench 32 | 14: bird 33 | 15: cat 34 | 16: dog 35 | 17: horse 36 | 18: sheep 37 | 19: cow 38 | 20: elephant 39 | 21: bear 40 | 22: zebra 41 | 23: giraffe 42 | 24: backpack 43 | 25: umbrella 44 | 26: handbag 45 | 27: tie 46 | 28: suitcase 47 | 29: frisbee 48 | 30: skis 49 | 31: snowboard 50 | 32: sports ball 51 | 33: kite 52 | 34: baseball bat 53 | 35: baseball glove 54 | 36: skateboard 55 | 37: surfboard 56 | 38: tennis racket 57 | 39: bottle 58 | 40: wine glass 59 | 41: cup 60 | 42: fork 61 | 43: knife 62 | 44: spoon 63 | 45: bowl 64 | 46: banana 65 | 47: apple 66 | 48: sandwich 67 | 49: orange 68 | 50: broccoli 69 | 51: carrot 70 | 52: hot dog 71 | 53: pizza 72 | 54: donut 73 | 55: cake 74 | 56: chair 75 | 57: couch 76 | 58: potted plant 77 | 59: bed 78 | 60: dining table 79 | 61: toilet 80 | 62: tv 81 | 63: laptop 82 | 64: mouse 83 | 65: remote 84 | 66: keyboard 85 | 67: cell phone 86 | 68: microwave 87 | 69: oven 88 | 70: toaster 89 | 71: sink 90 | 72: refrigerator 91 | 73: book 92 | 74: clock 93 | 75: vase 94 | 76: scissors 95 | 77: teddy bear 96 | 78: hair drier 97 | 79: toothbrush 98 | 99 | 100 | # Download script/URL (optional) 101 | download: https://ultralytics.com/assets/coco128-seg.zip -------------------------------------------------------------------------------- /ultralytics/yolo/data/datasets/SKU-110K.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | # SKU-110K retail items dataset https://github.com/eg4000/SKU110K_CVPR19 by Trax Retail 3 | # Example usage: python train.py --data SKU-110K.yaml 4 | # parent 5 | # ├── yolov5 6 | # └── datasets 7 | # └── SKU-110K ← downloads here (13.6 GB) 8 | 9 | 10 | # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] 11 | path: ../datasets/SKU-110K # dataset root dir 12 | train: train.txt # train images (relative to 'path') 8219 images 13 | val: val.txt # val images (relative to 'path') 588 images 14 | test: test.txt # test images (optional) 2936 images 15 | 16 | # Classes 17 | names: 18 | 0: object 19 | 20 | 21 | # Download script/URL (optional) --------------------------------------------------------------------------------------- 22 | download: | 23 | import shutil 24 | from tqdm import tqdm 25 | from utils.general import np, pd, Path, download, xyxy2xywh 26 | 27 | 28 | # Download 29 | dir = Path(yaml['path']) # dataset root dir 30 | parent = Path(dir.parent) # download dir 31 | urls = ['http://trax-geometry.s3.amazonaws.com/cvpr_challenge/SKU110K_fixed.tar.gz'] 32 | download(urls, dir=parent, delete=False) 33 | 34 | # Rename directories 35 | if dir.exists(): 36 | shutil.rmtree(dir) 37 | (parent / 'SKU110K_fixed').rename(dir) # rename dir 38 | (dir / 'labels').mkdir(parents=True, exist_ok=True) # create labels dir 39 | 40 | # Convert labels 41 | names = 'image', 'x1', 'y1', 'x2', 'y2', 'class', 'image_width', 'image_height' # column names 42 | for d in 'annotations_train.csv', 'annotations_val.csv', 'annotations_test.csv': 43 | x = pd.read_csv(dir / 'annotations' / d, names=names).values # annotations 44 | images, unique_images = x[:, 0], np.unique(x[:, 0]) 45 | with open((dir / d).with_suffix('.txt').__str__().replace('annotations_', ''), 'w') as f: 46 | f.writelines(f'./images/{s}\n' for s in unique_images) 47 | for im in tqdm(unique_images, desc=f'Converting {dir / d}'): 48 | cls = 0 # single-class dataset 49 | with open((dir / 'labels' / im).with_suffix('.txt'), 'a') as f: 50 | for r in x[images == im]: 51 | w, h = r[6], r[7] # image width, height 52 | xywh = xyxy2xywh(np.array([[r[1] / w, r[2] / h, r[3] / w, r[4] / h]]))[0] # instance 53 | f.write(f"{cls} {xywh[0]:.5f} {xywh[1]:.5f} {xywh[2]:.5f} {xywh[3]:.5f}\n") # write label 54 | -------------------------------------------------------------------------------- /ultralytics/yolo/utils/dist.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | import os 4 | import shutil 5 | import socket 6 | import sys 7 | import tempfile 8 | 9 | from . import USER_CONFIG_DIR 10 | 11 | 12 | def find_free_network_port() -> int: 13 | # https://github.com/Lightning-AI/lightning/blob/master/src/lightning_lite/plugins/environments/lightning.py 14 | """Finds a free port on localhost. 15 | 16 | It is useful in single-node training when we don't want to connect to a real main node but have to set the 17 | `MASTER_PORT` environment variable. 18 | """ 19 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 20 | s.bind(("", 0)) 21 | port = s.getsockname()[1] 22 | s.close() 23 | return port 24 | 25 | 26 | def generate_ddp_file(trainer): 27 | import_path = '.'.join(str(trainer.__class__).split(".")[1:-1]) 28 | 29 | if not trainer.resume: 30 | shutil.rmtree(trainer.save_dir) # remove the save_dir 31 | content = f'''config = {dict(trainer.args)} \nif __name__ == "__main__": 32 | from ultralytics.{import_path} import {trainer.__class__.__name__} 33 | 34 | trainer = {trainer.__class__.__name__}(config=config) 35 | trainer.train()''' 36 | (USER_CONFIG_DIR / 'DDP').mkdir(exist_ok=True) 37 | with tempfile.NamedTemporaryFile(prefix="_temp_", 38 | suffix=f"{id(trainer)}.py", 39 | mode="w+", 40 | encoding='utf-8', 41 | dir=USER_CONFIG_DIR / 'DDP', 42 | delete=False) as file: 43 | file.write(content) 44 | return file.name 45 | 46 | 47 | def generate_ddp_command(world_size, trainer): 48 | import __main__ # noqa local import to avoid https://github.com/Lightning-AI/lightning/issues/15218 49 | file_name = os.path.abspath(sys.argv[0]) 50 | using_cli = not file_name.endswith(".py") 51 | if using_cli: 52 | file_name = generate_ddp_file(trainer) 53 | return [ 54 | sys.executable, "-m", "torch.distributed.run", "--nproc_per_node", f"{world_size}", "--master_port", 55 | f"{find_free_network_port()}", file_name] + sys.argv[1:] 56 | 57 | 58 | def ddp_cleanup(command, trainer): 59 | # delete temp file if created 60 | tempfile_suffix = f"{id(trainer)}.py" 61 | if tempfile_suffix in "".join(command): 62 | for chunk in command: 63 | if tempfile_suffix in chunk: 64 | os.remove(chunk) 65 | break 66 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | import re 4 | from pathlib import Path 5 | 6 | import pkg_resources as pkg 7 | from setuptools import find_packages, setup 8 | 9 | # Settings 10 | FILE = Path(__file__).resolve() 11 | ROOT = FILE.parent # root directory 12 | README = (ROOT / "README.md").read_text(encoding="utf-8") 13 | REQUIREMENTS = [f'{x.name}{x.specifier}' for x in pkg.parse_requirements((ROOT / 'requirements.txt').read_text())] 14 | 15 | 16 | def get_version(): 17 | file = ROOT / 'ultralytics/__init__.py' 18 | return re.search(r'^__version__ = [\'"]([^\'"]*)[\'"]', file.read_text(), re.M)[1] 19 | 20 | 21 | setup( 22 | name="ultralytics", # name of pypi package 23 | version=get_version(), # version of pypi package 24 | python_requires=">=3.7.0", 25 | license='GPL-3.0', 26 | description='Ultralytics YOLOv8 and HUB', 27 | long_description=README, 28 | long_description_content_type="text/markdown", 29 | url="https://github.com/ultralytics/ultralytics", 30 | project_urls={ 31 | 'Bug Reports': 'https://github.com/ultralytics/ultralytics/issues', 32 | 'Funding': 'https://ultralytics.com', 33 | 'Source': 'https://github.com/ultralytics/ultralytics',}, 34 | author="Ultralytics", 35 | author_email='hello@ultralytics.com', 36 | packages=find_packages(), # required 37 | include_package_data=True, 38 | install_requires=REQUIREMENTS, 39 | extras_require={ 40 | 'dev': 41 | ['check-manifest', 'pytest', 'pytest-cov', 'coverage', 'mkdocs', 'mkdocstrings[python]', 'mkdocs-material'],}, 42 | classifiers=[ 43 | "Intended Audience :: Developers", "Intended Audience :: Science/Research", 44 | "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", "Programming Language :: Python :: 3", 45 | "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", 46 | "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", 47 | "Topic :: Software Development", "Topic :: Scientific/Engineering", 48 | "Topic :: Scientific/Engineering :: Artificial Intelligence", 49 | "Topic :: Scientific/Engineering :: Image Recognition", "Operating System :: POSIX :: Linux", 50 | "Operating System :: MacOS", "Operating System :: Microsoft :: Windows"], 51 | keywords="machine-learning, deep-learning, vision, ML, DL, AI, YOLO, YOLOv3, YOLOv5, YOLOv8, HUB, Ultralytics", 52 | entry_points={ 53 | 'console_scripts': ['yolo = ultralytics.yolo.cli:cli', 'ultralytics = ultralytics.yolo.cli:cli'],}) 54 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: Ultralytics Docs 2 | repo_url: https://github.com/ultralytics/ultralytics 3 | edit_uri: https://github.com/ultralytics/ultralytics/tree/main/docs 4 | repo_name: ultralytics/ultralytics 5 | 6 | theme: 7 | name: "material" 8 | logo: https://github.com/ultralytics/assets/raw/main/logo/Ultralytics-logomark-white.png 9 | favicon: assets/favicon.ico 10 | font: 11 | text: Roboto 12 | 13 | palette: 14 | # Palette toggle for light mode 15 | - scheme: default 16 | # primary: grey 17 | toggle: 18 | icon: material/brightness-7 19 | name: Switch to dark mode 20 | 21 | # Palette toggle for dark mode 22 | - scheme: slate 23 | # primary: black 24 | toggle: 25 | icon: material/brightness-4 26 | name: Switch to light mode 27 | features: 28 | - content.action.edit 29 | - content.code.annotate 30 | - content.tooltips 31 | - search.highlight 32 | - search.share 33 | - search.suggest 34 | - toc.follow 35 | - navigation.top 36 | - navigation.expand 37 | - navigation.footer 38 | - content.tabs.link # all code tabs change simultaneously 39 | 40 | extra_css: 41 | - stylesheets/style.css 42 | 43 | markdown_extensions: 44 | # Div text decorators 45 | - admonition 46 | - pymdownx.details 47 | - pymdownx.superfences 48 | - tables 49 | - attr_list 50 | - def_list 51 | # Syntax highlight 52 | - pymdownx.highlight: 53 | anchor_linenums: true 54 | - pymdownx.inlinehilite 55 | - pymdownx.snippets 56 | 57 | # Button 58 | - attr_list 59 | 60 | # Content tabs 61 | - pymdownx.superfences 62 | - pymdownx.tabbed: 63 | alternate_style: true 64 | 65 | # Highlight 66 | - pymdownx.critic 67 | - pymdownx.caret 68 | - pymdownx.keys 69 | - pymdownx.mark 70 | - pymdownx.tilde 71 | 72 | plugins: 73 | - mkdocstrings 74 | - search 75 | 76 | # Primary navigation 77 | nav: 78 | - Quickstart: quickstart.md 79 | - Tasks: 80 | - Detection: tasks/detection.md 81 | - Segmentation: tasks/segmentation.md 82 | - Classification: tasks/classification.md 83 | - Usage: 84 | - CLI: cli.md 85 | - Python: python.md 86 | - Configuration: config.md 87 | - Customization Guide: engine.md 88 | - Ultralytics HUB: hub.md 89 | - iOS and Android App: app.md 90 | - Reference: 91 | - Python Model interface: reference/model.md 92 | - Engine: 93 | - Trainer: reference/base_trainer.md 94 | - Validator: reference/base_val.md 95 | - Predictor: reference/base_pred.md 96 | - Exporter: reference/exporter.md 97 | - nn Module: reference/nn.md 98 | - operations: reference/ops.md 99 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | # Builds ultralytics/ultralytics:latest image on DockerHub https://hub.docker.com/r/ultralytics/ultralytics 3 | # Image is CUDA-optimized for YOLOv8 single/multi-GPU training and inference 4 | 5 | # Start FROM NVIDIA PyTorch image https://ngc.nvidia.com/catalog/containers/nvidia:pytorch 6 | FROM nvcr.io/nvidia/pytorch:22.12-py3 7 | RUN rm -rf /opt/pytorch # remove 1.2GB dir 8 | 9 | # Downloads to user config dir 10 | ADD https://ultralytics.com/assets/Arial.ttf https://ultralytics.com/assets/Arial.Unicode.ttf /root/.config/Ultralytics/ 11 | 12 | # Install linux packages 13 | RUN apt update && apt install --no-install-recommends -y zip htop screen libgl1-mesa-glx 14 | 15 | # Create working directory 16 | RUN mkdir -p /usr/src/ultralytics 17 | WORKDIR /usr/src/ultralytics 18 | 19 | # Copy contents 20 | # COPY . /usr/src/app (issues as not a .git directory) 21 | RUN git clone https://github.com/ultralytics/ultralytics /usr/src/ultralytics 22 | 23 | # Install pip packages 24 | RUN python -m pip install --upgrade pip wheel 25 | RUN pip uninstall -y Pillow torchtext torch torchvision 26 | RUN pip install --no-cache ultralytics albumentations comet gsutil notebook Pillow>=9.1.0 \ 27 | 'opencv-python<4.6.0.66' \ 28 | --extra-index-url https://download.pytorch.org/whl/cu113 29 | 30 | # Set environment variables 31 | ENV OMP_NUM_THREADS=1 32 | 33 | 34 | # Usage Examples ------------------------------------------------------------------------------------------------------- 35 | 36 | # Build and Push 37 | # t=ultralytics/ultralytics:latest && sudo docker build -f utils/docker/Dockerfile -t $t . && sudo docker push $t 38 | 39 | # Pull and Run 40 | # t=ultralytics/ultralytics:latest && sudo docker pull $t && sudo docker run -it --ipc=host --gpus all $t 41 | 42 | # Pull and Run with local directory access 43 | # t=ultralytics/ultralytics:latest && sudo docker pull $t && sudo docker run -it --ipc=host --gpus all -v "$(pwd)"/datasets:/usr/src/datasets $t 44 | 45 | # Kill all 46 | # sudo docker kill $(sudo docker ps -q) 47 | 48 | # Kill all image-based 49 | # sudo docker kill $(sudo docker ps -qa --filter ancestor=ultralytics/ultralytics:latest) 50 | 51 | # DockerHub tag update 52 | # t=ultralytics/ultralytics:latest tnew=ultralytics/ultralytics:v6.2 && sudo docker pull $t && sudo docker tag $t $tnew && sudo docker push $tnew 53 | 54 | # Clean up 55 | # docker system prune -a --volumes 56 | 57 | # Update Ubuntu drivers 58 | # https://www.maketecheasier.com/install-nvidia-drivers-ubuntu/ 59 | 60 | # DDP test 61 | # python -m torch.distributed.run --nproc_per_node 2 --master_port 1 train.py --epochs 3 62 | 63 | # GCP VM from Image 64 | # docker.io/ultralytics/ultralytics:latest 65 | -------------------------------------------------------------------------------- /ultralytics/hub/auth.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | import requests 4 | 5 | from ultralytics.hub.utils import HUB_API_ROOT, request_with_credentials 6 | from ultralytics.yolo.utils import is_colab 7 | 8 | API_KEY_PATH = "https://hub.ultralytics.com/settings?tab=api+keys" 9 | 10 | 11 | class Auth: 12 | id_token = api_key = model_key = False 13 | 14 | def __init__(self, api_key=None): 15 | self.api_key = self._clean_api_key(api_key) 16 | self.authenticate() if self.api_key else self.auth_with_cookies() 17 | 18 | @staticmethod 19 | def _clean_api_key(key: str) -> str: 20 | """Strip model from key if present""" 21 | separator = "_" 22 | return key.split(separator)[0] if separator in key else key 23 | 24 | def authenticate(self) -> bool: 25 | """Attempt to authenticate with server""" 26 | try: 27 | header = self.get_auth_header() 28 | if header: 29 | r = requests.post(f"{HUB_API_ROOT}/v1/auth", headers=header) 30 | if not r.json().get('success', False): 31 | raise ConnectionError("Unable to authenticate.") 32 | return True 33 | raise ConnectionError("User has not authenticated locally.") 34 | except ConnectionError: 35 | self.id_token = self.api_key = False # reset invalid 36 | return False 37 | 38 | def auth_with_cookies(self) -> bool: 39 | """ 40 | Attempt to fetch authentication via cookies and set id_token. 41 | User must be logged in to HUB and running in a supported browser. 42 | """ 43 | if not is_colab(): 44 | return False # Currently only works with Colab 45 | try: 46 | authn = request_with_credentials(f"{HUB_API_ROOT}/v1/auth/auto") 47 | if authn.get("success", False): 48 | self.id_token = authn.get("data", {}).get("idToken", None) 49 | self.authenticate() 50 | return True 51 | raise ConnectionError("Unable to fetch browser authentication details.") 52 | except ConnectionError: 53 | self.id_token = False # reset invalid 54 | return False 55 | 56 | def get_auth_header(self): 57 | if self.id_token: 58 | return {"authorization": f"Bearer {self.id_token}"} 59 | elif self.api_key: 60 | return {"x-api-key": self.api_key} 61 | else: 62 | return None 63 | 64 | def get_state(self) -> bool: 65 | """Get the authentication state""" 66 | return self.id_token or self.api_key 67 | 68 | def set_api_key(self, key: str): 69 | """Get the authentication state""" 70 | self.api_key = key 71 | -------------------------------------------------------------------------------- /ultralytics/yolo/v8/classify/predict.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | import hydra 4 | import torch 5 | 6 | from ultralytics.yolo.engine.predictor import BasePredictor 7 | from ultralytics.yolo.utils import DEFAULT_CONFIG, ROOT 8 | from ultralytics.yolo.utils.checks import check_imgsz 9 | from ultralytics.yolo.utils.plotting import Annotator 10 | 11 | 12 | class ClassificationPredictor(BasePredictor): 13 | 14 | def get_annotator(self, img): 15 | return Annotator(img, example=str(self.model.names), pil=True) 16 | 17 | def preprocess(self, img): 18 | img = torch.Tensor(img).to(self.model.device) 19 | img = img.half() if self.model.fp16 else img.float() # uint8 to fp16/32 20 | return img 21 | 22 | def write_results(self, idx, preds, batch): 23 | p, im, im0 = batch 24 | log_string = "" 25 | if len(im.shape) == 3: 26 | im = im[None] # expand for batch dim 27 | self.seen += 1 28 | im0 = im0.copy() 29 | if self.webcam: # batch_size >= 1 30 | log_string += f'{idx}: ' 31 | frame = self.dataset.cound 32 | else: 33 | frame = getattr(self.dataset, 'frame', 0) 34 | 35 | self.data_path = p 36 | # save_path = str(self.save_dir / p.name) # im.jpg 37 | self.txt_path = str(self.save_dir / 'labels' / p.stem) + ('' if self.dataset.mode == 'image' else f'_{frame}') 38 | log_string += '%gx%g ' % im.shape[2:] # print string 39 | self.annotator = self.get_annotator(im0) 40 | 41 | prob = preds[idx].softmax(0) 42 | if self.return_outputs: 43 | self.output["prob"] = prob.cpu().numpy() 44 | # Print results 45 | top5i = prob.argsort(0, descending=True)[:5].tolist() # top 5 indices 46 | log_string += f"{', '.join(f'{self.model.names[j]} {prob[j]:.2f}' for j in top5i)}, " 47 | 48 | # write 49 | text = '\n'.join(f'{prob[j]:.2f} {self.model.names[j]}' for j in top5i) 50 | if self.args.save or self.args.show: # Add bbox to image 51 | self.annotator.text((32, 32), text, txt_color=(255, 255, 255)) 52 | if self.args.save_txt: # Write to file 53 | with open(f'{self.txt_path}.txt', 'a') as f: 54 | f.write(text + '\n') 55 | 56 | return log_string 57 | 58 | 59 | @hydra.main(version_base=None, config_path=str(DEFAULT_CONFIG.parent), config_name=DEFAULT_CONFIG.name) 60 | def predict(cfg): 61 | cfg.model = cfg.model or "squeezenet1_0" 62 | cfg.imgsz = check_imgsz(cfg.imgsz, min_dim=2) # check image size 63 | cfg.source = cfg.source if cfg.source is not None else ROOT / "assets" 64 | 65 | predictor = ClassificationPredictor(cfg) 66 | predictor.predict_cli() 67 | 68 | 69 | if __name__ == "__main__": 70 | predict() 71 | -------------------------------------------------------------------------------- /docs/engine.md: -------------------------------------------------------------------------------- 1 | Both the Ultralytics YOLO command-line and python interfaces are simply a high-level abstraction on the base engine 2 | executors. Let's take a look at the Trainer engine. 3 | 4 | ## BaseTrainer 5 | 6 | BaseTrainer contains the generic boilerplate training routine. It can be customized for any task based over overidding 7 | the required functions or operations as long the as correct formats are followed. For example, you can support your own 8 | custom model and dataloder by just overriding these functions: 9 | 10 | * `get_model(cfg, weights)` - The function that builds the model to be trained 11 | * `get_dataloder()` - The function that builds the dataloder 12 | More details and source code can be found in [`BaseTrainer` Reference](reference/base_trainer.md) 13 | 14 | ## DetectionTrainer 15 | 16 | Here's how you can use the YOLOv8 `DetectionTrainer` and customize it. 17 | 18 | ```python 19 | from ultralytics.yolo.v8.detect import DetectionTrainer 20 | 21 | trainer = DetectionTrainer(overrides={...}) 22 | trainer.train() 23 | trained_model = trainer.best # get best model 24 | ``` 25 | 26 | ### Customizing the DetectionTrainer 27 | 28 | Let's customize the trainer **to train a custom detection model** that is not supported directly. You can do this by 29 | simply overloading the existing the `get_model` functionality: 30 | 31 | ```python 32 | from ultralytics.yolo.v8.detect import DetectionTrainer 33 | 34 | 35 | class CustomTrainer(DetectionTrainer): 36 | def get_model(self, cfg, weights): 37 | ... 38 | 39 | 40 | trainer = CustomTrainer(overrides={...}) 41 | trainer.train() 42 | ``` 43 | 44 | You now realize that you need to customize the trainer further to: 45 | 46 | * Customize the `loss function`. 47 | * Add `callback` that uploads model to your Google Drive after every 10 `epochs` 48 | Here's how you can do it: 49 | 50 | ```python 51 | from ultralytics.yolo.v8.detect import DetectionTrainer 52 | 53 | 54 | class CustomTrainer(DetectionTrainer): 55 | def get_model(self, cfg, weights): 56 | ... 57 | 58 | def criterion(self, preds, batch): 59 | # get ground truth 60 | imgs = batch["imgs"] 61 | bboxes = batch["bboxes"] 62 | ... 63 | return loss, loss_items # see Reference-> Trainer for details on the expected format 64 | 65 | 66 | # callback to upload model weights 67 | def log_model(trainer): 68 | last_weight_path = trainer.last 69 | ... 70 | 71 | 72 | trainer = CustomTrainer(overrides={...}) 73 | trainer.add_callback("on_train_epoch_end", log_model) # Adds to existing callback 74 | trainer.train() 75 | ``` 76 | 77 | To know more about Callback triggering events and entry point, checkout our Callbacks guide # TODO 78 | 79 | ## Other engine components 80 | 81 | There are other componenets that can be customized similarly like `Validators` and `Predictors` 82 | See Reference section for more information on these. 83 | 84 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | 131 | # datasets and projects 132 | datasets/ 133 | runs/ 134 | wandb/ 135 | 136 | .DS_Store 137 | 138 | # Neural Network weights ----------------------------------------------------------------------------------------------- 139 | *.weights 140 | *.pt 141 | *.pb 142 | *.onnx 143 | *.engine 144 | *.mlmodel 145 | *.torchscript 146 | *.tflite 147 | *.h5 148 | *_saved_model/ 149 | *_web_model/ 150 | *_openvino_model/ 151 | -------------------------------------------------------------------------------- /ultralytics/yolo/utils/callbacks/hub.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | import json 4 | from time import time 5 | 6 | import torch 7 | 8 | from ultralytics.hub.utils import PREFIX, sync_analytics 9 | from ultralytics.yolo.utils import LOGGER 10 | 11 | 12 | def on_pretrain_routine_end(trainer): 13 | session = getattr(trainer, 'hub_session', None) 14 | if session: 15 | # Start timer for upload rate limit 16 | LOGGER.info(f"{PREFIX}View model at https://hub.ultralytics.com/models/{session.model_id} 🚀") 17 | session.t = {'metrics': time(), 'ckpt': time()} # start timer on self.rate_limit 18 | 19 | 20 | def on_fit_epoch_end(trainer): 21 | session = getattr(trainer, 'hub_session', None) 22 | if session: 23 | session.metrics_queue[trainer.epoch] = json.dumps(trainer.metrics) # json string 24 | if time() - session.t['metrics'] > session.rate_limits['metrics']: 25 | session.upload_metrics() 26 | session.t['metrics'] = time() # reset timer 27 | session.metrics_queue = {} # reset queue 28 | 29 | 30 | def on_model_save(trainer): 31 | session = getattr(trainer, 'hub_session', None) 32 | if session: 33 | # Upload checkpoints with rate limiting 34 | is_best = trainer.best_fitness == trainer.fitness 35 | if time() - session.t['ckpt'] > session.rate_limits['ckpt']: 36 | LOGGER.info(f"{PREFIX}Uploading checkpoint {session.model_id}") 37 | session.upload_model(trainer.epoch, trainer.last, is_best) 38 | session.t['ckpt'] = time() # reset timer 39 | 40 | 41 | def on_train_end(trainer): 42 | session = getattr(trainer, 'hub_session', None) 43 | if session: 44 | # Upload final model and metrics with exponential standoff 45 | LOGGER.info(f"{PREFIX}Training completed successfully ✅\n" 46 | f"{PREFIX}Uploading final {session.model_id}") 47 | session.upload_model(trainer.epoch, trainer.best, map=trainer.metrics['metrics/mAP50-95(B)'], final=True) 48 | session.alive = False # stop heartbeats 49 | LOGGER.info(f"{PREFIX}View model at https://hub.ultralytics.com/models/{session.model_id} 🚀") 50 | 51 | 52 | def on_train_start(trainer): 53 | sync_analytics(trainer.args) 54 | 55 | 56 | def on_val_start(validator): 57 | sync_analytics(validator.args) 58 | 59 | 60 | def on_predict_start(predictor): 61 | sync_analytics(predictor.args) 62 | 63 | 64 | def on_export_start(exporter): 65 | sync_analytics(exporter.args) 66 | 67 | 68 | callbacks = { 69 | "on_pretrain_routine_end": on_pretrain_routine_end, 70 | "on_fit_epoch_end": on_fit_epoch_end, 71 | "on_model_save": on_model_save, 72 | "on_train_end": on_train_end, 73 | "on_train_start": on_train_start, 74 | "on_val_start": on_val_start, 75 | "on_predict_start": on_predict_start, 76 | "on_export_start": on_export_start} 77 | -------------------------------------------------------------------------------- /docs/quickstart.md: -------------------------------------------------------------------------------- 1 | ## Install 2 | 3 | Install YOLOv8 via the `ultralytics` pip package for the latest stable release or by cloning 4 | the [https://github.com/ultralytics/ultralytics](https://github.com/ultralytics/ultralytics) repository for the most 5 | up-to-date version. 6 | 7 | !!! example "Pip install method (recommended)" 8 | 9 | ```bash 10 | pip install ultralytics 11 | ``` 12 | 13 | !!! example "Git clone method (for development)" 14 | 15 | ```bash 16 | git clone https://github.com/ultralytics/ultralytics 17 | cd ultralytics 18 | pip install -e '.[dev]' 19 | ``` 20 | See contributing section to know more about contributing to the project 21 | 22 | ## Use with CLI 23 | 24 | The YOLO command line interface (CLI) lets you simply train, validate or infer models on various tasks and versions. 25 | CLI requires no customization or code. You can simply run all tasks from the terminal with the `yolo` command. 26 | 27 | !!! example 28 | 29 | === "Syntax" 30 | ```bash 31 | yolo task=detect mode=train model=yolov8n.yaml args... 32 | classify predict yolov8n-cls.yaml args... 33 | segment val yolov8n-seg.yaml args... 34 | export yolov8n.pt format=onnx args... 35 | ``` 36 | 37 | === "Example training" 38 | ```bash 39 | yolo task=detect mode=train model=yolov8n.pt data=coco128.yaml device=0 40 | ``` 41 | === "Example Multi-GPU training" 42 | ```bash 43 | yolo task=detect mode=train model=yolov8n.pt data=coco128.yaml device=\'0,1,2,3\' 44 | ``` 45 | 46 | [CLI Guide](cli.md){ .md-button .md-button--primary} 47 | 48 | ## Use with Python 49 | 50 | Python usage allows users to easily use YOLOv8 inside their Python projects. It provides functions for loading and 51 | running the model, as well as for processing the model's output. The interface is designed to be easy to use, so that 52 | users can quickly implement object detection in their projects. 53 | 54 | Overall, the Python interface is a useful tool for anyone looking to incorporate object detection, segmentation or 55 | classification into their Python projects using YOLOv8. 56 | 57 | !!! example 58 | 59 | ```python 60 | from ultralytics import YOLO 61 | 62 | # Load a model 63 | model = YOLO("yolov8n.yaml") # build a new model from scratch 64 | model = YOLO("yolov8n.pt") # load a pretrained model (recommended for training) 65 | 66 | # Use the model 67 | results = model.train(data="coco128.yaml", epochs=3) # train the model 68 | results = model.val() # evaluate model performance on the validation set 69 | results = model("https://ultralytics.com/images/bus.jpg") # predict on an image 70 | success = model.export(format="onnx") # export the model to ONNX format 71 | ``` 72 | 73 | [Python Guide](python.md){.md-button .md-button--primary} 74 | -------------------------------------------------------------------------------- /ultralytics/yolo/data/datasets/Argoverse.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | # Argoverse-HD dataset (ring-front-center camera) http://www.cs.cmu.edu/~mengtial/proj/streaming/ by Argo AI 3 | # Example usage: python train.py --data Argoverse.yaml 4 | # parent 5 | # ├── yolov5 6 | # └── datasets 7 | # └── Argoverse ← downloads here (31.3 GB) 8 | 9 | 10 | # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] 11 | path: ../datasets/Argoverse # dataset root dir 12 | train: Argoverse-1.1/images/train/ # train images (relative to 'path') 39384 images 13 | val: Argoverse-1.1/images/val/ # val images (relative to 'path') 15062 images 14 | test: Argoverse-1.1/images/test/ # test images (optional) https://eval.ai/web/challenges/challenge-page/800/overview 15 | 16 | # Classes 17 | names: 18 | 0: person 19 | 1: bicycle 20 | 2: car 21 | 3: motorcycle 22 | 4: bus 23 | 5: truck 24 | 6: traffic_light 25 | 7: stop_sign 26 | 27 | 28 | # Download script/URL (optional) --------------------------------------------------------------------------------------- 29 | download: | 30 | import json 31 | 32 | from tqdm import tqdm 33 | from utils.general import download, Path 34 | 35 | 36 | def argoverse2yolo(set): 37 | labels = {} 38 | a = json.load(open(set, "rb")) 39 | for annot in tqdm(a['annotations'], desc=f"Converting {set} to YOLOv5 format..."): 40 | img_id = annot['image_id'] 41 | img_name = a['images'][img_id]['name'] 42 | img_label_name = f'{img_name[:-3]}txt' 43 | 44 | cls = annot['category_id'] # instance class id 45 | x_center, y_center, width, height = annot['bbox'] 46 | x_center = (x_center + width / 2) / 1920.0 # offset and scale 47 | y_center = (y_center + height / 2) / 1200.0 # offset and scale 48 | width /= 1920.0 # scale 49 | height /= 1200.0 # scale 50 | 51 | img_dir = set.parents[2] / 'Argoverse-1.1' / 'labels' / a['seq_dirs'][a['images'][annot['image_id']]['sid']] 52 | if not img_dir.exists(): 53 | img_dir.mkdir(parents=True, exist_ok=True) 54 | 55 | k = str(img_dir / img_label_name) 56 | if k not in labels: 57 | labels[k] = [] 58 | labels[k].append(f"{cls} {x_center} {y_center} {width} {height}\n") 59 | 60 | for k in labels: 61 | with open(k, "w") as f: 62 | f.writelines(labels[k]) 63 | 64 | 65 | # Download 66 | dir = Path(yaml['path']) # dataset root dir 67 | urls = ['https://argoverse-hd.s3.us-east-2.amazonaws.com/Argoverse-HD-Full.zip'] 68 | download(urls, dir=dir, delete=False) 69 | 70 | # Convert 71 | annotations_dir = 'Argoverse-HD/annotations/' 72 | (dir / 'Argoverse-1.1' / 'tracking').rename(dir / 'Argoverse-1.1' / 'images') # rename 'tracking' to 'images' 73 | for d in "train.json", "val.json": 74 | argoverse2yolo(dir / annotations_dir / d) # convert VisDrone annotations to YOLO labels 75 | -------------------------------------------------------------------------------- /ultralytics/yolo/data/datasets/coco.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | # COCO 2017 dataset http://cocodataset.org by Microsoft 3 | # Example usage: python train.py --data coco.yaml 4 | # parent 5 | # ├── yolov5 6 | # └── datasets 7 | # └── coco ← downloads here (20.1 GB) 8 | 9 | 10 | # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] 11 | path: ../datasets/coco # dataset root dir 12 | train: train2017.txt # train images (relative to 'path') 118287 images 13 | val: val2017.txt # val images (relative to 'path') 5000 images 14 | test: test-dev2017.txt # 20288 of 40670 images, submit to https://competitions.codalab.org/competitions/20794 15 | 16 | # Classes 17 | names: 18 | 0: person 19 | 1: bicycle 20 | 2: car 21 | 3: motorcycle 22 | 4: airplane 23 | 5: bus 24 | 6: train 25 | 7: truck 26 | 8: boat 27 | 9: traffic light 28 | 10: fire hydrant 29 | 11: stop sign 30 | 12: parking meter 31 | 13: bench 32 | 14: bird 33 | 15: cat 34 | 16: dog 35 | 17: horse 36 | 18: sheep 37 | 19: cow 38 | 20: elephant 39 | 21: bear 40 | 22: zebra 41 | 23: giraffe 42 | 24: backpack 43 | 25: umbrella 44 | 26: handbag 45 | 27: tie 46 | 28: suitcase 47 | 29: frisbee 48 | 30: skis 49 | 31: snowboard 50 | 32: sports ball 51 | 33: kite 52 | 34: baseball bat 53 | 35: baseball glove 54 | 36: skateboard 55 | 37: surfboard 56 | 38: tennis racket 57 | 39: bottle 58 | 40: wine glass 59 | 41: cup 60 | 42: fork 61 | 43: knife 62 | 44: spoon 63 | 45: bowl 64 | 46: banana 65 | 47: apple 66 | 48: sandwich 67 | 49: orange 68 | 50: broccoli 69 | 51: carrot 70 | 52: hot dog 71 | 53: pizza 72 | 54: donut 73 | 55: cake 74 | 56: chair 75 | 57: couch 76 | 58: potted plant 77 | 59: bed 78 | 60: dining table 79 | 61: toilet 80 | 62: tv 81 | 63: laptop 82 | 64: mouse 83 | 65: remote 84 | 66: keyboard 85 | 67: cell phone 86 | 68: microwave 87 | 69: oven 88 | 70: toaster 89 | 71: sink 90 | 72: refrigerator 91 | 73: book 92 | 74: clock 93 | 75: vase 94 | 76: scissors 95 | 77: teddy bear 96 | 78: hair drier 97 | 79: toothbrush 98 | 99 | 100 | # Download script/URL (optional) 101 | download: | 102 | from utils.general import download, Path 103 | # Download labels 104 | segments = True # segment or box labels 105 | dir = Path(yaml['path']) # dataset root dir 106 | url = 'https://github.com/ultralytics/yolov5/releases/download/v1.0/' 107 | urls = [url + ('coco2017labels-segments.zip' if segments else 'coco2017labels.zip')] # labels 108 | download(urls, dir=dir.parent) 109 | # Download data 110 | urls = ['http://images.cocodataset.org/zips/train2017.zip', # 19G, 118k images 111 | 'http://images.cocodataset.org/zips/val2017.zip', # 1G, 5k images 112 | 'http://images.cocodataset.org/zips/test2017.zip'] # 7G, 41k images (optional) 113 | download(urls, dir=dir / 'images', threads=3) -------------------------------------------------------------------------------- /ultralytics/yolo/data/datasets/VisDrone.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | # VisDrone2019-DET dataset https://github.com/VisDrone/VisDrone-Dataset by Tianjin University 3 | # Example usage: python train.py --data VisDrone.yaml 4 | # parent 5 | # ├── yolov5 6 | # └── datasets 7 | # └── VisDrone ← downloads here (2.3 GB) 8 | 9 | 10 | # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] 11 | path: ../datasets/VisDrone # dataset root dir 12 | train: VisDrone2019-DET-train/images # train images (relative to 'path') 6471 images 13 | val: VisDrone2019-DET-val/images # val images (relative to 'path') 548 images 14 | test: VisDrone2019-DET-test-dev/images # test images (optional) 1610 images 15 | 16 | # Classes 17 | names: 18 | 0: pedestrian 19 | 1: people 20 | 2: bicycle 21 | 3: car 22 | 4: van 23 | 5: truck 24 | 6: tricycle 25 | 7: awning-tricycle 26 | 8: bus 27 | 9: motor 28 | 29 | 30 | # Download script/URL (optional) --------------------------------------------------------------------------------------- 31 | download: | 32 | from utils.general import download, os, Path 33 | 34 | def visdrone2yolo(dir): 35 | from PIL import Image 36 | from tqdm import tqdm 37 | 38 | def convert_box(size, box): 39 | # Convert VisDrone box to YOLO xywh box 40 | dw = 1. / size[0] 41 | dh = 1. / size[1] 42 | return (box[0] + box[2] / 2) * dw, (box[1] + box[3] / 2) * dh, box[2] * dw, box[3] * dh 43 | 44 | (dir / 'labels').mkdir(parents=True, exist_ok=True) # make labels directory 45 | pbar = tqdm((dir / 'annotations').glob('*.txt'), desc=f'Converting {dir}') 46 | for f in pbar: 47 | img_size = Image.open((dir / 'images' / f.name).with_suffix('.jpg')).size 48 | lines = [] 49 | with open(f, 'r') as file: # read annotation.txt 50 | for row in [x.split(',') for x in file.read().strip().splitlines()]: 51 | if row[4] == '0': # VisDrone 'ignored regions' class 0 52 | continue 53 | cls = int(row[5]) - 1 54 | box = convert_box(img_size, tuple(map(int, row[:4]))) 55 | lines.append(f"{cls} {' '.join(f'{x:.6f}' for x in box)}\n") 56 | with open(str(f).replace(os.sep + 'annotations' + os.sep, os.sep + 'labels' + os.sep), 'w') as fl: 57 | fl.writelines(lines) # write label.txt 58 | 59 | 60 | # Download 61 | dir = Path(yaml['path']) # dataset root dir 62 | urls = ['https://github.com/ultralytics/yolov5/releases/download/v1.0/VisDrone2019-DET-train.zip', 63 | 'https://github.com/ultralytics/yolov5/releases/download/v1.0/VisDrone2019-DET-val.zip', 64 | 'https://github.com/ultralytics/yolov5/releases/download/v1.0/VisDrone2019-DET-test-dev.zip', 65 | 'https://github.com/ultralytics/yolov5/releases/download/v1.0/VisDrone2019-DET-test-challenge.zip'] 66 | download(urls, dir=dir, curl=True, threads=4) 67 | 68 | # Convert 69 | for d in 'VisDrone2019-DET-train', 'VisDrone2019-DET-val', 'VisDrone2019-DET-test-dev': 70 | visdrone2yolo(dir / d) # convert VisDrone annotations to YOLO labels 71 | -------------------------------------------------------------------------------- /ultralytics/yolo/utils/autobatch.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | """ 3 | Auto-batch utils 4 | """ 5 | 6 | from copy import deepcopy 7 | 8 | import numpy as np 9 | import torch 10 | 11 | from ultralytics.yolo.utils import LOGGER, colorstr 12 | from ultralytics.yolo.utils.torch_utils import profile 13 | 14 | 15 | def check_train_batch_size(model, imgsz=640, amp=True): 16 | # Check YOLOv5 training batch size 17 | with torch.cuda.amp.autocast(amp): 18 | return autobatch(deepcopy(model).train(), imgsz) # compute optimal batch size 19 | 20 | 21 | def autobatch(model, imgsz=640, fraction=0.7, batch_size=16): 22 | # Automatically estimate best YOLOv5 batch size to use `fraction` of available CUDA memory 23 | # Usage: 24 | # import torch 25 | # from utils.autobatch import autobatch 26 | # model = torch.hub.load('ultralytics/yolov5', 'yolov5s', autoshape=False) 27 | # print(autobatch(model)) 28 | 29 | # Check device 30 | prefix = colorstr('AutoBatch: ') 31 | LOGGER.info(f'{prefix}Computing optimal batch size for --imgsz {imgsz}') 32 | device = next(model.parameters()).device # get model device 33 | if device.type == 'cpu': 34 | LOGGER.info(f'{prefix}CUDA not detected, using default CPU batch-size {batch_size}') 35 | return batch_size 36 | if torch.backends.cudnn.benchmark: 37 | LOGGER.info(f'{prefix} ⚠️ Requires torch.backends.cudnn.benchmark=False, using default batch-size {batch_size}') 38 | return batch_size 39 | 40 | # Inspect CUDA memory 41 | gb = 1 << 30 # bytes to GiB (1024 ** 3) 42 | d = str(device).upper() # 'CUDA:0' 43 | properties = torch.cuda.get_device_properties(device) # device properties 44 | t = properties.total_memory / gb # GiB total 45 | r = torch.cuda.memory_reserved(device) / gb # GiB reserved 46 | a = torch.cuda.memory_allocated(device) / gb # GiB allocated 47 | f = t - (r + a) # GiB free 48 | LOGGER.info(f'{prefix}{d} ({properties.name}) {t:.2f}G total, {r:.2f}G reserved, {a:.2f}G allocated, {f:.2f}G free') 49 | 50 | # Profile batch sizes 51 | batch_sizes = [1, 2, 4, 8, 16] 52 | try: 53 | img = [torch.empty(b, 3, imgsz, imgsz) for b in batch_sizes] 54 | results = profile(img, model, n=3, device=device) 55 | except Exception as e: 56 | LOGGER.warning(f'{prefix}{e}') 57 | 58 | # Fit a solution 59 | y = [x[2] for x in results if x] # memory [2] 60 | p = np.polyfit(batch_sizes[:len(y)], y, deg=1) # first degree polynomial fit 61 | b = int((f * fraction - p[1]) / p[0]) # y intercept (optimal batch size) 62 | if None in results: # some sizes failed 63 | i = results.index(None) # first fail index 64 | if b >= batch_sizes[i]: # y intercept above failure point 65 | b = batch_sizes[max(i - 1, 0)] # select prior safe point 66 | if b < 1 or b > 1024: # b outside of safe range 67 | b = batch_size 68 | LOGGER.warning(f'{prefix}WARNING ⚠️ CUDA anomaly detected, recommend restart environment and retry command.') 69 | 70 | fraction = (np.polyval(p, b) + r + a) / t # actual fraction predicted 71 | LOGGER.info(f'{prefix}Using batch-size {b} for {d} {t * fraction:.2f}G/{t:.2f}G ({fraction * 100:.0f}%) ✅') 72 | return b 73 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.yml: -------------------------------------------------------------------------------- 1 | name: 🐛 Bug Report 2 | # title: " " 3 | description: Problems with YOLOv8 4 | labels: [bug, triage] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | Thank you for submitting a YOLOv8 🐛 Bug Report! 10 | 11 | - type: checkboxes 12 | attributes: 13 | label: Search before asking 14 | description: > 15 | Please search the [issues](https://github.com/ultralytics/ultralytics/issues) to see if a similar bug report already exists. 16 | options: 17 | - label: > 18 | I have searched the YOLOv8 [issues](https://github.com/ultralytics/ultralytics/issues) and found no similar bug report. 19 | required: true 20 | 21 | - type: dropdown 22 | attributes: 23 | label: YOLOv8 Component 24 | description: | 25 | Please select the part of YOLOv8 where you found the bug. 26 | multiple: true 27 | options: 28 | - "Training" 29 | - "Validation" 30 | - "Detection" 31 | - "Export" 32 | - "PyTorch Hub" 33 | - "Multi-GPU" 34 | - "Evolution" 35 | - "Integrations" 36 | - "Other" 37 | validations: 38 | required: false 39 | 40 | - type: textarea 41 | attributes: 42 | label: Bug 43 | description: Provide console output with error messages and/or screenshots of the bug. 44 | placeholder: | 45 | 💡 ProTip! Include as much information as possible (screenshots, logs, tracebacks etc.) to receive the most helpful response. 46 | validations: 47 | required: true 48 | 49 | - type: textarea 50 | attributes: 51 | label: Environment 52 | description: Please specify the software and hardware you used to produce the bug. 53 | placeholder: | 54 | - YOLO: YOLOv8 🚀 v6.0-67-g60e42e1 torch 1.9.0+cu111 CUDA:0 (A100-SXM4-40GB, 40536MiB) 55 | - OS: Ubuntu 20.04 56 | - Python: 3.9.0 57 | validations: 58 | required: false 59 | 60 | - type: textarea 61 | attributes: 62 | label: Minimal Reproducible Example 63 | description: > 64 | When asking a question, people will be better able to provide help if you provide code that they can easily understand and use to **reproduce** the problem. 65 | This is referred to by community members as creating a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). 66 | placeholder: | 67 | ``` 68 | # Code to reproduce your issue here 69 | ``` 70 | validations: 71 | required: false 72 | 73 | - type: textarea 74 | attributes: 75 | label: Additional 76 | description: Anything else you would like to share? 77 | 78 | - type: checkboxes 79 | attributes: 80 | label: Are you willing to submit a PR? 81 | description: > 82 | (Optional) We encourage you to submit a [Pull Request](https://github.com/ultralytics/ultralytics/pulls) (PR) to help improve YOLOv8 for everyone, especially if you have a good understanding of how to implement a fix or feature. 83 | See the YOLOv8 [Contributing Guide](https://github.com/ultralytics/ultralytics/blob/main/CONTRIBUTING.md) to get started. 84 | options: 85 | - label: Yes I'd like to help by submitting a PR! 86 | -------------------------------------------------------------------------------- /tests/test_python.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | from pathlib import Path 4 | 5 | from ultralytics import YOLO 6 | from ultralytics.yolo.utils import ROOT, SETTINGS 7 | 8 | MODEL = Path(SETTINGS['weights_dir']) / 'yolov8n.pt' 9 | CFG = 'yolov8n.yaml' 10 | SOURCE = ROOT / 'assets/bus.jpg' 11 | 12 | 13 | def test_model_forward(): 14 | model = YOLO(CFG) 15 | model.predict(SOURCE) 16 | model(SOURCE) 17 | 18 | 19 | def test_model_info(): 20 | model = YOLO(CFG) 21 | model.info() 22 | model = YOLO(MODEL) 23 | model.info(verbose=True) 24 | 25 | 26 | def test_model_fuse(): 27 | model = YOLO(CFG) 28 | model.fuse() 29 | model = YOLO(MODEL) 30 | model.fuse() 31 | 32 | 33 | def test_predict_dir(): 34 | model = YOLO(MODEL) 35 | model.predict(source=ROOT / "assets") 36 | 37 | 38 | def test_val(): 39 | model = YOLO(MODEL) 40 | model.val(data="coco128.yaml", imgsz=32) 41 | 42 | 43 | def test_train_scratch(): 44 | model = YOLO(CFG) 45 | model.train(data="coco128.yaml", epochs=1, imgsz=32) 46 | model(SOURCE) 47 | 48 | 49 | def test_train_pretrained(): 50 | model = YOLO(MODEL) 51 | model.train(data="coco128.yaml", epochs=1, imgsz=32) 52 | model(SOURCE) 53 | 54 | 55 | def test_export_torchscript(): 56 | """ 57 | Format Argument Suffix CPU GPU 58 | 0 PyTorch - .pt True True 59 | 1 TorchScript torchscript .torchscript True True 60 | 2 ONNX onnx .onnx True True 61 | 3 OpenVINO openvino _openvino_model True False 62 | 4 TensorRT engine .engine False True 63 | 5 CoreML coreml .mlmodel True False 64 | 6 TensorFlow SavedModel saved_model _saved_model True True 65 | 7 TensorFlow GraphDef pb .pb True True 66 | 8 TensorFlow Lite tflite .tflite True False 67 | 9 TensorFlow Edge TPU edgetpu _edgetpu.tflite False False 68 | 10 TensorFlow.js tfjs _web_model False False 69 | 11 PaddlePaddle paddle _paddle_model True True 70 | """ 71 | from ultralytics.yolo.engine.exporter import export_formats 72 | print(export_formats()) 73 | 74 | model = YOLO(MODEL) 75 | model.export(format='torchscript') 76 | 77 | 78 | def test_export_onnx(): 79 | model = YOLO(MODEL) 80 | model.export(format='onnx') 81 | 82 | 83 | def test_export_openvino(): 84 | model = YOLO(MODEL) 85 | model.export(format='openvino') 86 | 87 | 88 | def test_export_coreml(): 89 | model = YOLO(MODEL) 90 | model.export(format='coreml') 91 | 92 | 93 | def test_export_paddle(): 94 | model = YOLO(MODEL) 95 | model.export(format='paddle') 96 | 97 | 98 | def test_all_model_yamls(): 99 | for m in list((ROOT / 'models').rglob('*.yaml')): 100 | YOLO(m.name) 101 | 102 | 103 | def test_workflow(): 104 | model = YOLO(MODEL) 105 | model.train(data="coco128.yaml", epochs=1, imgsz=32) 106 | model.val() 107 | model.predict(SOURCE) 108 | model.export(format="onnx", opset=12) # export a model to ONNX format 109 | -------------------------------------------------------------------------------- /tests/test_engine.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | from ultralytics import YOLO 4 | from ultralytics.yolo.configs import get_config 5 | from ultralytics.yolo.utils import DEFAULT_CONFIG, ROOT 6 | from ultralytics.yolo.v8 import classify, detect, segment 7 | 8 | CFG_DET = 'yolov8n.yaml' 9 | CFG_SEG = 'yolov8n-seg.yaml' 10 | CFG_CLS = 'squeezenet1_0' 11 | CFG = get_config(DEFAULT_CONFIG) 12 | SOURCE = ROOT / "assets" 13 | 14 | 15 | def test_detect(): 16 | overrides = {"data": "coco128.yaml", "model": CFG_DET, "imgsz": 32, "epochs": 1, "save": False} 17 | CFG.data = "coco128.yaml" 18 | # trainer 19 | trainer = detect.DetectionTrainer(overrides=overrides) 20 | trainer.train() 21 | trained_model = trainer.best 22 | 23 | # Validator 24 | val = detect.DetectionValidator(args=CFG) 25 | val(model=trained_model) 26 | 27 | # predictor 28 | pred = detect.DetectionPredictor(overrides={"imgsz": [640, 640]}) 29 | i = 0 30 | for _ in pred(source=SOURCE, model="yolov8n.pt", return_outputs=True): 31 | i += 1 32 | assert i == 2, "predictor test failed" 33 | 34 | overrides["resume"] = trainer.last 35 | trainer = detect.DetectionTrainer(overrides=overrides) 36 | try: 37 | trainer.train() 38 | except Exception as e: 39 | print(f"Expected exception caught: {e}") 40 | return 41 | 42 | Exception("Resume test failed!") 43 | 44 | 45 | def test_segment(): 46 | overrides = {"data": "coco128-seg.yaml", "model": CFG_SEG, "imgsz": 32, "epochs": 1, "save": False} 47 | CFG.data = "coco128-seg.yaml" 48 | CFG.v5loader = False 49 | 50 | # YOLO(CFG_SEG).train(**overrides) # This works 51 | # trainer 52 | trainer = segment.SegmentationTrainer(overrides=overrides) 53 | trainer.train() 54 | trained_model = trainer.best 55 | 56 | # Validator 57 | val = segment.SegmentationValidator(args=CFG) 58 | val(model=trained_model) 59 | 60 | # predictor 61 | pred = segment.SegmentationPredictor(overrides={"imgsz": [640, 640]}) 62 | i = 0 63 | for _ in pred(source=SOURCE, model="yolov8n-seg.pt", return_outputs=True): 64 | i += 1 65 | assert i == 2, "predictor test failed" 66 | 67 | # test resume 68 | overrides["resume"] = trainer.last 69 | trainer = segment.SegmentationTrainer(overrides=overrides) 70 | try: 71 | trainer.train() 72 | except Exception as e: 73 | print(f"Expected exception caught: {e}") 74 | return 75 | 76 | Exception("Resume test failed!") 77 | 78 | 79 | def test_classify(): 80 | overrides = {"data": "mnist160", "model": "yolov8n-cls.yaml", "imgsz": 32, "epochs": 1, "batch": 64, "save": False} 81 | CFG.data = "mnist160" 82 | CFG.imgsz = 32 83 | CFG.batch = 64 84 | # YOLO(CFG_SEG).train(**overrides) # This works 85 | # trainer 86 | trainer = classify.ClassificationTrainer(overrides=overrides) 87 | trainer.train() 88 | trained_model = trainer.best 89 | 90 | # Validator 91 | val = classify.ClassificationValidator(args=CFG) 92 | val(model=trained_model) 93 | 94 | # predictor 95 | pred = classify.ClassificationPredictor(overrides={"imgsz": [640, 640]}) 96 | i = 0 97 | for _ in pred(source=SOURCE, model=trained_model, return_outputs=True): 98 | i += 1 99 | assert i == 2, "predictor test failed" 100 | -------------------------------------------------------------------------------- /docs/cli.md: -------------------------------------------------------------------------------- 1 | If you want to train, validate or run inference on models and don't need to make any modifications to the code, using 2 | YOLO command line interface is the easiest way to get started. 3 | 4 | !!! tip "Syntax" 5 | 6 | ```bash 7 | yolo task=detect mode=train model=yolov8n.yaml epochs=1 ... 8 | ... ... ... 9 | segment predict yolov8n-seg.pt 10 | classify val yolov8n-cls.pt 11 | ``` 12 | 13 | The experiment arguments can be overridden directly by pass `arg=val` covered in the next section. You can run any 14 | supported task by setting `task` and `mode` in cli. 15 | === "Training" 16 | 17 | | | `task` | snippet | 18 | |------------------|------------|------------------------------------------------------------| 19 | | Detection | `detect` |
yolo task=detect mode=train       
| 20 | | Instance Segment | `segment` |
yolo task=segment mode=train      
| 21 | | Classification | `classify` |
yolo task=classify mode=train    
| 22 | 23 | === "Prediction" 24 | 25 | | | `task` | snippet | 26 | |------------------|------------|--------------------------------------------------------------| 27 | | Detection | `detect` |
yolo task=detect mode=predict       
| 28 | | Instance Segment | `segment` |
yolo task=segment mode=predict     
| 29 | | Classification | `classify` |
yolo task=classify mode=predict    
| 30 | 31 | === "Validation" 32 | 33 | | | `task` | snippet | 34 | |------------------|------------|-----------------------------------------------------------| 35 | | Detection | `detect` |
yolo task=detect mode=val        
| 36 | | Instance Segment | `segment` |
yolo task=segment mode=val       
| 37 | | Classification | `classify` |
yolo task=classify mode=val      
| 38 | 39 | !!! note "" 40 | 41 | Note: The arguments don't require `'--'` prefix. These are reserved for special commands covered later 42 | 43 | --- 44 | 45 | ## Overriding default config arguments 46 | 47 | All global default arguments can be overriden by simply passing them as arguments in the cli. 48 | 49 | !!! tip "" 50 | 51 | === "Syntax" 52 | ```bash 53 | yolo task= ... mode= ... {++ arg=val ++} 54 | ``` 55 | 56 | === "Example" 57 | Perform detection training for `10 epochs` with `learning_rate` of `0.01` 58 | ```bash 59 | yolo task=detect mode=train {++ epochs=10 lr0=0.01 ++} 60 | ``` 61 | 62 | --- 63 | 64 | ## Overriding default config file 65 | 66 | You can override config file entirely by passing a new file. You can create a copy of default config file in your 67 | current working dir as follows: 68 | 69 | ```bash 70 | yolo task=init 71 | ``` 72 | 73 | You can then use `cfg=name.yaml` command to pass the new config file 74 | 75 | ```bash 76 | yolo cfg=default.yaml 77 | ``` 78 | 79 | ??? example 80 | 81 | === "Command" 82 | ```bash 83 | yolo task=init 84 | yolo cfg=default.yaml 85 | ``` 86 | === "Result" 87 | TODO: add terminal output 88 | 89 | 90 | -------------------------------------------------------------------------------- /ultralytics/yolo/data/datasets/VOC.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | # PASCAL VOC dataset http://host.robots.ox.ac.uk/pascal/VOC by University of Oxford 3 | # Example usage: python train.py --data VOC.yaml 4 | # parent 5 | # ├── yolov5 6 | # └── datasets 7 | # └── VOC ← downloads here (2.8 GB) 8 | 9 | 10 | # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] 11 | path: ../datasets/VOC 12 | train: # train images (relative to 'path') 16551 images 13 | - images/train2012 14 | - images/train2007 15 | - images/val2012 16 | - images/val2007 17 | val: # val images (relative to 'path') 4952 images 18 | - images/test2007 19 | test: # test images (optional) 20 | - images/test2007 21 | 22 | # Classes 23 | names: 24 | 0: aeroplane 25 | 1: bicycle 26 | 2: bird 27 | 3: boat 28 | 4: bottle 29 | 5: bus 30 | 6: car 31 | 7: cat 32 | 8: chair 33 | 9: cow 34 | 10: diningtable 35 | 11: dog 36 | 12: horse 37 | 13: motorbike 38 | 14: person 39 | 15: pottedplant 40 | 16: sheep 41 | 17: sofa 42 | 18: train 43 | 19: tvmonitor 44 | 45 | 46 | # Download script/URL (optional) --------------------------------------------------------------------------------------- 47 | download: | 48 | import xml.etree.ElementTree as ET 49 | 50 | from tqdm import tqdm 51 | from utils.general import download, Path 52 | 53 | 54 | def convert_label(path, lb_path, year, image_id): 55 | def convert_box(size, box): 56 | dw, dh = 1. / size[0], 1. / size[1] 57 | x, y, w, h = (box[0] + box[1]) / 2.0 - 1, (box[2] + box[3]) / 2.0 - 1, box[1] - box[0], box[3] - box[2] 58 | return x * dw, y * dh, w * dw, h * dh 59 | 60 | in_file = open(path / f'VOC{year}/Annotations/{image_id}.xml') 61 | out_file = open(lb_path, 'w') 62 | tree = ET.parse(in_file) 63 | root = tree.getroot() 64 | size = root.find('size') 65 | w = int(size.find('width').text) 66 | h = int(size.find('height').text) 67 | 68 | names = list(yaml['names'].values()) # names list 69 | for obj in root.iter('object'): 70 | cls = obj.find('name').text 71 | if cls in names and int(obj.find('difficult').text) != 1: 72 | xmlbox = obj.find('bndbox') 73 | bb = convert_box((w, h), [float(xmlbox.find(x).text) for x in ('xmin', 'xmax', 'ymin', 'ymax')]) 74 | cls_id = names.index(cls) # class id 75 | out_file.write(" ".join([str(a) for a in (cls_id, *bb)]) + '\n') 76 | 77 | 78 | # Download 79 | dir = Path(yaml['path']) # dataset root dir 80 | url = 'https://github.com/ultralytics/yolov5/releases/download/v1.0/' 81 | urls = [f'{url}VOCtrainval_06-Nov-2007.zip', # 446MB, 5012 images 82 | f'{url}VOCtest_06-Nov-2007.zip', # 438MB, 4953 images 83 | f'{url}VOCtrainval_11-May-2012.zip'] # 1.95GB, 17126 images 84 | download(urls, dir=dir / 'images', delete=False, curl=True, threads=3) 85 | 86 | # Convert 87 | path = dir / 'images/VOCdevkit' 88 | for year, image_set in ('2012', 'train'), ('2012', 'val'), ('2007', 'train'), ('2007', 'val'), ('2007', 'test'): 89 | imgs_path = dir / 'images' / f'{image_set}{year}' 90 | lbs_path = dir / 'labels' / f'{image_set}{year}' 91 | imgs_path.mkdir(exist_ok=True, parents=True) 92 | lbs_path.mkdir(exist_ok=True, parents=True) 93 | 94 | with open(path / f'VOC{year}/ImageSets/Main/{image_set}.txt') as f: 95 | image_ids = f.read().strip().split() 96 | for id in tqdm(image_ids, desc=f'{image_set}{year}'): 97 | f = path / f'VOC{year}/JPEGImages/{id}.jpg' # old img path 98 | lb_path = (lbs_path / f.name).with_suffix('.txt') # new label path 99 | f.rename(imgs_path / f.name) # move image 100 | convert_label(path, lb_path, year, id) # convert labels to YOLO format 101 | -------------------------------------------------------------------------------- /ultralytics/yolo/utils/callbacks/base.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | """ 3 | Base callbacks 4 | """ 5 | 6 | 7 | # Trainer callbacks ---------------------------------------------------------------------------------------------------- 8 | def on_pretrain_routine_start(trainer): 9 | pass 10 | 11 | 12 | def on_pretrain_routine_end(trainer): 13 | pass 14 | 15 | 16 | def on_train_start(trainer): 17 | pass 18 | 19 | 20 | def on_train_epoch_start(trainer): 21 | pass 22 | 23 | 24 | def on_train_batch_start(trainer): 25 | pass 26 | 27 | 28 | def optimizer_step(trainer): 29 | pass 30 | 31 | 32 | def on_before_zero_grad(trainer): 33 | pass 34 | 35 | 36 | def on_train_batch_end(trainer): 37 | pass 38 | 39 | 40 | def on_train_epoch_end(trainer): 41 | pass 42 | 43 | 44 | def on_fit_epoch_end(trainer): 45 | pass 46 | 47 | 48 | def on_model_save(trainer): 49 | pass 50 | 51 | 52 | def on_train_end(trainer): 53 | pass 54 | 55 | 56 | def on_params_update(trainer): 57 | pass 58 | 59 | 60 | def teardown(trainer): 61 | pass 62 | 63 | 64 | # Validator callbacks -------------------------------------------------------------------------------------------------- 65 | def on_val_start(validator): 66 | pass 67 | 68 | 69 | def on_val_batch_start(validator): 70 | pass 71 | 72 | 73 | def on_val_batch_end(validator): 74 | pass 75 | 76 | 77 | def on_val_end(validator): 78 | pass 79 | 80 | 81 | # Predictor callbacks -------------------------------------------------------------------------------------------------- 82 | def on_predict_start(predictor): 83 | pass 84 | 85 | 86 | def on_predict_batch_start(predictor): 87 | pass 88 | 89 | 90 | def on_predict_batch_end(predictor): 91 | pass 92 | 93 | 94 | def on_predict_end(predictor): 95 | pass 96 | 97 | 98 | # Exporter callbacks --------------------------------------------------------------------------------------------------- 99 | def on_export_start(exporter): 100 | pass 101 | 102 | 103 | def on_export_end(exporter): 104 | pass 105 | 106 | 107 | default_callbacks = { 108 | # Run in trainer 109 | 'on_pretrain_routine_start': on_pretrain_routine_start, 110 | 'on_pretrain_routine_end': on_pretrain_routine_end, 111 | 'on_train_start': on_train_start, 112 | 'on_train_epoch_start': on_train_epoch_start, 113 | 'on_train_batch_start': on_train_batch_start, 114 | 'optimizer_step': optimizer_step, 115 | 'on_before_zero_grad': on_before_zero_grad, 116 | 'on_train_batch_end': on_train_batch_end, 117 | 'on_train_epoch_end': on_train_epoch_end, 118 | 'on_fit_epoch_end': on_fit_epoch_end, # fit = train + val 119 | 'on_model_save': on_model_save, 120 | 'on_train_end': on_train_end, 121 | 'on_params_update': on_params_update, 122 | 'teardown': teardown, 123 | 124 | # Run in validator 125 | 'on_val_start': on_val_start, 126 | 'on_val_batch_start': on_val_batch_start, 127 | 'on_val_batch_end': on_val_batch_end, 128 | 'on_val_end': on_val_end, 129 | 130 | # Run in predictor 131 | 'on_predict_start': on_predict_start, 132 | 'on_predict_batch_start': on_predict_batch_start, 133 | 'on_predict_batch_end': on_predict_batch_end, 134 | 'on_predict_end': on_predict_end, 135 | 136 | # Run in exporter 137 | 'on_export_start': on_export_start, 138 | 'on_export_end': on_export_end} 139 | 140 | 141 | def add_integration_callbacks(instance): 142 | from .clearml import callbacks as clearml_callbacks 143 | from .comet import callbacks as comet_callbacks 144 | from .hub import callbacks as hub_callbacks 145 | from .tensorboard import callbacks as tb_callbacks 146 | 147 | for x in clearml_callbacks, comet_callbacks, hub_callbacks, tb_callbacks: 148 | for k, v in x.items(): 149 | instance.callbacks[k].append(v) # callback[name].append(func) 150 | -------------------------------------------------------------------------------- /docs/reference/ops.md: -------------------------------------------------------------------------------- 1 | This module contains optimized deep learning related operations used in the Ultralytics YOLO framework 2 | 3 | ## Non-max suppression 4 | 5 | :::ultralytics.ops.non_max_suppression 6 | handler: python 7 | options: 8 | show_source: false 9 | show_root_toc_entry: false 10 | --- 11 | 12 | ## Scale boxes 13 | 14 | :::ultralytics.ops.scale_boxes 15 | handler: python 16 | options: 17 | show_source: false 18 | show_root_toc_entry: false 19 | --- 20 | 21 | ## Scale image 22 | 23 | :::ultralytics.ops.scale_image 24 | handler: python 25 | options: 26 | show_source: false 27 | show_root_toc_entry: false 28 | --- 29 | 30 | ## clip boxes 31 | 32 | :::ultralytics.ops.clip_boxes 33 | handler: python 34 | options: 35 | show_source: false 36 | show_root_toc_entry: false 37 | --- 38 | 39 | # Box Format Conversion 40 | 41 | ## xyxy2xywh 42 | 43 | :::ultralytics.ops.xyxy2xywh 44 | handler: python 45 | options: 46 | show_source: false 47 | show_root_toc_entry: false 48 | --- 49 | 50 | ## xywh2xyxy 51 | 52 | :::ultralytics.ops.xywh2xyxy 53 | handler: python 54 | options: 55 | show_source: false 56 | show_root_toc_entry: false 57 | --- 58 | 59 | ## xywhn2xyxy 60 | 61 | :::ultralytics.ops.xywhn2xyxy 62 | handler: python 63 | options: 64 | show_source: false 65 | show_root_toc_entry: false 66 | --- 67 | 68 | ## xyxy2xywhn 69 | 70 | :::ultralytics.ops.xyxy2xywhn 71 | handler: python 72 | options: 73 | show_source: false 74 | show_root_toc_entry: false 75 | --- 76 | 77 | ## xyn2xy 78 | 79 | :::ultralytics.ops.xyn2xy 80 | handler: python 81 | options: 82 | show_source: false 83 | show_root_toc_entry: false 84 | --- 85 | 86 | ## xywh2ltwh 87 | 88 | :::ultralytics.ops.xywh2ltwh 89 | handler: python 90 | options: 91 | show_source: false 92 | show_root_toc_entry: false 93 | --- 94 | 95 | ## xyxy2ltwh 96 | 97 | :::ultralytics.ops.xyxy2ltwh 98 | handler: python 99 | options: 100 | show_source: false 101 | show_root_toc_entry: false 102 | --- 103 | 104 | ## ltwh2xywh 105 | 106 | :::ultralytics.ops.ltwh2xywh 107 | handler: python 108 | options: 109 | show_source: false 110 | show_root_toc_entry: false 111 | --- 112 | 113 | ## ltwh2xyxy 114 | 115 | :::ultralytics.ops.ltwh2xyxy 116 | handler: python 117 | options: 118 | show_source: false 119 | show_root_toc_entry: false 120 | --- 121 | 122 | ## segment2box 123 | 124 | :::ultralytics.ops.segment2box 125 | handler: python 126 | options: 127 | show_source: false 128 | show_root_toc_entry: false 129 | --- 130 | 131 | # Mask Operations 132 | 133 | ## resample_segments 134 | 135 | :::ultralytics.ops.resample_segments 136 | handler: python 137 | options: 138 | show_source: false 139 | show_root_toc_entry: false 140 | --- 141 | 142 | ## crop_mask 143 | 144 | :::ultralytics.ops.crop_mask 145 | handler: python 146 | options: 147 | show_source: false 148 | show_root_toc_entry: false 149 | --- 150 | 151 | ## process_mask_upsample 152 | 153 | :::ultralytics.ops.process_mask_upsample 154 | handler: python 155 | options: 156 | show_source: false 157 | show_root_toc_entry: false 158 | --- 159 | 160 | ## process_mask 161 | 162 | :::ultralytics.ops.process_mask 163 | handler: python 164 | options: 165 | show_source: false 166 | show_root_toc_entry: false 167 | --- 168 | 169 | ## process_mask_native 170 | 171 | :::ultralytics.ops.process_mask_native 172 | handler: python 173 | options: 174 | show_source: false 175 | show_root_toc_entry: false 176 | --- 177 | 178 | ## scale_segments 179 | 180 | :::ultralytics.ops.scale_segments 181 | handler: python 182 | options: 183 | show_source: false 184 | show_root_toc_entry: false 185 | --- 186 | 187 | ## masks2segments 188 | 189 | :::ultralytics.ops.masks2segments 190 | handler: python 191 | options: 192 | show_source: false 193 | show_root_toc_entry: false 194 | --- 195 | 196 | ## clip_segments 197 | 198 | :::ultralytics.ops.clip_segments 199 | handler: python 200 | options: 201 | show_source: false 202 | show_root_toc_entry: false 203 | --- 204 | 205 | 206 | 207 | 208 | 209 | -------------------------------------------------------------------------------- /ultralytics/yolo/configs/hydra_patch.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | import sys 4 | from difflib import get_close_matches 5 | from textwrap import dedent 6 | 7 | import hydra 8 | from hydra.errors import ConfigCompositionException 9 | from omegaconf import OmegaConf, open_dict # noqa 10 | from omegaconf.errors import ConfigAttributeError, ConfigKeyError, OmegaConfBaseException # noqa 11 | 12 | from ultralytics.yolo.utils import LOGGER, colorstr 13 | 14 | 15 | def override_config(overrides, cfg): 16 | override_keys = [override.key_or_group for override in overrides] 17 | check_config_mismatch(override_keys, cfg.keys()) 18 | for override in overrides: 19 | if override.package is not None: 20 | raise ConfigCompositionException(f"Override {override.input_line} looks like a config group" 21 | f" override, but config group '{override.key_or_group}' does not exist.") 22 | 23 | key = override.key_or_group 24 | value = override.value() 25 | try: 26 | if override.is_delete(): 27 | config_val = OmegaConf.select(cfg, key, throw_on_missing=False) 28 | if config_val is None: 29 | raise ConfigCompositionException(f"Could not delete from config. '{override.key_or_group}'" 30 | " does not exist.") 31 | elif value is not None and value != config_val: 32 | raise ConfigCompositionException("Could not delete from config. The value of" 33 | f" '{override.key_or_group}' is {config_val} and not" 34 | f" {value}.") 35 | 36 | last_dot = key.rfind(".") 37 | with open_dict(cfg): 38 | if last_dot == -1: 39 | del cfg[key] 40 | else: 41 | node = OmegaConf.select(cfg, key[:last_dot]) 42 | del node[key[last_dot + 1:]] 43 | 44 | elif override.is_add(): 45 | if OmegaConf.select(cfg, key, throw_on_missing=False) is None or isinstance(value, (dict, list)): 46 | OmegaConf.update(cfg, key, value, merge=True, force_add=True) 47 | else: 48 | assert override.input_line is not None 49 | raise ConfigCompositionException( 50 | dedent(f"""\ 51 | Could not append to config. An item is already at '{override.key_or_group}'. 52 | Either remove + prefix: '{override.input_line[1:]}' 53 | Or add a second + to add or override '{override.key_or_group}': '+{override.input_line}' 54 | """)) 55 | elif override.is_force_add(): 56 | OmegaConf.update(cfg, key, value, merge=True, force_add=True) 57 | else: 58 | try: 59 | OmegaConf.update(cfg, key, value, merge=True) 60 | except (ConfigAttributeError, ConfigKeyError) as ex: 61 | raise ConfigCompositionException(f"Could not override '{override.key_or_group}'." 62 | f"\nTo append to your config use +{override.input_line}") from ex 63 | except OmegaConfBaseException as ex: 64 | raise ConfigCompositionException(f"Error merging override {override.input_line}").with_traceback( 65 | sys.exc_info()[2]) from ex 66 | 67 | 68 | def check_config_mismatch(overrides, cfg): 69 | mismatched = [option for option in overrides if option not in cfg and 'hydra.' not in option] 70 | 71 | for option in mismatched: 72 | LOGGER.info(f"{colorstr(option)} is not a valid key. Similar keys: {get_close_matches(option, cfg, 3, 0.6)}") 73 | if mismatched: 74 | sys.exit() 75 | 76 | 77 | hydra._internal.config_loader_impl.ConfigLoaderImpl._apply_overrides_to_config = override_config 78 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Ultralytics Docs 2 | 3 | Deployed to https://docs.ultralytics.com 4 | 5 | ### Install Ultralytics package 6 | 7 | To install the ultralytics package in developer mode, you will need to have Git and Python 3 installed on your system. 8 | Then, follow these steps: 9 | 10 | 1. Clone the ultralytics repository to your local machine using Git: 11 | 12 | ```bash 13 | git clone https://github.com/ultralytics/ultralytics.git 14 | ``` 15 | 16 | 2. Navigate to the root directory of the repository: 17 | 18 | ```bash 19 | cd ultralytics 20 | ``` 21 | 22 | 3. Install the package in developer mode using pip: 23 | 24 | ```bash 25 | pip install -e '.[dev]' 26 | ``` 27 | 28 | This will install the ultralytics package and its dependencies in developer mode, allowing you to make changes to the 29 | package code and have them reflected immediately in your Python environment. 30 | 31 | Note that you may need to use the pip3 command instead of pip if you have multiple versions of Python installed on your 32 | system. 33 | 34 | ### Building and Serving Locally 35 | 36 | The `mkdocs serve` command is used to build and serve a local version of the MkDocs documentation site. It is typically 37 | used during the development and testing phase of a documentation project. 38 | 39 | ```bash 40 | mkdocs serve 41 | ``` 42 | 43 | Here is a breakdown of what this command does: 44 | 45 | - `mkdocs`: This is the command-line interface (CLI) for the MkDocs static site generator. It is used to build and serve 46 | MkDocs sites. 47 | - `serve`: This is a subcommand of the `mkdocs` CLI that tells it to build and serve the documentation site locally. 48 | - `-a`: This flag specifies the hostname and port number to bind the server to. The default value is `localhost:8000`. 49 | - `-t`: This flag specifies the theme to use for the documentation site. The default value is `mkdocs`. 50 | - `-s`: This flag tells the `serve` command to serve the site in silent mode, which means it will not display any log 51 | messages or progress updates. 52 | When you run the `mkdocs serve` command, it will build the documentation site using the files in the `docs/` directory 53 | and serve it at the specified hostname and port number. You can then view the site by going to the URL in your web 54 | browser. 55 | 56 | While the site is being served, you can make changes to the documentation files and see them reflected in the live site 57 | immediately. This is useful for testing and debugging your documentation before deploying it to a live server. 58 | 59 | To stop the serve command and terminate the local server, you can use the `CTRL+C` keyboard shortcut. 60 | 61 | ### Deploying Your Documentation Site 62 | 63 | To deploy your MkDocs documentation site, you will need to choose a hosting provider and a deployment method. Some 64 | popular options include GitHub Pages, GitLab Pages, and Amazon S3. 65 | 66 | Before you can deploy your site, you will need to configure your `mkdocs.yml` file to specify the remote host and any 67 | other necessary deployment settings. 68 | 69 | Once you have configured your `mkdocs.yml` file, you can use the `mkdocs deploy` command to build and deploy your site. 70 | This command will build the documentation site using the files in the `docs/` directory and the specified configuration 71 | file and theme, and then deploy the site to the specified remote host. 72 | 73 | For example, to deploy your site to GitHub Pages using the gh-deploy plugin, you can use the following command: 74 | 75 | ```bash 76 | mkdocs gh-deploy 77 | ``` 78 | 79 | If you are using GitHub Pages, you can set a custom domain for your documentation site by going to the "Settings" page 80 | for your repository and updating the "Custom domain" field in the "GitHub Pages" section. 81 | 82 | ![196814117-fc16e711-d2be-4722-9536-b7c6d78fd167](https://user-images.githubusercontent.com/26833433/210150206-9e86dcd7-10af-43e4-9eb2-9518b3799eac.png) 83 | 84 | For more information on deploying your MkDocs documentation site, see 85 | the [MkDocs documentation](https://www.mkdocs.org/user-guide/deploying-your-docs/). 86 | -------------------------------------------------------------------------------- /ultralytics/yolo/utils/files.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | import contextlib 4 | import glob 5 | import os 6 | import urllib 7 | from datetime import datetime 8 | from pathlib import Path 9 | from zipfile import ZipFile 10 | 11 | 12 | class WorkingDirectory(contextlib.ContextDecorator): 13 | # Usage: @WorkingDirectory(dir) decorator or 'with WorkingDirectory(dir):' context manager 14 | def __init__(self, new_dir): 15 | self.dir = new_dir # new dir 16 | self.cwd = Path.cwd().resolve() # current dir 17 | 18 | def __enter__(self): 19 | os.chdir(self.dir) 20 | 21 | def __exit__(self, exc_type, exc_val, exc_tb): 22 | os.chdir(self.cwd) 23 | 24 | 25 | def increment_path(path, exist_ok=False, sep='', mkdir=False): 26 | """ 27 | Increments a file or directory path, i.e. runs/exp --> runs/exp{sep}2, runs/exp{sep}3, ... etc. 28 | 29 | If the path exists and exist_ok is not set to True, the path will be incremented by appending a number and sep to 30 | the end of the path. If the path is a file, the file extension will be preserved. If the path is a directory, the 31 | number will be appended directly to the end of the path. If mkdir is set to True, the path will be created as a 32 | directory if it does not already exist. 33 | 34 | Args: 35 | path (str or pathlib.Path): Path to increment. 36 | exist_ok (bool, optional): If True, the path will not be incremented and will be returned as-is. Defaults to False. 37 | sep (str, optional): Separator to use between the path and the incrementation number. Defaults to an empty string. 38 | mkdir (bool, optional): If True, the path will be created as a directory if it does not exist. Defaults to False. 39 | 40 | Returns: 41 | pathlib.Path: Incremented path. 42 | """ 43 | path = Path(path) # os-agnostic 44 | if path.exists() and not exist_ok: 45 | path, suffix = (path.with_suffix(''), path.suffix) if path.is_file() else (path, '') 46 | 47 | # Method 1 48 | for n in range(2, 9999): 49 | p = f'{path}{sep}{n}{suffix}' # increment path 50 | if not os.path.exists(p): # 51 | break 52 | path = Path(p) 53 | 54 | if mkdir: 55 | path.mkdir(parents=True, exist_ok=True) # make directory 56 | 57 | return path 58 | 59 | 60 | def unzip_file(file, path=None, exclude=('.DS_Store', '__MACOSX')): 61 | # Unzip a *.zip file to path/, excluding files containing strings in exclude list 62 | if path is None: 63 | path = Path(file).parent # default path 64 | with ZipFile(file) as zipObj: 65 | for f in zipObj.namelist(): # list all archived filenames in the zip 66 | if all(x not in f for x in exclude): 67 | zipObj.extract(f, path=path) 68 | 69 | 70 | def file_age(path=__file__): 71 | # Return days since last file update 72 | dt = (datetime.now() - datetime.fromtimestamp(Path(path).stat().st_mtime)) # delta 73 | return dt.days # + dt.seconds / 86400 # fractional days 74 | 75 | 76 | def file_date(path=__file__): 77 | # Return human-readable file modification date, i.e. '2021-3-26' 78 | t = datetime.fromtimestamp(Path(path).stat().st_mtime) 79 | return f'{t.year}-{t.month}-{t.day}' 80 | 81 | 82 | def file_size(path): 83 | # Return file/dir size (MB) 84 | mb = 1 << 20 # bytes to MiB (1024 ** 2) 85 | path = Path(path) 86 | if path.is_file(): 87 | return path.stat().st_size / mb 88 | elif path.is_dir(): 89 | return sum(f.stat().st_size for f in path.glob('**/*') if f.is_file()) / mb 90 | else: 91 | return 0.0 92 | 93 | 94 | def url2file(url): 95 | # Convert URL to filename, i.e. https://url.com/file.txt?auth -> file.txt 96 | url = str(Path(url)).replace(':/', '://') # Pathlib turns :// -> :/ 97 | return Path(urllib.parse.unquote(url)).name.split('?')[0] # '%2F' to '/', split https://url.com/file.txt?auth 98 | 99 | 100 | def get_latest_run(search_dir='.'): 101 | # Return path to most recent 'last.pt' in /runs (i.e. to --resume from) 102 | last_list = glob.glob(f'{search_dir}/**/last*.pt', recursive=True) 103 | return max(last_list, key=os.path.getctime) if last_list else '' 104 | -------------------------------------------------------------------------------- /ultralytics/yolo/v8/detect/predict.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | import hydra 4 | import torch 5 | 6 | from ultralytics.yolo.engine.predictor import BasePredictor 7 | from ultralytics.yolo.utils import DEFAULT_CONFIG, ROOT, ops 8 | from ultralytics.yolo.utils.checks import check_imgsz 9 | from ultralytics.yolo.utils.plotting import Annotator, colors, save_one_box 10 | 11 | 12 | class DetectionPredictor(BasePredictor): 13 | 14 | def get_annotator(self, img): 15 | return Annotator(img, line_width=self.args.line_thickness, example=str(self.model.names)) 16 | 17 | def preprocess(self, img): 18 | img = torch.from_numpy(img).to(self.model.device) 19 | img = img.half() if self.model.fp16 else img.float() # uint8 to fp16/32 20 | img /= 255 # 0 - 255 to 0.0 - 1.0 21 | return img 22 | 23 | def postprocess(self, preds, img, orig_img): 24 | preds = ops.non_max_suppression(preds, 25 | self.args.conf, 26 | self.args.iou, 27 | agnostic=self.args.agnostic_nms, 28 | max_det=self.args.max_det) 29 | 30 | for i, pred in enumerate(preds): 31 | shape = orig_img[i].shape if self.webcam else orig_img.shape 32 | pred[:, :4] = ops.scale_boxes(img.shape[2:], pred[:, :4], shape).round() 33 | 34 | return preds 35 | 36 | def write_results(self, idx, preds, batch): 37 | p, im, im0 = batch 38 | log_string = "" 39 | if len(im.shape) == 3: 40 | im = im[None] # expand for batch dim 41 | self.seen += 1 42 | im0 = im0.copy() 43 | if self.webcam: # batch_size >= 1 44 | log_string += f'{idx}: ' 45 | frame = self.dataset.count 46 | else: 47 | frame = getattr(self.dataset, 'frame', 0) 48 | 49 | self.data_path = p 50 | # save_path = str(self.save_dir / p.name) # im.jpg 51 | self.txt_path = str(self.save_dir / 'labels' / p.stem) + ('' if self.dataset.mode == 'image' else f'_{frame}') 52 | log_string += '%gx%g ' % im.shape[2:] # print string 53 | self.annotator = self.get_annotator(im0) 54 | 55 | det = preds[idx] 56 | if len(det) == 0: 57 | return log_string 58 | for c in det[:, 5].unique(): 59 | n = (det[:, 5] == c).sum() # detections per class 60 | log_string += f"{n} {self.model.names[int(c)]}{'s' * (n > 1)}, " 61 | 62 | if self.return_outputs: 63 | self.output["det"] = det.cpu().numpy() 64 | 65 | # write 66 | gn = torch.tensor(im0.shape)[[1, 0, 1, 0]] # normalization gain whwh 67 | for *xyxy, conf, cls in reversed(det): 68 | if self.args.save_txt: # Write to file 69 | xywh = (ops.xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist() # normalized xywh 70 | line = (cls, *xywh, conf) if self.args.save_conf else (cls, *xywh) # label format 71 | with open(f'{self.txt_path}.txt', 'a') as f: 72 | f.write(('%g ' * len(line)).rstrip() % line + '\n') 73 | 74 | if self.args.save or self.args.save_crop or self.args.show: # Add bbox to image 75 | c = int(cls) # integer class 76 | label = None if self.args.hide_labels else ( 77 | self.model.names[c] if self.args.hide_conf else f'{self.model.names[c]} {conf:.2f}') 78 | self.annotator.box_label(xyxy, label, color=colors(c, True)) 79 | if self.args.save_crop: 80 | imc = im0.copy() 81 | save_one_box(xyxy, 82 | imc, 83 | file=self.save_dir / 'crops' / self.model.model.names[c] / f'{self.data_path.stem}.jpg', 84 | BGR=True) 85 | 86 | return log_string 87 | 88 | 89 | @hydra.main(version_base=None, config_path=str(DEFAULT_CONFIG.parent), config_name=DEFAULT_CONFIG.name) 90 | def predict(cfg): 91 | cfg.model = cfg.model or "yolov8n.pt" 92 | cfg.imgsz = check_imgsz(cfg.imgsz, min_dim=2) # check image size 93 | cfg.source = cfg.source if cfg.source is not None else ROOT / "assets" 94 | predictor = DetectionPredictor(cfg) 95 | predictor.predict_cli() 96 | 97 | 98 | if __name__ == "__main__": 99 | predict() 100 | -------------------------------------------------------------------------------- /docs/python.md: -------------------------------------------------------------------------------- 1 | This is the simplest way of simply using YOLOv8 models in a Python environment. It can be imported from 2 | the `ultralytics` module. 3 | 4 | !!! example "Train" 5 | 6 | === "From pretrained(recommanded)" 7 | ```python 8 | from ultralytics import YOLO 9 | 10 | model = YOLO("yolov8n.pt") # pass any model type 11 | model.train(epochs=5) 12 | ``` 13 | 14 | === "From scratch" 15 | ```python 16 | from ultralytics import YOLO 17 | 18 | model = YOLO("yolov8n.yaml") 19 | model.train(data="coco128.yaml", epochs=5) 20 | ``` 21 | 22 | === "Resume" 23 | ```python 24 | TODO: Resume feature is under development and should be released soon. 25 | ``` 26 | 27 | !!! example "Val" 28 | 29 | === "Val after training" 30 | ```python 31 | from ultralytics import YOLO 32 | 33 | model = YOLO("yolov8n.yaml") 34 | model.train(data="coco128.yaml", epochs=5) 35 | model.val() # It'll automatically evaluate the data you trained. 36 | ``` 37 | 38 | === "Val independently" 39 | ```python 40 | from ultralytics import YOLO 41 | 42 | model = YOLO("model.pt") 43 | # It'll use the data yaml file in model.pt if you don't set data. 44 | model.val() 45 | # or you can set the data you want to val 46 | model.val(data="coco128.yaml") 47 | ``` 48 | 49 | !!! example "Predict" 50 | 51 | === "From source" 52 | ```python 53 | from ultralytics import YOLO 54 | 55 | model = YOLO("model.pt") 56 | model.predict(source="0") # accepts all formats - img/folder/vid.*(mp4/format). 0 for webcam 57 | model.predict(source="folder", show=True) # Display preds. Accepts all yolo predict arguments 58 | 59 | ``` 60 | 61 | === "From image/ndarray/tensor" 62 | ```python 63 | # TODO, still working on it. 64 | ``` 65 | 66 | 67 | === "Return outputs" 68 | ```python 69 | from ultralytics import YOLO 70 | 71 | model = YOLO("model.pt") 72 | outputs = model.predict(source="0", return_outputs=True) # treat predict as a Python generator 73 | for output in outputs: 74 | # each output here is a dict. 75 | # for detection 76 | print(output["det"]) # np.ndarray, (N, 6), xyxy, score, cls 77 | # for segmentation 78 | print(output["det"]) # np.ndarray, (N, 6), xyxy, score, cls 79 | print(output["segment"]) # List[np.ndarray] * N, bounding coordinates of masks 80 | # for classify 81 | print(output["prob"]) # np.ndarray, (num_class, ), cls prob 82 | 83 | ``` 84 | 85 | !!! note "Export and Deployment" 86 | 87 | === "Export, Fuse & info" 88 | ```python 89 | from ultralytics import YOLO 90 | 91 | model = YOLO("model.pt") 92 | model.fuse() 93 | model.info(verbose=True) # Print model information 94 | model.export(format=) # TODO: 95 | 96 | ``` 97 | === "Deployment" 98 | 99 | 100 | More functionality coming soon 101 | 102 | To know more about using `YOLO` models, refer Model class Reference 103 | 104 | [Model reference](reference/model.md){ .md-button .md-button--primary} 105 | 106 | --- 107 | 108 | ### Using Trainers 109 | 110 | `YOLO` model class is a high-level wrapper on the Trainer classes. Each YOLO task has its own trainer that inherits 111 | from `BaseTrainer`. 112 | 113 | !!! tip "Detection Trainer Example" 114 | 115 | ```python 116 | from ultralytics.yolo import v8 import DetectionTrainer, DetectionValidator, DetectionPredictor 117 | 118 | # trainer 119 | trainer = DetectionTrainer(overrides={}) 120 | trainer.train() 121 | trained_model = trainer.best 122 | 123 | # Validator 124 | val = DetectionValidator(args=...) 125 | val(model=trained_model) 126 | 127 | # predictor 128 | pred = DetectionPredictor(overrides={}) 129 | pred(source=SOURCE, model=trained_model) 130 | 131 | # resume from last weight 132 | overrides["resume"] = trainer.last 133 | trainer = detect.DetectionTrainer(overrides=overrides) 134 | ``` 135 | 136 | You can easily customize Trainers to support custom tasks or explore R&D ideas. 137 | Learn more about Customizing `Trainers`, `Validators` and `Predictors` to suit your project needs in the Customization 138 | Section. 139 | 140 | [Customization tutorials](engine.md){ .md-button .md-button--primary} 141 | -------------------------------------------------------------------------------- /docs/hub.md: -------------------------------------------------------------------------------- 1 | # Ultralytics HUB 2 | 3 |
4 | 5 | 6 |
7 | 8 | CI CPU 9 |
10 | 11 | 12 | 13 | [Ultralytics HUB](https://hub.ultralytics.com) is a new no-code online tool developed 14 | by [Ultralytics](https://ultralytics.com), the creators of the popular [YOLOv5](https://github.com/ultralytics/yolov5) 15 | object detection and image segmentation models. With Ultralytics HUB, users can easily train and deploy YOLOv5 models 16 | without any coding or technical expertise. 17 | 18 | Ultralytics HUB is designed to be user-friendly and intuitive, with a drag-and-drop interface that allows users to 19 | easily upload their data and select their model configurations. It also offers a range of pre-trained models and 20 | templates to choose from, making it easy for users to get started with training their own models. Once a model is 21 | trained, it can be easily deployed and used for real-time object detection and image segmentation tasks. Overall, 22 | Ultralytics HUB is an essential tool for anyone looking to use YOLOv5 for their object detection and image segmentation 23 | projects. 24 | 25 | **[Get started now](https://hub.ultralytics.com)** and experience the power and simplicity of Ultralytics HUB for 26 | yourself. Sign up for a free account and 27 | start building, training, and deploying YOLOv5 and YOLOv8 models today. 28 | 29 | ## 1. Upload a Dataset 30 | 31 | Ultralytics HUB datasets are just like YOLOv5 🚀 datasets, they use the same structure and the same label formats to keep 32 | everything simple. 33 | 34 | When you upload a dataset to Ultralytics HUB, make sure to **place your dataset YAML inside the dataset root directory** 35 | as in the example shown below, and then zip for upload to https://hub.ultralytics.com/. Your **dataset YAML, directory 36 | and zip** should all share the same name. For example, if your dataset is called 'coco6' as in our 37 | example [ultralytics/hub/coco6.zip](https://github.com/ultralytics/hub/blob/master/coco6.zip), then you should have a 38 | coco6.yaml inside your coco6/ directory, which should zip to create coco6.zip for upload: 39 | 40 | ```bash 41 | zip -r coco6.zip coco6 42 | ``` 43 | 44 | The example [coco6.zip](https://github.com/ultralytics/hub/blob/master/coco6.zip) dataset in this repository can be 45 | downloaded and unzipped to see exactly how to structure your custom dataset. 46 | 47 |

48 | 49 | The dataset YAML is the same standard YOLOv5 YAML format. See 50 | the [YOLOv5 Train Custom Data tutorial](https://github.com/ultralytics/yolov5/wiki/Train-Custom-Data) for full details. 51 | 52 | ```yaml 53 | # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] 54 | path: # dataset root dir (leave empty for HUB) 55 | train: images/train # train images (relative to 'path') 8 images 56 | val: images/val # val images (relative to 'path') 8 images 57 | test: # test images (optional) 58 | 59 | # Classes 60 | names: 61 | 0: person 62 | 1: bicycle 63 | 2: car 64 | 3: motorcycle 65 | ... 66 | ``` 67 | 68 | After zipping your dataset, sign in to [Ultralytics HUB](https://bit.ly/ultralytics_hub) and click the Datasets tab. 69 | Click 'Upload Dataset' to upload, scan and visualize your new dataset before training new YOLOv5 models on it! 70 | 71 | HUB Dataset Upload 72 | 73 | ## 2. Train a Model 74 | 75 | Connect to the Ultralytics HUB notebook and use your model API key to begin 76 | training! Open In Colab 77 | 78 | ## 3. Deploy to Real World 79 | 80 | Export your model to 13 different formats, including TensorFlow, ONNX, OpenVINO, CoreML, Paddle and many others. Run 81 | models directly on your mobile device by downloading the [Ultralytics App](https://ultralytics.com/app_install)! 82 | 83 | 84 | Ultralytics mobile app 85 | 86 | ## ❓ Issues 87 | 88 | If you are a new [Ultralytics HUB](https://bit.ly/ultralytics_hub) user and have questions or comments, you are in the 89 | right place! Please raise a [New Issue](https://github.com/ultralytics/hub/issues/new/choose) and let us know what we 90 | can do to make your life better 😃! 91 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | # YOLO Continuous Integration (CI) GitHub Actions tests 3 | 4 | name: Ultralytics CI 5 | 6 | on: 7 | push: 8 | branches: [main] 9 | pull_request: 10 | branches: [main] 11 | # schedule: 12 | # - cron: '0 0 * * *' # runs at 00:00 UTC every day 13 | 14 | jobs: 15 | Tests: 16 | timeout-minutes: 60 17 | runs-on: ${{ matrix.os }} 18 | strategy: 19 | fail-fast: false 20 | matrix: 21 | os: [ubuntu-latest, windows-latest, macos-latest] 22 | python-version: ['3.10'] 23 | model: [yolov8n] 24 | torch: [latest] 25 | include: 26 | - os: ubuntu-latest 27 | python-version: '3.7' # '3.6.8' min 28 | model: yolov8n 29 | - os: ubuntu-latest 30 | python-version: '3.8' # torch 1.7.0 requires python >=3.6, <=3.8 31 | model: yolov8n 32 | torch: '1.7.0' # min torch version CI https://pypi.org/project/torchvision/ 33 | steps: 34 | - uses: actions/checkout@v3 35 | - uses: actions/setup-python@v4 36 | with: 37 | python-version: ${{ matrix.python-version }} 38 | - name: Get cache dir 39 | # https://github.com/actions/cache/blob/master/examples.md#multiple-oss-in-a-workflow 40 | id: pip-cache 41 | run: echo "::set-output name=dir::$(pip cache dir)" 42 | - name: Cache pip 43 | uses: actions/cache@v3 44 | with: 45 | path: ${{ steps.pip-cache.outputs.dir }} 46 | key: ${{ runner.os }}-${{ matrix.python-version }}-pip-${{ hashFiles('requirements.txt') }} 47 | restore-keys: ${{ runner.os }}-${{ matrix.python-version }}-pip- 48 | - name: Install requirements 49 | run: | 50 | python -m pip install --upgrade pip wheel 51 | if [ "${{ matrix.torch }}" == "1.7.0" ]; then 52 | pip install -r requirements.txt torch==1.7.0 torchvision==0.8.1 --extra-index-url https://download.pytorch.org/whl/cpu 53 | else 54 | pip install -r requirements.txt --extra-index-url https://download.pytorch.org/whl/cpu 55 | fi 56 | # pip install ultralytics (production) 57 | pip install . 58 | shell: bash # for Windows compatibility 59 | - name: Check environment 60 | run: | 61 | # python -c "import utils; utils.notebook_init()" 62 | echo "RUNNER_OS is ${{ runner.os }}" 63 | echo "GITHUB_EVENT_NAME is ${{ github.event_name }}" 64 | echo "GITHUB_WORKFLOW is ${{ github.workflow }}" 65 | echo "GITHUB_ACTOR is ${{ github.actor }}" 66 | echo "GITHUB_REPOSITORY is ${{ github.repository }}" 67 | echo "GITHUB_REPOSITORY_OWNER is ${{ github.repository_owner }}" 68 | python --version 69 | pip --version 70 | pip list 71 | - name: Test pip package 72 | shell: python 73 | env: 74 | APIKEY: ${{ secrets.ULTRALYTICS_HUB_APIKEY }} 75 | run: | 76 | import os 77 | import ultralytics 78 | from ultralytics import hub, yolo 79 | key = os.environ['APIKEY'] 80 | print(ultralytics.__version__) 81 | # ultralytics.checks() 82 | # ultralytics.reset_model(key) # reset trained model 83 | # ultralytics.start(key) # train model 84 | - name: Test detection 85 | shell: bash # for Windows compatibility 86 | run: | 87 | yolo task=detect mode=train model=yolov8n.yaml data=coco128.yaml epochs=1 imgsz=32 88 | yolo task=detect mode=val model=runs/detect/train/weights/last.pt imgsz=32 89 | yolo task=detect mode=predict model=runs/detect/train/weights/last.pt imgsz=32 source=ultralytics/assets/bus.jpg 90 | yolo mode=export model=runs/detect/train/weights/last.pt imgsz=32 format=torchscript 91 | - name: Test segmentation 92 | shell: bash # for Windows compatibility 93 | run: | 94 | yolo task=segment mode=train model=yolov8n-seg.yaml data=coco128-seg.yaml epochs=1 imgsz=32 95 | yolo task=segment mode=val model=runs/segment/train/weights/last.pt data=coco128-seg.yaml imgsz=32 96 | yolo task=segment mode=predict model=runs/segment/train/weights/last.pt imgsz=32 source=ultralytics/assets/bus.jpg 97 | yolo mode=export model=runs/segment/train/weights/last.pt imgsz=32 format=torchscript 98 | - name: Test classification 99 | shell: bash # for Windows compatibility 100 | run: | 101 | yolo task=classify mode=train model=yolov8n-cls.yaml data=mnist160 epochs=1 imgsz=32 102 | yolo task=classify mode=val model=runs/classify/train/weights/last.pt data=mnist160 imgsz=32 103 | yolo task=classify mode=predict model=runs/classify/train/weights/last.pt imgsz=32 source=ultralytics/assets/bus.jpg 104 | yolo mode=export model=runs/classify/train/weights/last.pt imgsz=32 format=torchscript 105 | -------------------------------------------------------------------------------- /ultralytics/hub/session.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | import signal 4 | import sys 5 | from pathlib import Path 6 | from time import sleep 7 | 8 | import requests 9 | 10 | from ultralytics import __version__ 11 | from ultralytics.hub.utils import HUB_API_ROOT, check_dataset_disk_space, smart_request 12 | from ultralytics.yolo.utils import LOGGER, is_colab, threaded 13 | 14 | AGENT_NAME = f'python-{__version__}-colab' if is_colab() else f'python-{__version__}-local' 15 | 16 | session = None 17 | 18 | 19 | def signal_handler(signum, frame): 20 | """ Confirm exit """ 21 | global hub_logger 22 | LOGGER.info(f'Signal received. {signum} {frame}') 23 | if isinstance(session, HubTrainingSession): 24 | hub_logger.alive = False 25 | del hub_logger 26 | sys.exit(signum) 27 | 28 | 29 | signal.signal(signal.SIGTERM, signal_handler) 30 | signal.signal(signal.SIGINT, signal_handler) 31 | 32 | 33 | class HubTrainingSession: 34 | 35 | def __init__(self, model_id, auth): 36 | self.agent_id = None # identifies which instance is communicating with server 37 | self.model_id = model_id 38 | self.api_url = f'{HUB_API_ROOT}/v1/models/{model_id}' 39 | self.auth_header = auth.get_auth_header() 40 | self.rate_limits = {'metrics': 3.0, 'ckpt': 900.0, 'heartbeat': 300.0} # rate limits (seconds) 41 | self.t = {} # rate limit timers (seconds) 42 | self.metrics_queue = {} # metrics queue 43 | self.alive = True # for heartbeats 44 | self.model = self._get_model() 45 | self._heartbeats() # start heartbeats 46 | 47 | def __del__(self): 48 | # Class destructor 49 | self.alive = False 50 | 51 | def upload_metrics(self): 52 | payload = {"metrics": self.metrics_queue.copy(), "type": "metrics"} 53 | smart_request(f'{self.api_url}', json=payload, headers=self.auth_header, code=2) 54 | 55 | def upload_model(self, epoch, weights, is_best=False, map=0.0, final=False): 56 | # Upload a model to HUB 57 | file = None 58 | if Path(weights).is_file(): 59 | with open(weights, "rb") as f: 60 | file = f.read() 61 | if final: 62 | smart_request(f'{self.api_url}/upload', 63 | data={ 64 | "epoch": epoch, 65 | "type": "final", 66 | "map": map}, 67 | files={"best.pt": file}, 68 | headers=self.auth_header, 69 | retry=10, 70 | timeout=3600, 71 | code=4) 72 | else: 73 | smart_request(f'{self.api_url}/upload', 74 | data={ 75 | "epoch": epoch, 76 | "type": "epoch", 77 | "isBest": bool(is_best)}, 78 | headers=self.auth_header, 79 | files={"last.pt": file}, 80 | code=3) 81 | 82 | def _get_model(self): 83 | # Returns model from database by id 84 | api_url = f"{HUB_API_ROOT}/v1/models/{self.model_id}" 85 | headers = self.auth_header 86 | 87 | try: 88 | r = smart_request(api_url, method="get", headers=headers, thread=False, code=0) 89 | data = r.json().get("data", None) 90 | if not data: 91 | return 92 | assert data['data'], 'ERROR: Dataset may still be processing. Please wait a minute and try again.' # RF fix 93 | self.model_id = data["id"] 94 | 95 | return data 96 | except requests.exceptions.ConnectionError as e: 97 | raise ConnectionRefusedError('ERROR: The HUB server is not online. Please try again later.') from e 98 | 99 | def check_disk_space(self): 100 | if not check_dataset_disk_space(self.model['data']): 101 | raise MemoryError("Not enough disk space") 102 | 103 | # COMMENT: Should not be needed as HUB is now considered an integration and is in integrations_callbacks 104 | # import ultralytics.yolo.utils.callbacks.hub as hub_callbacks 105 | # @staticmethod 106 | # def register_callbacks(trainer): 107 | # for k, v in hub_callbacks.callbacks.items(): 108 | # trainer.add_callback(k, v) 109 | 110 | @threaded 111 | def _heartbeats(self): 112 | while self.alive: 113 | r = smart_request(f'{HUB_API_ROOT}/v1/agent/heartbeat/models/{self.model_id}', 114 | json={ 115 | "agent": AGENT_NAME, 116 | "agentId": self.agent_id}, 117 | headers=self.auth_header, 118 | retry=0, 119 | code=5, 120 | thread=False) 121 | self.agent_id = r.json().get('data', {}).get('agentId', None) 122 | sleep(self.rate_limits['heartbeat']) 123 | -------------------------------------------------------------------------------- /ultralytics/yolo/v8/segment/predict.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | import hydra 4 | import torch 5 | 6 | from ultralytics.yolo.utils import DEFAULT_CONFIG, ROOT, ops 7 | from ultralytics.yolo.utils.checks import check_imgsz 8 | from ultralytics.yolo.utils.plotting import colors, save_one_box 9 | 10 | from ..detect.predict import DetectionPredictor 11 | 12 | 13 | class SegmentationPredictor(DetectionPredictor): 14 | 15 | def postprocess(self, preds, img, orig_img): 16 | masks = [] 17 | # TODO: filter by classes 18 | p = ops.non_max_suppression(preds[0], 19 | self.args.conf, 20 | self.args.iou, 21 | agnostic=self.args.agnostic_nms, 22 | max_det=self.args.max_det, 23 | nm=32) 24 | proto = preds[1][-1] 25 | for i, pred in enumerate(p): 26 | shape = orig_img[i].shape if self.webcam else orig_img.shape 27 | if not len(pred): 28 | continue 29 | if self.args.retina_masks: 30 | pred[:, :4] = ops.scale_boxes(img.shape[2:], pred[:, :4], shape).round() 31 | masks.append(ops.process_mask_native(proto[i], pred[:, 6:], pred[:, :4], shape[:2])) # HWC 32 | else: 33 | masks.append(ops.process_mask(proto[i], pred[:, 6:], pred[:, :4], img.shape[2:], upsample=True)) # HWC 34 | pred[:, :4] = ops.scale_boxes(img.shape[2:], pred[:, :4], shape).round() 35 | 36 | return (p, masks) 37 | 38 | def write_results(self, idx, preds, batch): 39 | p, im, im0 = batch 40 | log_string = "" 41 | if len(im.shape) == 3: 42 | im = im[None] # expand for batch dim 43 | self.seen += 1 44 | if self.webcam: # batch_size >= 1 45 | log_string += f'{idx}: ' 46 | frame = self.dataset.count 47 | else: 48 | frame = getattr(self.dataset, 'frame', 0) 49 | 50 | self.data_path = p 51 | self.txt_path = str(self.save_dir / 'labels' / p.stem) + ('' if self.dataset.mode == 'image' else f'_{frame}') 52 | log_string += '%gx%g ' % im.shape[2:] # print string 53 | self.annotator = self.get_annotator(im0) 54 | 55 | preds, masks = preds 56 | det = preds[idx] 57 | if len(det) == 0: 58 | return log_string 59 | # Segments 60 | mask = masks[idx] 61 | if self.args.save_txt or self.return_outputs: 62 | shape = im0.shape if self.args.retina_masks else im.shape[2:] 63 | segments = [ 64 | ops.scale_segments(shape, x, im0.shape, normalize=False) for x in reversed(ops.masks2segments(mask))] 65 | 66 | # Print results 67 | for c in det[:, 5].unique(): 68 | n = (det[:, 5] == c).sum() # detections per class 69 | log_string += f"{n} {self.model.names[int(c)]}{'s' * (n > 1)}, " # add to string 70 | 71 | # Mask plotting 72 | self.annotator.masks( 73 | mask, 74 | colors=[colors(x, True) for x in det[:, 5]], 75 | im_gpu=torch.as_tensor(im0, dtype=torch.float16).to(self.device).permute(2, 0, 1).flip(0).contiguous() / 76 | 255 if self.args.retina_masks else im[idx]) 77 | 78 | det = reversed(det[:, :6]) 79 | if self.return_outputs: 80 | self.output["det"] = det.cpu().numpy() 81 | self.output["segment"] = segments 82 | 83 | # Write results 84 | for j, (*xyxy, conf, cls) in enumerate(det): 85 | if self.args.save_txt: # Write to file 86 | seg = segments[j].copy() 87 | seg[:, 0] /= shape[1] # width 88 | seg[:, 1] /= shape[0] # height 89 | seg = seg.reshape(-1) # (n,2) to (n*2) 90 | line = (cls, *seg, conf) if self.args.save_conf else (cls, *seg) # label format 91 | with open(f'{self.txt_path}.txt', 'a') as f: 92 | f.write(('%g ' * len(line)).rstrip() % line + '\n') 93 | 94 | if self.args.save or self.args.save_crop or self.args.show: 95 | c = int(cls) # integer class 96 | label = None if self.args.hide_labels else ( 97 | self.model.names[c] if self.args.hide_conf else f'{self.model.names[c]} {conf:.2f}') 98 | self.annotator.box_label(xyxy, label, color=colors(c, True)) 99 | # annotator.draw.polygon(segments[j], outline=colors(c, True), width=3) 100 | if self.args.save_crop: 101 | imc = im0.copy() 102 | save_one_box(xyxy, imc, file=self.save_dir / 'crops' / self.model.names[c] / f'{p.stem}.jpg', BGR=True) 103 | 104 | return log_string 105 | 106 | 107 | @hydra.main(version_base=None, config_path=str(DEFAULT_CONFIG.parent), config_name=DEFAULT_CONFIG.name) 108 | def predict(cfg): 109 | cfg.model = cfg.model or "yolov8n-seg.pt" 110 | cfg.imgsz = check_imgsz(cfg.imgsz, min_dim=2) # check image size 111 | cfg.source = cfg.source if cfg.source is not None else ROOT / "assets" 112 | 113 | predictor = SegmentationPredictor(cfg) 114 | predictor.predict_cli() 115 | 116 | 117 | if __name__ == "__main__": 118 | predict() 119 | -------------------------------------------------------------------------------- /ultralytics/yolo/data/build.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | import os 4 | import random 5 | 6 | import numpy as np 7 | import torch 8 | from torch.utils.data import DataLoader, dataloader, distributed 9 | 10 | from ..utils import LOGGER, colorstr 11 | from ..utils.torch_utils import torch_distributed_zero_first 12 | from .dataset import ClassificationDataset, YOLODataset 13 | from .utils import PIN_MEMORY, RANK 14 | 15 | 16 | class InfiniteDataLoader(dataloader.DataLoader): 17 | """Dataloader that reuses workers 18 | 19 | Uses same syntax as vanilla DataLoader 20 | """ 21 | 22 | def __init__(self, *args, **kwargs): 23 | super().__init__(*args, **kwargs) 24 | object.__setattr__(self, "batch_sampler", _RepeatSampler(self.batch_sampler)) 25 | self.iterator = super().__iter__() 26 | 27 | def __len__(self): 28 | return len(self.batch_sampler.sampler) 29 | 30 | def __iter__(self): 31 | for _ in range(len(self)): 32 | yield next(self.iterator) 33 | 34 | 35 | class _RepeatSampler: 36 | """Sampler that repeats forever 37 | 38 | Args: 39 | sampler (Sampler) 40 | """ 41 | 42 | def __init__(self, sampler): 43 | self.sampler = sampler 44 | 45 | def __iter__(self): 46 | while True: 47 | yield from iter(self.sampler) 48 | 49 | 50 | def seed_worker(worker_id): 51 | # Set dataloader worker seed https://pytorch.org/docs/stable/notes/randomness.html#dataloader 52 | worker_seed = torch.initial_seed() % 2 ** 32 53 | np.random.seed(worker_seed) 54 | random.seed(worker_seed) 55 | 56 | 57 | def build_dataloader(cfg, batch_size, img_path, stride=32, label_path=None, rank=-1, mode="train"): 58 | assert mode in ["train", "val"] 59 | shuffle = mode == "train" 60 | if cfg.rect and shuffle: 61 | LOGGER.warning("WARNING ⚠️ --rect is incompatible with DataLoader shuffle, setting shuffle=False") 62 | shuffle = False 63 | with torch_distributed_zero_first(rank): # init dataset *.cache only once if DDP 64 | dataset = YOLODataset( 65 | img_path=img_path, 66 | label_path=label_path, 67 | imgsz=cfg.imgsz, 68 | batch_size=batch_size, 69 | augment=mode == "train", # augmentation 70 | hyp=cfg, # TODO: probably add a get_hyps_from_cfg function 71 | rect=cfg.rect if mode == "train" else True, # rectangular batches 72 | cache=cfg.get("cache", None), 73 | single_cls=cfg.get("single_cls", False), 74 | stride=int(stride), 75 | pad=0.0 if mode == "train" else 0.5, 76 | prefix=colorstr(f"{mode}: "), 77 | use_segments=cfg.task == "segment", 78 | use_keypoints=cfg.task == "keypoint") 79 | 80 | batch_size = min(batch_size, len(dataset)) 81 | nd = torch.cuda.device_count() # number of CUDA devices 82 | workers = cfg.workers if mode == "train" else cfg.workers * 2 83 | nw = min([os.cpu_count() // max(nd, 1), batch_size if batch_size > 1 else 0, workers]) # number of workers 84 | sampler = None if rank == -1 else distributed.DistributedSampler(dataset, shuffle=shuffle) 85 | loader = DataLoader if cfg.image_weights or cfg.close_mosaic else InfiniteDataLoader # allow attribute updates 86 | generator = torch.Generator() 87 | generator.manual_seed(6148914691236517205 + RANK) 88 | return loader(dataset=dataset, 89 | batch_size=batch_size, 90 | shuffle=shuffle and sampler is None, 91 | num_workers=nw, 92 | sampler=sampler, 93 | pin_memory=PIN_MEMORY, 94 | collate_fn=getattr(dataset, "collate_fn", None), 95 | worker_init_fn=seed_worker, 96 | generator=generator), dataset 97 | 98 | 99 | # build classification 100 | # TODO: using cfg like `build_dataloader` 101 | def build_classification_dataloader(path, 102 | imgsz=224, 103 | batch_size=16, 104 | augment=True, 105 | cache=False, 106 | rank=-1, 107 | workers=8, 108 | shuffle=True): 109 | # Returns Dataloader object to be used with YOLOv5 Classifier 110 | with torch_distributed_zero_first(rank): # init dataset *.cache only once if DDP 111 | dataset = ClassificationDataset(root=path, imgsz=imgsz, augment=augment, cache=cache) 112 | batch_size = min(batch_size, len(dataset)) 113 | nd = torch.cuda.device_count() 114 | nw = min([os.cpu_count() // max(nd, 1), batch_size if batch_size > 1 else 0, workers]) 115 | sampler = None if rank == -1 else distributed.DistributedSampler(dataset, shuffle=shuffle) 116 | generator = torch.Generator() 117 | generator.manual_seed(6148914691236517205 + RANK) 118 | return InfiniteDataLoader(dataset, 119 | batch_size=batch_size, 120 | shuffle=shuffle and sampler is None, 121 | num_workers=nw, 122 | sampler=sampler, 123 | pin_memory=PIN_MEMORY, 124 | worker_init_fn=seed_worker, 125 | generator=generator) # or DataLoader(persistent_workers=True) 126 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |
5 | Ultralytics CI 6 | YOLOv8 Citation 7 | Docker Pulls 8 |
9 | Run on Gradient 10 | Open In Colab 11 | Open In Kaggle 12 |
13 |
14 |
15 | 16 | # Welcome to Ultralytics YOLOv8 17 | 18 | Welcome to the Ultralytics YOLOv8 documentation landing 19 | page! [Ultralytics YOLOv8](https://github.com/ultralytics/ultralytics) is the latest version of the YOLO (You Only Look 20 | Once) object detection and image segmentation model developed by [Ultralytics](https://ultralytics.com). This page 21 | serves as the starting point for exploring the various resources available to help you get started with YOLOv8 and 22 | understand its features and capabilities. 23 | 24 | The YOLOv8 model is designed to be fast, accurate, and easy to use, making it an excellent choice for a wide range of 25 | object detection and image segmentation tasks. It can be trained on large datasets and is capable of running on a 26 | variety of hardware platforms, from CPUs to GPUs. 27 | 28 | Whether you are a seasoned machine learning practitioner or new to the field, we hope that the resources on this page 29 | will help you get the most out of YOLOv8. For any bugs and feature requests please 30 | visit [GitHub Issues](https://github.com/ultralytics/ultralytics/issues). For professional support 31 | please [Contact Us](https://ultralytics.com/contact). 32 | 33 | ## A Brief History of YOLO 34 | 35 | YOLO (You Only Look Once) is a popular object detection and image segmentation model developed by Joseph Redmon and Ali 36 | Farhadi at the University of Washington. The first version of YOLO was released in 2015 and quickly gained popularity 37 | due to its high speed and accuracy. 38 | 39 | YOLOv2 was released in 2016 and improved upon the original model by incorporating batch normalization, anchor boxes, and 40 | dimension clusters. YOLOv3 was released in 2018 and further improved the model's performance by using a more efficient 41 | backbone network, adding a feature pyramid, and making use of focal loss. 42 | 43 | In 2020, YOLOv4 was released which introduced a number of innovations such as the use of Mosaic data augmentation, a new 44 | anchor-free detection head, and a new loss function. 45 | 46 | In 2021, Ultralytics released [YOLOv5](https://github.com/ultralytics/yolov5), which further improved the model's 47 | performance and added new features such as support for panoptic segmentation and object tracking. 48 | 49 | YOLO has been widely used in a variety of applications, including autonomous vehicles, security and surveillance, and 50 | medical imaging. It has also been used to win several competitions, such as the COCO Object Detection Challenge and the 51 | DOTA Object Detection Challenge. 52 | 53 | For more information about the history and development of YOLO, you can refer to the following references: 54 | 55 | - Redmon, J., & Farhadi, A. (2015). You only look once: Unified, real-time object detection. In Proceedings of the IEEE 56 | conference on computer vision and pattern recognition (pp. 779-788). 57 | - Redmon, J., & Farhadi, A. (2016). YOLO9000: Better, faster, stronger. In Proceedings 58 | 59 | ## Ultralytics YOLOv8 60 | 61 | [Ultralytics YOLOv8](https://github.com/ultralytics/ultralytics) is the latest version of the YOLO object detection and 62 | image segmentation model developed by Ultralytics. YOLOv8 is a cutting-edge, state-of-the-art (SOTA) model that builds 63 | upon the success of previous YOLO versions and introduces new features and improvements to further boost performance and 64 | flexibility. 65 | 66 | One key feature of YOLOv8 is its extensibility. It is designed as a framework that supports all previous versions of 67 | YOLO, making it easy to switch between different versions and compare their performance. This makes YOLOv8 an ideal 68 | choice for users who want to take advantage of the latest YOLO technology while still being able to use their existing 69 | YOLO models. 70 | 71 | In addition to its extensibility, YOLOv8 includes a number of other innovations that make it an appealing choice for a 72 | wide range of object detection and image segmentation tasks. These include a new backbone network, a new anchor-free 73 | detection head, and a new loss function. YOLOv8 is also highly efficient and can be run on a variety of hardware 74 | platforms, from CPUs to GPUs. 75 | 76 | Overall, YOLOv8 is a powerful and flexible tool for object detection and image segmentation that offers the best of both 77 | worlds: the latest SOTA technology and the ability to use and compare all previous YOLO versions. 78 | -------------------------------------------------------------------------------- /ultralytics/hub/__init__.py: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | 3 | import os 4 | import shutil 5 | 6 | import psutil 7 | import requests 8 | from IPython import display # to display images and clear console output 9 | 10 | from ultralytics.hub.auth import Auth 11 | from ultralytics.hub.session import HubTrainingSession 12 | from ultralytics.hub.utils import PREFIX, split_key 13 | from ultralytics.yolo.utils import LOGGER, emojis, is_colab 14 | from ultralytics.yolo.utils.torch_utils import select_device 15 | from ultralytics.yolo.v8.detect import DetectionTrainer 16 | 17 | 18 | def checks(verbose=True): 19 | if is_colab(): 20 | shutil.rmtree('sample_data', ignore_errors=True) # remove colab /sample_data directory 21 | 22 | if verbose: 23 | # System info 24 | gib = 1 << 30 # bytes per GiB 25 | ram = psutil.virtual_memory().total 26 | total, used, free = shutil.disk_usage("/") 27 | display.clear_output() 28 | s = f'({os.cpu_count()} CPUs, {ram / gib:.1f} GB RAM, {(total - free) / gib:.1f}/{total / gib:.1f} GB disk)' 29 | else: 30 | s = '' 31 | 32 | select_device(newline=False) 33 | LOGGER.info(f'Setup complete ✅ {s}') 34 | 35 | 36 | def start(key=''): 37 | # Start training models with Ultralytics HUB. Usage: from src.ultralytics import start; start('API_KEY') 38 | def request_api_key(attempts=0): 39 | """Prompt the user to input their API key""" 40 | import getpass 41 | 42 | max_attempts = 3 43 | tries = f"Attempt {str(attempts + 1)} of {max_attempts}" if attempts > 0 else "" 44 | LOGGER.info(f"{PREFIX}Login. {tries}") 45 | input_key = getpass.getpass("Enter your Ultralytics HUB API key:\n") 46 | auth.api_key, model_id = split_key(input_key) 47 | if not auth.authenticate(): 48 | attempts += 1 49 | LOGGER.warning(f"{PREFIX}Invalid API key ⚠️\n") 50 | if attempts < max_attempts: 51 | return request_api_key(attempts) 52 | raise ConnectionError(emojis(f"{PREFIX}Failed to authenticate ❌")) 53 | else: 54 | return model_id 55 | 56 | try: 57 | api_key, model_id = split_key(key) 58 | auth = Auth(api_key) # attempts cookie login if no api key is present 59 | attempts = 1 if len(key) else 0 60 | if not auth.get_state(): 61 | if len(key): 62 | LOGGER.warning(f"{PREFIX}Invalid API key ⚠️\n") 63 | model_id = request_api_key(attempts) 64 | LOGGER.info(f"{PREFIX}Authenticated ✅") 65 | if not model_id: 66 | raise ConnectionError(emojis('Connecting with global API key is not currently supported. ❌')) 67 | session = HubTrainingSession(model_id=model_id, auth=auth) 68 | session.check_disk_space() 69 | 70 | # TODO: refactor, hardcoded for v8 71 | args = session.model.copy() 72 | args.pop("id") 73 | args.pop("status") 74 | args.pop("weights") 75 | args["data"] = "coco128.yaml" 76 | args["model"] = "yolov8n.yaml" 77 | args["batch_size"] = 16 78 | args["imgsz"] = 64 79 | 80 | trainer = DetectionTrainer(overrides=args) 81 | session.register_callbacks(trainer) 82 | setattr(trainer, 'hub_session', session) 83 | trainer.train() 84 | except Exception as e: 85 | LOGGER.warning(f"{PREFIX}{e}") 86 | 87 | 88 | def reset_model(key=''): 89 | # Reset a trained model to an untrained state 90 | api_key, model_id = split_key(key) 91 | r = requests.post('https://api.ultralytics.com/model-reset', json={"apiKey": api_key, "modelId": model_id}) 92 | 93 | if r.status_code == 200: 94 | LOGGER.info(f"{PREFIX}model reset successfully") 95 | return 96 | LOGGER.warning(f"{PREFIX}model reset failure {r.status_code} {r.reason}") 97 | 98 | 99 | def export_model(key='', format='torchscript'): 100 | # Export a model to all formats 101 | api_key, model_id = split_key(key) 102 | formats = ('torchscript', 'onnx', 'openvino', 'engine', 'coreml', 'saved_model', 'pb', 'tflite', 'edgetpu', 'tfjs', 103 | 'ultralytics_tflite', 'ultralytics_coreml') 104 | assert format in formats, f"ERROR: Unsupported export format '{format}' passed, valid formats are {formats}" 105 | 106 | r = requests.post('https://api.ultralytics.com/export', 107 | json={ 108 | "apiKey": api_key, 109 | "modelId": model_id, 110 | "format": format}) 111 | assert r.status_code == 200, f"{PREFIX}{format} export failure {r.status_code} {r.reason}" 112 | LOGGER.info(f"{PREFIX}{format} export started ✅") 113 | 114 | 115 | def get_export(key='', format='torchscript'): 116 | # Get an exported model dictionary with download URL 117 | api_key, model_id = split_key(key) 118 | formats = ('torchscript', 'onnx', 'openvino', 'engine', 'coreml', 'saved_model', 'pb', 'tflite', 'edgetpu', 'tfjs', 119 | 'ultralytics_tflite', 'ultralytics_coreml') 120 | assert format in formats, f"ERROR: Unsupported export format '{format}' passed, valid formats are {formats}" 121 | 122 | r = requests.post('https://api.ultralytics.com/get-export', 123 | json={ 124 | "apiKey": api_key, 125 | "modelId": model_id, 126 | "format": format}) 127 | assert r.status_code == 200, f"{PREFIX}{format} get_export failure {r.status_code} {r.reason}" 128 | return r.json() 129 | 130 | 131 | # temp. For checking 132 | if __name__ == "__main__": 133 | start(key="b3fba421be84a20dbe68644e14436d1cce1b0a0aaa_HeMfHgvHsseMPhdq7Ylz") 134 | -------------------------------------------------------------------------------- /ultralytics/yolo/data/datasets/xView.yaml: -------------------------------------------------------------------------------- 1 | # Ultralytics YOLO 🚀, GPL-3.0 license 2 | # DIUx xView 2018 Challenge https://challenge.xviewdataset.org by U.S. National Geospatial-Intelligence Agency (NGA) 3 | # -------- DOWNLOAD DATA MANUALLY and jar xf val_images.zip to 'datasets/xView' before running train command! -------- 4 | # Example usage: python train.py --data xView.yaml 5 | # parent 6 | # ├── yolov5 7 | # └── datasets 8 | # └── xView ← downloads here (20.7 GB) 9 | 10 | 11 | # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] 12 | path: ../datasets/xView # dataset root dir 13 | train: images/autosplit_train.txt # train images (relative to 'path') 90% of 847 train images 14 | val: images/autosplit_val.txt # train images (relative to 'path') 10% of 847 train images 15 | 16 | # Classes 17 | names: 18 | 0: Fixed-wing Aircraft 19 | 1: Small Aircraft 20 | 2: Cargo Plane 21 | 3: Helicopter 22 | 4: Passenger Vehicle 23 | 5: Small Car 24 | 6: Bus 25 | 7: Pickup Truck 26 | 8: Utility Truck 27 | 9: Truck 28 | 10: Cargo Truck 29 | 11: Truck w/Box 30 | 12: Truck Tractor 31 | 13: Trailer 32 | 14: Truck w/Flatbed 33 | 15: Truck w/Liquid 34 | 16: Crane Truck 35 | 17: Railway Vehicle 36 | 18: Passenger Car 37 | 19: Cargo Car 38 | 20: Flat Car 39 | 21: Tank car 40 | 22: Locomotive 41 | 23: Maritime Vessel 42 | 24: Motorboat 43 | 25: Sailboat 44 | 26: Tugboat 45 | 27: Barge 46 | 28: Fishing Vessel 47 | 29: Ferry 48 | 30: Yacht 49 | 31: Container Ship 50 | 32: Oil Tanker 51 | 33: Engineering Vehicle 52 | 34: Tower crane 53 | 35: Container Crane 54 | 36: Reach Stacker 55 | 37: Straddle Carrier 56 | 38: Mobile Crane 57 | 39: Dump Truck 58 | 40: Haul Truck 59 | 41: Scraper/Tractor 60 | 42: Front loader/Bulldozer 61 | 43: Excavator 62 | 44: Cement Mixer 63 | 45: Ground Grader 64 | 46: Hut/Tent 65 | 47: Shed 66 | 48: Building 67 | 49: Aircraft Hangar 68 | 50: Damaged Building 69 | 51: Facility 70 | 52: Construction Site 71 | 53: Vehicle Lot 72 | 54: Helipad 73 | 55: Storage Tank 74 | 56: Shipping container lot 75 | 57: Shipping Container 76 | 58: Pylon 77 | 59: Tower 78 | 79 | 80 | # Download script/URL (optional) --------------------------------------------------------------------------------------- 81 | download: | 82 | import json 83 | import os 84 | from pathlib import Path 85 | 86 | import numpy as np 87 | from PIL import Image 88 | from tqdm import tqdm 89 | 90 | from utils.dataloaders import autosplit 91 | from utils.general import download, xyxy2xywhn 92 | 93 | 94 | def convert_labels(fname=Path('xView/xView_train.geojson')): 95 | # Convert xView geoJSON labels to YOLO format 96 | path = fname.parent 97 | with open(fname) as f: 98 | print(f'Loading {fname}...') 99 | data = json.load(f) 100 | 101 | # Make dirs 102 | labels = Path(path / 'labels' / 'train') 103 | os.system(f'rm -rf {labels}') 104 | labels.mkdir(parents=True, exist_ok=True) 105 | 106 | # xView classes 11-94 to 0-59 107 | xview_class2index = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, -1, 3, -1, 4, 5, 6, 7, 8, -1, 9, 10, 11, 108 | 12, 13, 14, 15, -1, -1, 16, 17, 18, 19, 20, 21, 22, -1, 23, 24, 25, -1, 26, 27, -1, 28, -1, 109 | 29, 30, 31, 32, 33, 34, 35, 36, 37, -1, 38, 39, 40, 41, 42, 43, 44, 45, -1, -1, -1, -1, 46, 110 | 47, 48, 49, -1, 50, 51, -1, 52, -1, -1, -1, 53, 54, -1, 55, -1, -1, 56, -1, 57, -1, 58, 59] 111 | 112 | shapes = {} 113 | for feature in tqdm(data['features'], desc=f'Converting {fname}'): 114 | p = feature['properties'] 115 | if p['bounds_imcoords']: 116 | id = p['image_id'] 117 | file = path / 'train_images' / id 118 | if file.exists(): # 1395.tif missing 119 | try: 120 | box = np.array([int(num) for num in p['bounds_imcoords'].split(",")]) 121 | assert box.shape[0] == 4, f'incorrect box shape {box.shape[0]}' 122 | cls = p['type_id'] 123 | cls = xview_class2index[int(cls)] # xView class to 0-60 124 | assert 59 >= cls >= 0, f'incorrect class index {cls}' 125 | 126 | # Write YOLO label 127 | if id not in shapes: 128 | shapes[id] = Image.open(file).size 129 | box = xyxy2xywhn(box[None].astype(np.float), w=shapes[id][0], h=shapes[id][1], clip=True) 130 | with open((labels / id).with_suffix('.txt'), 'a') as f: 131 | f.write(f"{cls} {' '.join(f'{x:.6f}' for x in box[0])}\n") # write label.txt 132 | except Exception as e: 133 | print(f'WARNING: skipping one label for {file}: {e}') 134 | 135 | 136 | # Download manually from https://challenge.xviewdataset.org 137 | dir = Path(yaml['path']) # dataset root dir 138 | # urls = ['https://d307kc0mrhucc3.cloudfront.net/train_labels.zip', # train labels 139 | # 'https://d307kc0mrhucc3.cloudfront.net/train_images.zip', # 15G, 847 train images 140 | # 'https://d307kc0mrhucc3.cloudfront.net/val_images.zip'] # 5G, 282 val images (no labels) 141 | # download(urls, dir=dir, delete=False) 142 | 143 | # Convert labels 144 | convert_labels(dir / 'xView_train.geojson') 145 | 146 | # Move images 147 | images = Path(dir / 'images') 148 | images.mkdir(parents=True, exist_ok=True) 149 | Path(dir / 'train_images').rename(dir / 'images' / 'train') 150 | Path(dir / 'val_images').rename(dir / 'images' / 'val') 151 | 152 | # Split 153 | autosplit(dir / 'images' / 'train') 154 | --------------------------------------------------------------------------------