`ultralytics 8.0.58` new SimpleClass, fixes and updates (#1636)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Laughing <61612323+Laughing-q@users.noreply.github.com>
single_channel
Glenn Jocher 2 years ago committed by GitHub
parent ef03e6732a
commit ec10002a4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -18,8 +18,9 @@ jobs:
pr-message: | pr-message: |
👋 Hello @${{ github.actor }}, thank you for submitting a YOLOv8 🚀 PR! To allow your work to be integrated as seamlessly as possible, we advise you to: 👋 Hello @${{ github.actor }}, thank you for submitting a YOLOv8 🚀 PR! To allow your work to be integrated as seamlessly as possible, we advise you to:
- ✅ Verify your PR is **up-to-date** with `ultralytics/ultralytics` `main` branch. If your PR is behind you can update your code by clicking the 'Update branch' button or by running `git pull` and `git merge master` locally. - ✅ Verify your PR is **up-to-date** with `ultralytics/ultralytics` `main` branch. If your PR is behind you can update your code by clicking the 'Update branch' button or by running `git pull` and `git merge main` locally.
- ✅ Verify all YOLOv8 Continuous Integration (CI) **checks are passing**. - ✅ Verify all YOLOv8 Continuous Integration (CI) **checks are passing**.
- ✅ Update YOLOv8 [Docs](https://docs.ultralytics.com) for any new or updated features.
- ✅ Reduce changes to the absolute **minimum** required for your bug fix or feature addition. _"It is not daily increase but daily decrease, hack away the unessential. The closer to the source, the less wastage there is."_ — Bruce Lee - ✅ Reduce changes to the absolute **minimum** required for your bug fix or feature addition. _"It is not daily increase but daily decrease, hack away the unessential. The closer to the source, the less wastage there is."_ — Bruce Lee
See our [Contributing Guide](https://github.com/ultralytics/ultralytics/blob/main/CONTRIBUTING.md) for details and let us know if you have any questions! See our [Contributing Guide](https://github.com/ultralytics/ultralytics/blob/main/CONTRIBUTING.md) for details and let us know if you have any questions!
@ -33,7 +34,7 @@ jobs:
## Install ## Install
Pip install the `ultralytics` package including all [requirements.txt](https://github.com/ultralytics/ultralytics/blob/main/requirements.txt) in a [**Python>=3.7**](https://www.python.org/) environment with [**PyTorch>=1.7**](https://pytorch.org/get-started/locally/). Pip install the `ultralytics` package including all [requirements](https://github.com/ultralytics/ultralytics/blob/main/requirements.txt) in a [**Python>=3.7**](https://www.python.org/) environment with [**PyTorch>=1.7**](https://pytorch.org/get-started/locally/).
```bash ```bash
pip install ultralytics pip install ultralytics

@ -23,7 +23,7 @@ jobs:
with: with:
fail: true fail: true
# accept 429(Instagram, 'too many requests'), 999(LinkedIn, 'unknown status code'), Timeout(Twitter) # accept 429(Instagram, 'too many requests'), 999(LinkedIn, 'unknown status code'), Timeout(Twitter)
args: --accept 429,999 --exclude twitter.com --verbose --no-progress './**/*.md' './**/*.html' args: --accept 429,999 --exclude-loopback --exclude twitter.com --verbose --no-progress './**/*.md' './**/*.html'
env: env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
@ -33,6 +33,6 @@ jobs:
with: with:
fail: true fail: true
# accept 429(Instagram, 'too many requests'), 999(LinkedIn, 'unknown status code'), Timeout(Twitter) # accept 429(Instagram, 'too many requests'), 999(LinkedIn, 'unknown status code'), Timeout(Twitter)
args: --accept 429,999 --exclude twitter.com,url.com --verbose --no-progress './**/*.md' './**/*.html' './**/*.yml' './**/*.yaml' './**/*.py' './**/*.ipynb' args: --accept 429,999 --exclude-loopback --exclude twitter.com,url.com --verbose --no-progress './**/*.md' './**/*.html' './**/*.yml' './**/*.yaml' './**/*.py' './**/*.ipynb'
env: env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}

@ -58,7 +58,7 @@ full documentation on training, validation, prediction and deployment.
<summary>Install</summary> <summary>Install</summary>
Pip install the ultralytics package including Pip install the ultralytics package including
all [requirements.txt](https://github.com/ultralytics/ultralytics/blob/main/requirements.txt) in a all [requirements](https://github.com/ultralytics/ultralytics/blob/main/requirements.txt) in a
[**Python>=3.7**](https://www.python.org/) environment with [**Python>=3.7**](https://www.python.org/) environment with
[**PyTorch>=1.7**](https://pytorch.org/get-started/locally/). [**PyTorch>=1.7**](https://pytorch.org/get-started/locally/).
@ -105,28 +105,11 @@ success = model.export(format="onnx") # export the model to ONNX format
Ultralytics [release](https://github.com/ultralytics/assets/releases). See Ultralytics [release](https://github.com/ultralytics/assets/releases). See
YOLOv8 [Python Docs](https://docs.ultralytics.com/usage/python) for more examples. YOLOv8 [Python Docs](https://docs.ultralytics.com/usage/python) for more examples.
#### Model Architectures
**NEW** YOLOv5u anchor free models are now available.
All supported model architectures can be found in the [Models](./ultralytics/models/) section.
#### Known Issues / TODOs
We are still working on several parts of YOLOv8! We aim to have these completed soon to bring the YOLOv8 feature set up
to par with YOLOv5, including export and inference to all the same formats. We are also writing a YOLOv8 paper which we
will submit to [arxiv.org](https://arxiv.org) once complete.
- [x] TensorFlow exports
- [x] DDP resume
- [ ] [arxiv.org](https://arxiv.org) paper
</details> </details>
## <div align="center">Models</div> ## <div align="center">Models</div>
All YOLOv8 pretrained models are available here. Detection and Segmentation models are pretrained on the COCO dataset, All YOLOv8 pretrained models are available here. Detect, Segment and Pose models are pretrained on the [COCO](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/coco.yaml) dataset, while Classify models are pretrained on the [ImageNet](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/ImageNet.yaml) dataset.
while Classification models are pretrained on the ImageNet dataset.
[Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/models) download automatically from the latest [Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/models) download automatically from the latest
Ultralytics [release](https://github.com/ultralytics/assets/releases) on first use. Ultralytics [release](https://github.com/ultralytics/assets/releases) on first use.
@ -147,7 +130,7 @@ See [Detection Docs](https://docs.ultralytics.com/tasks/detect/) for usage examp
<br>Reproduce by `yolo val detect data=coco.yaml device=0` <br>Reproduce by `yolo val detect data=coco.yaml device=0`
- **Speed** averaged over COCO val images using an [Amazon EC2 P4d](https://aws.amazon.com/ec2/instance-types/p4/) - **Speed** averaged over COCO val images using an [Amazon EC2 P4d](https://aws.amazon.com/ec2/instance-types/p4/)
instance. instance.
<br>Reproduce by `yolo val detect data=coco128.yaml batch=1 device=0/cpu` <br>Reproduce by `yolo val detect data=coco128.yaml batch=1 device=0|cpu`
</details> </details>
@ -167,7 +150,7 @@ See [Segmentation Docs](https://docs.ultralytics.com/tasks/segment/) for usage e
<br>Reproduce by `yolo val segment data=coco.yaml device=0` <br>Reproduce by `yolo val segment data=coco.yaml device=0`
- **Speed** averaged over COCO val images using an [Amazon EC2 P4d](https://aws.amazon.com/ec2/instance-types/p4/) - **Speed** averaged over COCO val images using an [Amazon EC2 P4d](https://aws.amazon.com/ec2/instance-types/p4/)
instance. instance.
<br>Reproduce by `yolo val segment data=coco128-seg.yaml batch=1 device=0/cpu` <br>Reproduce by `yolo val segment data=coco128-seg.yaml batch=1 device=0|cpu`
</details> </details>
@ -187,7 +170,7 @@ See [Classification Docs](https://docs.ultralytics.com/tasks/classify/) for usag
<br>Reproduce by `yolo val classify data=path/to/ImageNet device=0` <br>Reproduce by `yolo val classify data=path/to/ImageNet device=0`
- **Speed** averaged over ImageNet val images using an [Amazon EC2 P4d](https://aws.amazon.com/ec2/instance-types/p4/) - **Speed** averaged over ImageNet val images using an [Amazon EC2 P4d](https://aws.amazon.com/ec2/instance-types/p4/)
instance. instance.
<br>Reproduce by `yolo val classify data=path/to/ImageNet batch=1 device=0/cpu` <br>Reproduce by `yolo val classify data=path/to/ImageNet batch=1 device=0|cpu`
</details> </details>

@ -52,7 +52,7 @@ SOTA 模型。它在以前成功的 YOLO 版本基础上,引入了新的功能
<details open> <details open>
<summary>安装</summary> <summary>安装</summary>
Pip 安装包含所有 [requirements.txt](https://github.com/ultralytics/ultralytics/blob/main/requirements.txt) 的 Pip 安装包含所有 [requirements](https://github.com/ultralytics/ultralytics/blob/main/requirements.txt) 的
ultralytics 包,环境要求 [**Python>=3.7**](https://www.python.org/),且 [\*\*PyTorch>=1.7 ultralytics 包,环境要求 [**Python>=3.7**](https://www.python.org/),且 [\*\*PyTorch>=1.7
\*\*](https://pytorch.org/get-started/locally/)。 \*\*](https://pytorch.org/get-started/locally/)。
@ -100,15 +100,6 @@ success = model.export(format="onnx") # 将模型导出为 ONNX 格式
[模型](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/models) 会从 [模型](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/models) 会从
Ultralytics [发布页](https://github.com/ultralytics/ultralytics/releases) 自动下载。 Ultralytics [发布页](https://github.com/ultralytics/ultralytics/releases) 自动下载。
### 已知问题 / 待办事项
我们仍在努力完善 YOLOv8 的几个部分!我们的目标是尽快完成这些工作,使 YOLOv8 的功能设置达到YOLOv5
的水平,包括对所有相同格式的导出和推理。我们还在写一篇 YOLOv8 的论文,一旦完成,我们将提交给 [arxiv.org](https://arxiv.org)。
- [x] TensorFlow 导出
- [x] DDP 恢复训练
- [ ] [arxiv.org](https://arxiv.org) 论文
</details> </details>
## <div align="center">模型</div> ## <div align="center">模型</div>
@ -132,7 +123,7 @@ Ultralytics [发布页](https://github.com/ultralytics/ultralytics/releases) 自
<br>复现命令 `yolo val detect data=coco.yaml device=0` <br>复现命令 `yolo val detect data=coco.yaml device=0`
- **推理速度**使用 COCO - **推理速度**使用 COCO
验证集图片推理时间进行平均得到,测试环境使用 [Amazon EC2 P4d](https://aws.amazon.com/ec2/instance-types/p4/) 实例。 验证集图片推理时间进行平均得到,测试环境使用 [Amazon EC2 P4d](https://aws.amazon.com/ec2/instance-types/p4/) 实例。
<br>复现命令 `yolo val detect data=coco128.yaml batch=1 device=0/cpu` <br>复现命令 `yolo val detect data=coco128.yaml batch=1 device=0|cpu`
</details> </details>
@ -150,7 +141,7 @@ Ultralytics [发布页](https://github.com/ultralytics/ultralytics/releases) 自
<br>复现命令 `yolo val segment data=coco.yaml device=0` <br>复现命令 `yolo val segment data=coco.yaml device=0`
- **推理速度**使用 COCO - **推理速度**使用 COCO
验证集图片推理时间进行平均得到,测试环境使用 [Amazon EC2 P4d](https://aws.amazon.com/ec2/instance-types/p4/) 实例。 验证集图片推理时间进行平均得到,测试环境使用 [Amazon EC2 P4d](https://aws.amazon.com/ec2/instance-types/p4/) 实例。
<br>复现命令 `yolo val segment data=coco128-seg.yaml batch=1 device=0/cpu` <br>复现命令 `yolo val segment data=coco128-seg.yaml batch=1 device=0|cpu`
</details> </details>
@ -168,7 +159,7 @@ Ultralytics [发布页](https://github.com/ultralytics/ultralytics/releases) 自
<br>复现命令 `yolo val classify data=path/to/ImageNet device=0` <br>复现命令 `yolo val classify data=path/to/ImageNet device=0`
- **推理速度**使用 ImageNet - **推理速度**使用 ImageNet
验证集图片推理时间进行平均得到,测试环境使用 [Amazon EC2 P4d](https://aws.amazon.com/ec2/instance-types/p4/) 实例。 验证集图片推理时间进行平均得到,测试环境使用 [Amazon EC2 P4d](https://aws.amazon.com/ec2/instance-types/p4/) 实例。
<br>复现命令 `yolo val classify data=path/to/ImageNet batch=1 device=0/cpu` <br>复现命令 `yolo val classify data=path/to/ImageNet batch=1 device=0|cpu`
</details> </details>

@ -9,9 +9,31 @@ of that class are located or what their exact shape is.
!!! tip "Tip" !!! tip "Tip"
YOLOv8 _classification_ models use the `-cls` suffix, i.e. `yolov8n-cls.pt` and are pretrained on ImageNet. YOLOv8 Classify models use the `-cls` suffix, i.e. `yolov8n-cls.pt` and are pretrained on [ImageNet](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/ImageNet.yaml).
[Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/models/v8){ .md-button .md-button--primary} ## [Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/models/v8)
YOLOv8 pretrained Classify models are shown here. Detect, Segment and Pose models are pretrained on
the [COCO](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/coco.yaml) dataset, while Classify
models are pretrained on
the [ImageNet](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/ImageNet.yaml) dataset.
[Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/models) download automatically from the latest
Ultralytics [release](https://github.com/ultralytics/assets/releases) on first use.
| Model | size<br><sup>(pixels) | acc<br><sup>top1 | acc<br><sup>top5 | Speed<br><sup>CPU ONNX<br>(ms) | Speed<br><sup>A100 TensorRT<br>(ms) | params<br><sup>(M) | FLOPs<br><sup>(B) at 640 |
|----------------------------------------------------------------------------------------------|-----------------------|------------------|------------------|--------------------------------|-------------------------------------|--------------------|--------------------------|
| [YOLOv8n-cls](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8n-cls.pt) | 224 | 66.6 | 87.0 | 12.9 | 0.31 | 2.7 | 4.3 |
| [YOLOv8s-cls](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8s-cls.pt) | 224 | 72.3 | 91.1 | 23.4 | 0.35 | 6.4 | 13.5 |
| [YOLOv8m-cls](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8m-cls.pt) | 224 | 76.4 | 93.2 | 85.4 | 0.62 | 17.0 | 42.7 |
| [YOLOv8l-cls](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8l-cls.pt) | 224 | 78.0 | 94.1 | 163.0 | 0.87 | 37.5 | 99.7 |
| [YOLOv8x-cls](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8x-cls.pt) | 224 | 78.4 | 94.3 | 232.0 | 1.01 | 57.4 | 154.8 |
- **acc** values are model accuracies on the [ImageNet](https://www.image-net.org/) dataset validation set.
<br>Reproduce by `yolo val classify data=path/to/ImageNet device=0`
- **Speed** averaged over ImageNet val images using an [Amazon EC2 P4d](https://aws.amazon.com/ec2/instance-types/p4/)
instance.
<br>Reproduce by `yolo val classify data=path/to/ImageNet batch=1 device=0|cpu`
## Train ## Train

@ -9,9 +9,31 @@ scene, but don't need to know exactly where the object is or its exact shape.
!!! tip "Tip" !!! tip "Tip"
YOLOv8 _detection_ models have no suffix and are the default YOLOv8 models, i.e. `yolov8n.pt` and are pretrained on COCO. YOLOv8 Detect models are the default YOLOv8 models, i.e. `yolov8n.pt` and are pretrained on [COCO](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/coco.yaml).
[Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/models/v8){ .md-button .md-button--primary} ## [Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/models/v8)
YOLOv8 pretrained Detect models are shown here. Detect, Segment and Pose models are pretrained on
the [COCO](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/coco.yaml) dataset, while Classify
models are pretrained on
the [ImageNet](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/ImageNet.yaml) dataset.
[Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/models) download automatically from the latest
Ultralytics [release](https://github.com/ultralytics/assets/releases) on first use.
| Model | size<br><sup>(pixels) | mAP<sup>val<br>50-95 | Speed<br><sup>CPU ONNX<br>(ms) | Speed<br><sup>A100 TensorRT<br>(ms) | params<br><sup>(M) | FLOPs<br><sup>(B) |
|--------------------------------------------------------------------------------------|-----------------------|----------------------|--------------------------------|-------------------------------------|--------------------|-------------------|
| [YOLOv8n](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8n.pt) | 640 | 37.3 | 80.4 | 0.99 | 3.2 | 8.7 |
| [YOLOv8s](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8s.pt) | 640 | 44.9 | 128.4 | 1.20 | 11.2 | 28.6 |
| [YOLOv8m](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8m.pt) | 640 | 50.2 | 234.7 | 1.83 | 25.9 | 78.9 |
| [YOLOv8l](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8l.pt) | 640 | 52.9 | 375.2 | 2.39 | 43.7 | 165.2 |
| [YOLOv8x](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8x.pt) | 640 | 53.9 | 479.1 | 3.53 | 68.2 | 257.8 |
- **mAP<sup>val</sup>** values are for single-model single-scale on [COCO val2017](http://cocodataset.org) dataset.
<br>Reproduce by `yolo val detect data=coco.yaml device=0`
- **Speed** averaged over COCO val images using an [Amazon EC2 P4d](https://aws.amazon.com/ec2/instance-types/p4/)
instance.
<br>Reproduce by `yolo val detect data=coco128.yaml batch=1 device=0|cpu`
## Train ## Train

@ -9,9 +9,31 @@ segmentation is useful when you need to know not only where objects are in an im
!!! tip "Tip" !!! tip "Tip"
YOLOv8 _segmentation_ models use the `-seg` suffix, i.e. `yolov8n-seg.pt` and are pretrained on COCO. YOLOv8 Segment models use the `-seg` suffix, i.e. `yolov8n-seg.pt` and are pretrained on [COCO](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/coco.yaml).
[Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/models/v8){ .md-button .md-button--primary} ## [Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/models/v8)
YOLOv8 pretrained Segment models are shown here. Detect, Segment and Pose models are pretrained on
the [COCO](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/coco.yaml) dataset, while Classify
models are pretrained on
the [ImageNet](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/ImageNet.yaml) dataset.
[Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/models) download automatically from the latest
Ultralytics [release](https://github.com/ultralytics/assets/releases) on first use.
| Model | size<br><sup>(pixels) | mAP<sup>box<br>50-95 | mAP<sup>mask<br>50-95 | Speed<br><sup>CPU ONNX<br>(ms) | Speed<br><sup>A100 TensorRT<br>(ms) | params<br><sup>(M) | FLOPs<br><sup>(B) |
|----------------------------------------------------------------------------------------------|-----------------------|----------------------|-----------------------|--------------------------------|-------------------------------------|--------------------|-------------------|
| [YOLOv8n-seg](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8n-seg.pt) | 640 | 36.7 | 30.5 | 96.1 | 1.21 | 3.4 | 12.6 |
| [YOLOv8s-seg](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8s-seg.pt) | 640 | 44.6 | 36.8 | 155.7 | 1.47 | 11.8 | 42.6 |
| [YOLOv8m-seg](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8m-seg.pt) | 640 | 49.9 | 40.8 | 317.0 | 2.18 | 27.3 | 110.2 |
| [YOLOv8l-seg](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8l-seg.pt) | 640 | 52.3 | 42.6 | 572.4 | 2.79 | 46.0 | 220.5 |
| [YOLOv8x-seg](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8x-seg.pt) | 640 | 53.4 | 43.4 | 712.1 | 4.02 | 71.8 | 344.1 |
- **mAP<sup>val</sup>** values are for single-model single-scale on [COCO val2017](http://cocodataset.org) dataset.
<br>Reproduce by `yolo val segment data=coco.yaml device=0`
- **Speed** averaged over COCO val images using an [Amazon EC2 P4d](https://aws.amazon.com/ec2/instance-types/p4/)
instance.
<br>Reproduce by `yolo val segment data=coco128-seg.yaml batch=1 device=0|cpu`
## Train ## Train

@ -59,21 +59,21 @@
"colab": { "colab": {
"base_uri": "https://localhost:8080/" "base_uri": "https://localhost:8080/"
}, },
"outputId": "9bda69d4-e57f-404b-b6fe-117234e24677" "outputId": "ea235da2-8fb5-4094-9dc2-8523d0800a22"
}, },
"source": [ "source": [
"%pip install ultralytics\n", "%pip install ultralytics\n",
"import ultralytics\n", "import ultralytics\n",
"ultralytics.checks()" "ultralytics.checks()"
], ],
"execution_count": null, "execution_count": 1,
"outputs": [ "outputs": [
{ {
"output_type": "stream", "output_type": "stream",
"name": "stderr", "name": "stderr",
"text": [ "text": [
"Ultralytics YOLOv8.0.24 🚀 Python-3.8.10 torch-1.13.1+cu116 CUDA:0 (Tesla T4, 15110MiB)\n", "Ultralytics YOLOv8.0.57 🚀 Python-3.9.16 torch-1.13.1+cu116 CUDA:0 (Tesla T4, 15102MiB)\n",
"Setup complete ✅ (2 CPUs, 12.7 GB RAM, 30.8/166.8 GB disk)\n" "Setup complete ✅ (2 CPUs, 12.7 GB RAM, 25.9/166.8 GB disk)\n"
] ]
} }
] ]
@ -96,28 +96,24 @@
"colab": { "colab": {
"base_uri": "https://localhost:8080/" "base_uri": "https://localhost:8080/"
}, },
"outputId": "abe002b5-3df9-4324-9e50-1587394398a2" "outputId": "fe0a5a26-3bcc-4c1f-e688-cae00ee5b958"
}, },
"source": [ "source": [
"# Run inference on an image with YOLOv8n\n", "# Run inference on an image with YOLOv8n\n",
"!yolo predict model=yolov8n.pt source='https://ultralytics.com/images/zidane.jpg'" "!yolo predict model=yolov8n.pt source='https://ultralytics.com/images/zidane.jpg'"
], ],
"execution_count": null, "execution_count": 3,
"outputs": [ "outputs": [
{ {
"output_type": "stream", "output_type": "stream",
"name": "stdout", "name": "stdout",
"text": [ "text": [
"Downloading https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8n.pt to yolov8n.pt...\n", "Ultralytics YOLOv8.0.57 🚀 Python-3.9.16 torch-1.13.1+cu116 CUDA:0 (Tesla T4, 15102MiB)\n",
"\r 0% 0.00/6.23M [00:00<?, ?B/s]\r100% 6.23M/6.23M [00:00<00:00, 266MB/s]\n",
"Ultralytics YOLOv8.0.24 🚀 Python-3.8.10 torch-1.13.1+cu116 CUDA:0 (Tesla T4, 15110MiB)\n",
"YOLOv8n summary (fused): 168 layers, 3151904 parameters, 0 gradients, 8.7 GFLOPs\n", "YOLOv8n summary (fused): 168 layers, 3151904 parameters, 0 gradients, 8.7 GFLOPs\n",
"\n", "\n",
"Downloading https://ultralytics.com/images/zidane.jpg to zidane.jpg...\n", "Found https://ultralytics.com/images/zidane.jpg locally at zidane.jpg\n",
"100% 165k/165k [00:00<00:00, 87.4MB/s]\n", "image 1/1 /content/zidane.jpg: 384x640 2 persons, 1 tie, 14.3ms\n",
"image 1/1 /content/zidane.jpg: 384x640 2 persons, 1 tie, 13.3ms\n", "Speed: 0.5ms preprocess, 14.3ms inference, 1.8ms postprocess per image at shape (1, 3, 640, 640)\n"
"Speed: 0.5ms preprocess, 13.3ms inference, 43.5ms postprocess per image at shape (1, 3, 640, 640)\n",
"Results saved to \u001b[1mruns/detect/predict\u001b[0m\n"
] ]
} }
] ]
@ -160,7 +156,7 @@
"cell_type": "code", "cell_type": "code",
"metadata": { "metadata": {
"id": "X58w8JLpMnjH", "id": "X58w8JLpMnjH",
"outputId": "df71d7a8-f42f-473a-c143-75f033c58433", "outputId": "ae2040df-0f95-4701-c680-8bbb7be92bcd",
"colab": { "colab": {
"base_uri": "https://localhost:8080/" "base_uri": "https://localhost:8080/"
} }
@ -169,26 +165,26 @@
"# Validate YOLOv8n on COCO128 val\n", "# Validate YOLOv8n on COCO128 val\n",
"!yolo val model=yolov8n.pt data=coco128.yaml" "!yolo val model=yolov8n.pt data=coco128.yaml"
], ],
"execution_count": null, "execution_count": 4,
"outputs": [ "outputs": [
{ {
"output_type": "stream", "output_type": "stream",
"name": "stdout", "name": "stdout",
"text": [ "text": [
"Ultralytics YOLOv8.0.24 🚀 Python-3.8.10 torch-1.13.1+cu116 CUDA:0 (Tesla T4, 15110MiB)\n", "Ultralytics YOLOv8.0.57 🚀 Python-3.9.16 torch-1.13.1+cu116 CUDA:0 (Tesla T4, 15102MiB)\n",
"YOLOv8n summary (fused): 168 layers, 3151904 parameters, 0 gradients, 8.7 GFLOPs\n", "YOLOv8n summary (fused): 168 layers, 3151904 parameters, 0 gradients, 8.7 GFLOPs\n",
"\n", "\n",
"Dataset 'coco128.yaml' not found ⚠️, missing paths ['/content/datasets/coco128/images/train2017']\n", "Dataset 'coco128.yaml' images not found ⚠️, missing paths ['/content/datasets/coco128/images/train2017']\n",
"Downloading https://ultralytics.com/assets/coco128.zip to /content/datasets/coco128.zip...\n", "Downloading https://ultralytics.com/assets/coco128.zip to /content/datasets/coco128.zip...\n",
"100% 6.66M/6.66M [00:00<00:00, 50.5MB/s]\n", "100% 6.66M/6.66M [00:00<00:00, 87.2MB/s]\n",
"Unzipping /content/datasets/coco128.zip...\n", "Unzipping /content/datasets/coco128.zip to /content/datasets...\n",
"Dataset download success ✅ (0.5s), saved to \u001b[1m/content/datasets\u001b[0m\n", "Dataset download success ✅ (0.4s), saved to \u001b[1m/content/datasets\u001b[0m\n",
"\n", "\n",
"Downloading https://ultralytics.com/assets/Arial.ttf to /root/.config/Ultralytics/Arial.ttf...\n", "Downloading https://ultralytics.com/assets/Arial.ttf to /root/.config/Ultralytics/Arial.ttf...\n",
"100% 755k/755k [00:00<00:00, 99.8MB/s]\n", "100% 755k/755k [00:00<00:00, 16.9MB/s]\n",
"\u001b[34m\u001b[1mval: \u001b[0mScanning /content/datasets/coco128/labels/train2017... 126 images, 2 backgrounds, 0 corrupt: 100% 128/128 [00:00<00:00, 1290.29it/s]\n", "\u001b[34m\u001b[1mval: \u001b[0mScanning /content/datasets/coco128/labels/train2017... 126 images, 2 backgrounds, 0 corrupt: 100% 128/128 [00:00<00:00, 2007.12it/s]\n",
"\u001b[34m\u001b[1mval: \u001b[0mNew cache created: /content/datasets/coco128/labels/train2017.cache\n", "\u001b[34m\u001b[1mval: \u001b[0mNew cache created: /content/datasets/coco128/labels/train2017.cache\n",
" Class Images Instances Box(P R mAP50 mAP50-95): 100% 8/8 [00:06<00:00, 1.22it/s]\n", " Class Images Instances Box(P R mAP50 mAP50-95): 100% 8/8 [00:08<00:00, 1.04s/it]\n",
" all 128 929 0.64 0.537 0.605 0.446\n", " all 128 929 0.64 0.537 0.605 0.446\n",
" person 128 254 0.797 0.677 0.764 0.538\n", " person 128 254 0.797 0.677 0.764 0.538\n",
" bicycle 128 6 0.514 0.333 0.315 0.264\n", " bicycle 128 6 0.514 0.333 0.315 0.264\n",
@ -261,7 +257,8 @@
" scissors 128 1 1 0 0.249 0.0746\n", " scissors 128 1 1 0 0.249 0.0746\n",
" teddy bear 128 21 0.877 0.333 0.591 0.394\n", " teddy bear 128 21 0.877 0.333 0.591 0.394\n",
" toothbrush 128 5 0.743 0.6 0.638 0.374\n", " toothbrush 128 5 0.743 0.6 0.638 0.374\n",
"Speed: 2.4ms preprocess, 7.8ms inference, 0.0ms loss, 3.3ms postprocess per image\n" "Speed: 2.9ms preprocess, 6.2ms inference, 0.0ms loss, 5.1ms postprocess per image\n",
"Results saved to \u001b[1mruns/detect/val\u001b[0m\n"
] ]
} }
] ]
@ -283,7 +280,7 @@
"cell_type": "code", "cell_type": "code",
"metadata": { "metadata": {
"id": "1NcFxRcFdJ_O", "id": "1NcFxRcFdJ_O",
"outputId": "e0978a9a-ef1d-4a20-8082-19c8049d8c7e", "outputId": "fcb5e3da-3766-4c72-97e1-73c1bd2ccbef",
"colab": { "colab": {
"base_uri": "https://localhost:8080/" "base_uri": "https://localhost:8080/"
} }
@ -292,14 +289,14 @@
"# Train YOLOv8n on COCO128 for 3 epochs\n", "# Train YOLOv8n on COCO128 for 3 epochs\n",
"!yolo train model=yolov8n.pt data=coco128.yaml epochs=3 imgsz=640" "!yolo train model=yolov8n.pt data=coco128.yaml epochs=3 imgsz=640"
], ],
"execution_count": null, "execution_count": 5,
"outputs": [ "outputs": [
{ {
"output_type": "stream", "output_type": "stream",
"name": "stdout", "name": "stdout",
"text": [ "text": [
"Ultralytics YOLOv8.0.24 🚀 Python-3.8.10 torch-1.13.1+cu116 CUDA:0 (Tesla T4, 15110MiB)\n", "Ultralytics YOLOv8.0.57 🚀 Python-3.9.16 torch-1.13.1+cu116 CUDA:0 (Tesla T4, 15102MiB)\n",
"\u001b[34m\u001b[1myolo/engine/trainer: \u001b[0mtask=detect, mode=train, model=yolov8n.pt, data=coco128.yaml, epochs=3, patience=50, batch=16, imgsz=640, save=True, cache=False, device=None, workers=8, project=None, name=None, exist_ok=False, pretrained=False, optimizer=SGD, verbose=True, seed=0, deterministic=True, single_cls=False, image_weights=False, rect=False, cos_lr=False, close_mosaic=10, resume=False, overlap_mask=True, mask_ratio=4, dropout=0.0, val=True, save_json=False, save_hybrid=False, conf=None, iou=0.7, max_det=300, half=False, dnn=False, plots=True, source=None, show=False, save_txt=False, save_conf=False, save_crop=False, hide_labels=False, hide_conf=False, vid_stride=1, line_thickness=3, visualize=False, augment=False, agnostic_nms=False, classes=None, retina_masks=False, boxes=True, format=torchscript, keras=False, optimize=False, int8=False, dynamic=False, simplify=False, opset=None, workspace=4, nms=False, lr0=0.01, lrf=0.01, momentum=0.937, weight_decay=0.0005, warmup_epochs=3.0, warmup_momentum=0.8, warmup_bias_lr=0.1, box=7.5, cls=0.5, dfl=1.5, fl_gamma=0.0, label_smoothing=0.0, nbs=64, hsv_h=0.015, hsv_s=0.7, hsv_v=0.4, degrees=0.0, translate=0.1, scale=0.5, shear=0.0, perspective=0.0, flipud=0.0, fliplr=0.5, mosaic=1.0, mixup=0.0, copy_paste=0.0, cfg=None, v5loader=False, save_dir=runs/detect/train\n", "\u001b[34m\u001b[1myolo/engine/trainer: \u001b[0mtask=detect, mode=train, model=yolov8n.pt, data=coco128.yaml, epochs=3, patience=50, batch=16, imgsz=640, save=True, save_period=-1, cache=False, device=None, workers=8, project=None, name=None, exist_ok=False, pretrained=False, optimizer=SGD, verbose=True, seed=0, deterministic=True, single_cls=False, image_weights=False, rect=False, cos_lr=False, close_mosaic=10, resume=False, amp=True, overlap_mask=True, mask_ratio=4, dropout=0.0, val=True, split=val, save_json=False, save_hybrid=False, conf=None, iou=0.7, max_det=300, half=False, dnn=False, plots=True, source=None, show=False, save_txt=False, save_conf=False, save_crop=False, hide_labels=False, hide_conf=False, vid_stride=1, line_thickness=3, visualize=False, augment=False, agnostic_nms=False, classes=None, retina_masks=False, boxes=True, format=torchscript, keras=False, optimize=False, int8=False, dynamic=False, simplify=False, opset=None, workspace=4, nms=False, lr0=0.01, lrf=0.01, momentum=0.937, weight_decay=0.0005, warmup_epochs=3.0, warmup_momentum=0.8, warmup_bias_lr=0.1, box=7.5, cls=0.5, dfl=1.5, fl_gamma=0.0, label_smoothing=0.0, nbs=64, hsv_h=0.015, hsv_s=0.7, hsv_v=0.4, degrees=0.0, translate=0.1, scale=0.5, shear=0.0, perspective=0.0, flipud=0.0, fliplr=0.5, mosaic=1.0, mixup=0.0, copy_paste=0.0, cfg=None, v5loader=False, tracker=botsort.yaml, save_dir=runs/detect/train\n",
"\n", "\n",
" from n params module arguments \n", " from n params module arguments \n",
" 0 -1 1 464 ultralytics.nn.modules.Conv [3, 16, 3, 2] \n", " 0 -1 1 464 ultralytics.nn.modules.Conv [3, 16, 3, 2] \n",
@ -328,111 +325,120 @@
"Model summary: 225 layers, 3157200 parameters, 3157184 gradients, 8.9 GFLOPs\n", "Model summary: 225 layers, 3157200 parameters, 3157184 gradients, 8.9 GFLOPs\n",
"\n", "\n",
"Transferred 355/355 items from pretrained weights\n", "Transferred 355/355 items from pretrained weights\n",
"2023-03-26 14:57:47.224672: I tensorflow/core/platform/cpu_feature_guard.cc:193] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 FMA\n",
"To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n",
"2023-03-26 14:57:48.209047: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7'; dlerror: libnvinfer.so.7: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/local/lib/python3.9/dist-packages/cv2/../../lib64:/usr/local/lib/python3.9/dist-packages/cv2/../../lib64:/usr/lib64-nvidia\n",
"2023-03-26 14:57:48.209179: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7'; dlerror: libnvinfer_plugin.so.7: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/local/lib/python3.9/dist-packages/cv2/../../lib64:/usr/local/lib/python3.9/dist-packages/cv2/../../lib64:/usr/lib64-nvidia\n",
"2023-03-26 14:57:48.209199: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.\n",
"\u001b[34m\u001b[1mTensorBoard: \u001b[0mStart with 'tensorboard --logdir runs/detect/train', view at http://localhost:6006/\n",
"\u001b[34m\u001b[1mAMP: \u001b[0mrunning Automatic Mixed Precision (AMP) checks with YOLOv8n...\n",
"\u001b[34m\u001b[1mAMP: \u001b[0mchecks passed ✅\n",
"\u001b[34m\u001b[1moptimizer:\u001b[0m SGD(lr=0.01) with parameter groups 57 weight(decay=0.0), 64 weight(decay=0.0005), 63 bias\n", "\u001b[34m\u001b[1moptimizer:\u001b[0m SGD(lr=0.01) with parameter groups 57 weight(decay=0.0), 64 weight(decay=0.0005), 63 bias\n",
"\u001b[34m\u001b[1mtrain: \u001b[0mScanning /content/datasets/coco128/labels/train2017.cache... 126 images, 2 backgrounds, 0 corrupt: 100% 128/128 [00:00<?, ?it/s]\n", "\u001b[34m\u001b[1mtrain: \u001b[0mScanning /content/datasets/coco128/labels/train2017.cache... 126 images, 2 backgrounds, 0 corrupt: 100% 128/128 [00:00<?, ?it/s]\n",
"\u001b[34m\u001b[1malbumentations: \u001b[0mBlur(p=0.01, blur_limit=(3, 7)), MedianBlur(p=0.01, blur_limit=(3, 7)), ToGray(p=0.01), CLAHE(p=0.01, clip_limit=(1, 4.0), tile_grid_size=(8, 8))\n", "\u001b[34m\u001b[1malbumentations: \u001b[0mBlur(p=0.01, blur_limit=(3, 7)), MedianBlur(p=0.01, blur_limit=(3, 7)), ToGray(p=0.01), CLAHE(p=0.01, clip_limit=(1, 4.0), tile_grid_size=(8, 8))\n",
"\u001b[34m\u001b[1mval: \u001b[0mScanning /content/datasets/coco128/labels/train2017.cache... 126 images, 2 backgrounds, 0 corrupt: 100% 128/128 [00:00<?, ?it/s]\n", "\u001b[34m\u001b[1mval: \u001b[0mScanning /content/datasets/coco128/labels/train2017.cache... 126 images, 2 backgrounds, 0 corrupt: 100% 128/128 [00:00<?, ?it/s]\n",
"Plotting labels to runs/detect/train/labels.jpg... \n",
"Image sizes 640 train, 640 val\n", "Image sizes 640 train, 640 val\n",
"Using 2 dataloader workers\n", "Using 2 dataloader workers\n",
"Logging results to \u001b[1mruns/detect/train\u001b[0m\n", "Logging results to \u001b[1mruns/detect/train\u001b[0m\n",
"Starting training for 3 epochs...\n", "Starting training for 3 epochs...\n",
"\n", "\n",
" Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size\n", " Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size\n",
" 1/3 4.31G 1.221 1.429 1.241 196 640: 100% 8/8 [00:08<00:00, 1.01s/it]\n", " 1/3 2.77G 1.221 1.429 1.241 196 640: 100% 8/8 [00:10<00:00, 1.34s/it]\n",
" Class Images Instances Box(P R mAP50 mAP50-95): 100% 4/4 [00:01<00:00, 2.18it/s]\n", " Class Images Instances Box(P R mAP50 mAP50-95): 100% 4/4 [00:02<00:00, 1.70it/s]\n",
" all 128 929 0.671 0.516 0.617 0.457\n", " all 128 929 0.674 0.517 0.616 0.456\n",
"\n", "\n",
" Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size\n", " Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size\n",
" 2/3 5.31G 1.186 1.306 1.255 287 640: 100% 8/8 [00:04<00:00, 1.63it/s]\n", " 2/3 3.61G 1.186 1.306 1.255 287 640: 100% 8/8 [00:05<00:00, 1.58it/s]\n",
" Class Images Instances Box(P R mAP50 mAP50-95): 100% 4/4 [00:01<00:00, 2.23it/s]\n", " Class Images Instances Box(P R mAP50 mAP50-95): 100% 4/4 [00:02<00:00, 1.83it/s]\n",
" all 128 929 0.668 0.582 0.637 0.473\n", " all 128 929 0.644 0.599 0.638 0.473\n",
"\n", "\n",
" Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size\n", " Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size\n",
" 3/3 5.31G 1.17 1.408 1.267 189 640: 100% 8/8 [00:04<00:00, 1.64it/s]\n", " 3/3 3.61G 1.169 1.405 1.266 189 640: 100% 8/8 [00:04<00:00, 1.65it/s]\n",
" Class Images Instances Box(P R mAP50 mAP50-95): 100% 4/4 [00:03<00:00, 1.03it/s]\n", " Class Images Instances Box(P R mAP50 mAP50-95): 100% 4/4 [00:06<00:00, 1.59s/it]\n",
" all 128 929 0.638 0.601 0.645 0.483\n", " all 128 929 0.63 0.607 0.641 0.48\n",
"\n", "\n",
"3 epochs completed in 0.009 hours.\n", "3 epochs completed in 0.011 hours.\n",
"Optimizer stripped from runs/detect/train/weights/last.pt, 6.5MB\n", "Optimizer stripped from runs/detect/train/weights/last.pt, 6.5MB\n",
"Optimizer stripped from runs/detect/train/weights/best.pt, 6.5MB\n", "Optimizer stripped from runs/detect/train/weights/best.pt, 6.5MB\n",
"\n", "\n",
"Validating runs/detect/train/weights/best.pt...\n", "Validating runs/detect/train/weights/best.pt...\n",
"Ultralytics YOLOv8.0.24 🚀 Python-3.8.10 torch-1.13.1+cu116 CUDA:0 (Tesla T4, 15110MiB)\n", "Ultralytics YOLOv8.0.57 🚀 Python-3.9.16 torch-1.13.1+cu116 CUDA:0 (Tesla T4, 15102MiB)\n",
"Model summary (fused): 168 layers, 3151904 parameters, 0 gradients, 8.7 GFLOPs\n", "Model summary (fused): 168 layers, 3151904 parameters, 0 gradients, 8.7 GFLOPs\n",
" Class Images Instances Box(P R mAP50 mAP50-95): 100% 4/4 [00:04<00:00, 1.05s/it]\n", " Class Images Instances Box(P R mAP50 mAP50-95): 100% 4/4 [00:06<00:00, 1.66s/it]\n",
" all 128 929 0.638 0.602 0.644 0.483\n", " all 128 929 0.632 0.597 0.639 0.479\n",
" person 128 254 0.703 0.709 0.769 0.548\n", " person 128 254 0.708 0.693 0.766 0.55\n",
" bicycle 128 6 0.455 0.333 0.322 0.254\n", " bicycle 128 6 0.458 0.333 0.323 0.254\n",
" car 128 46 0.773 0.217 0.291 0.184\n", " car 128 46 0.763 0.217 0.287 0.181\n",
" motorcycle 128 5 0.551 0.8 0.895 0.724\n", " motorcycle 128 5 0.542 0.8 0.895 0.727\n",
" airplane 128 6 0.743 0.833 0.927 0.73\n", " airplane 128 6 0.744 0.833 0.903 0.695\n",
" bus 128 7 0.692 0.714 0.7 0.636\n", " bus 128 7 0.699 0.714 0.724 0.64\n",
" train 128 3 0.733 0.931 0.913 0.797\n", " train 128 3 0.73 0.919 0.913 0.797\n",
" truck 128 12 0.752 0.5 0.497 0.324\n", " truck 128 12 0.747 0.5 0.497 0.324\n",
" boat 128 6 0.41 0.333 0.492 0.344\n", " boat 128 6 0.365 0.333 0.393 0.291\n",
" traffic light 128 14 0.682 0.214 0.202 0.139\n", " traffic light 128 14 0.708 0.214 0.202 0.139\n",
" stop sign 128 2 0.933 1 0.995 0.671\n", " stop sign 128 2 1 0.953 0.995 0.666\n",
" bench 128 9 0.752 0.556 0.603 0.416\n", " bench 128 9 0.754 0.556 0.606 0.412\n",
" bird 128 16 0.875 0.876 0.957 0.641\n", " bird 128 16 0.929 0.819 0.948 0.643\n",
" cat 128 4 0.863 1 0.995 0.76\n", " cat 128 4 0.864 1 0.995 0.778\n",
" dog 128 9 0.554 0.778 0.855 0.664\n", " dog 128 9 0.598 0.828 0.834 0.627\n",
" horse 128 2 0.706 1 0.995 0.561\n", " horse 128 2 0.679 1 0.995 0.547\n",
" elephant 128 17 0.761 0.882 0.929 0.722\n", " elephant 128 17 0.757 0.882 0.929 0.722\n",
" bear 128 1 0.595 1 0.995 0.995\n", " bear 128 1 0.593 1 0.995 0.995\n",
" zebra 128 4 0.85 1 0.995 0.966\n", " zebra 128 4 0.851 1 0.995 0.966\n",
" giraffe 128 9 0.891 1 0.995 0.683\n", " giraffe 128 9 0.838 1 0.984 0.681\n",
" backpack 128 6 0.487 0.333 0.354 0.224\n", " backpack 128 6 0.473 0.333 0.342 0.217\n",
" umbrella 128 18 0.54 0.667 0.687 0.461\n", " umbrella 128 18 0.569 0.667 0.708 0.454\n",
" handbag 128 19 0.496 0.105 0.212 0.125\n", " handbag 128 19 0.649 0.105 0.233 0.137\n",
" tie 128 7 0.611 0.714 0.615 0.432\n", " tie 128 7 0.608 0.714 0.614 0.428\n",
" suitcase 128 4 0.469 1 0.745 0.529\n", " suitcase 128 4 0.471 1 0.745 0.54\n",
" frisbee 128 5 0.622 0.8 0.733 0.64\n", " frisbee 128 5 0.629 0.8 0.732 0.64\n",
" skis 128 1 0.721 1 0.995 0.531\n", " skis 128 1 0.699 1 0.995 0.522\n",
" snowboard 128 7 0.687 0.714 0.751 0.51\n", " snowboard 128 7 0.654 0.714 0.758 0.497\n",
" sports ball 128 6 0.71 0.42 0.503 0.282\n", " sports ball 128 6 0.707 0.415 0.515 0.288\n",
" kite 128 10 0.81 0.5 0.59 0.197\n", " kite 128 10 0.687 0.4 0.561 0.207\n",
" baseball bat 128 4 0.474 0.461 0.261 0.115\n", " baseball bat 128 4 0.439 0.409 0.263 0.114\n",
" baseball glove 128 7 0.67 0.429 0.43 0.317\n", " baseball glove 128 7 0.679 0.429 0.43 0.317\n",
" skateboard 128 5 0.751 0.6 0.599 0.387\n", " skateboard 128 5 0.738 0.6 0.599 0.386\n",
" tennis racket 128 7 0.742 0.415 0.507 0.378\n", " tennis racket 128 7 0.738 0.408 0.493 0.371\n",
" bottle 128 18 0.409 0.333 0.354 0.235\n", " bottle 128 18 0.44 0.333 0.377 0.247\n",
" wine glass 128 16 0.562 0.5 0.597 0.356\n", " wine glass 128 16 0.545 0.5 0.596 0.358\n",
" cup 128 36 0.67 0.306 0.411 0.296\n", " cup 128 36 0.651 0.278 0.412 0.297\n",
" fork 128 6 0.57 0.167 0.229 0.203\n", " fork 128 6 0.568 0.167 0.229 0.202\n",
" knife 128 16 0.608 0.562 0.634 0.405\n", " knife 128 16 0.557 0.562 0.628 0.399\n",
" spoon 128 22 0.529 0.358 0.369 0.201\n", " spoon 128 22 0.471 0.318 0.369 0.214\n",
" bowl 128 28 0.594 0.679 0.671 0.56\n", " bowl 128 28 0.611 0.679 0.671 0.547\n",
" banana 128 1 0.0625 0.312 0.199 0.0513\n", " banana 128 1 0.0573 0.286 0.199 0.0522\n",
" sandwich 128 2 0.638 0.913 0.828 0.828\n", " sandwich 128 2 0.377 0.5 0.745 0.745\n",
" orange 128 4 0.743 0.728 0.895 0.595\n", " orange 128 4 0.743 0.729 0.895 0.595\n",
" broccoli 128 11 0.49 0.264 0.278 0.232\n", " broccoli 128 11 0.491 0.265 0.281 0.233\n",
" carrot 128 24 0.547 0.667 0.704 0.47\n", " carrot 128 24 0.548 0.667 0.694 0.465\n",
" hot dog 128 2 0.578 1 0.828 0.796\n", " hot dog 128 2 0.586 1 0.828 0.796\n",
" pizza 128 5 0.835 1 0.995 0.84\n", " pizza 128 5 0.873 1 0.995 0.798\n",
" donut 128 14 0.537 1 0.891 0.788\n", " donut 128 14 0.554 1 0.891 0.786\n",
" cake 128 4 0.807 1 0.995 0.904\n", " cake 128 4 0.806 1 0.995 0.904\n",
" chair 128 35 0.401 0.514 0.485 0.277\n", " chair 128 35 0.408 0.514 0.469 0.267\n",
" couch 128 6 0.795 0.649 0.746 0.504\n", " couch 128 6 0.517 0.5 0.655 0.463\n",
" potted plant 128 14 0.563 0.643 0.676 0.471\n", " potted plant 128 14 0.564 0.643 0.673 0.467\n",
" bed 128 3 0.777 1 0.995 0.735\n", " bed 128 3 0.72 1 0.995 0.734\n",
" dining table 128 13 0.425 0.692 0.578 0.48\n", " dining table 128 13 0.433 0.692 0.58 0.48\n",
" toilet 128 2 0.508 0.5 0.745 0.721\n", " toilet 128 2 0.508 0.5 0.745 0.721\n",
" tv 128 2 0.55 0.649 0.828 0.762\n", " tv 128 2 0.563 0.689 0.828 0.762\n",
" laptop 128 3 1 0 0.741 0.653\n", " laptop 128 3 1 0.455 0.747 0.657\n",
" mouse 128 2 1 0 0.0454 0.00907\n", " mouse 128 2 1 0 0.0405 0.0081\n",
" remote 128 8 0.83 0.5 0.569 0.449\n", " remote 128 8 0.832 0.5 0.574 0.445\n",
" cell phone 128 8 0 0 0.0819 0.0266\n", " cell phone 128 8 0 0 0.0724 0.0315\n",
" microwave 128 3 0.475 0.667 0.83 0.699\n", " microwave 128 3 0.496 0.667 0.806 0.685\n",
" oven 128 5 0.5 0.4 0.348 0.275\n", " oven 128 5 0.501 0.4 0.345 0.273\n",
" sink 128 6 0.354 0.187 0.368 0.217\n", " sink 128 6 0.379 0.212 0.366 0.21\n",
" refrigerator 128 5 0.518 0.4 0.729 0.571\n", " refrigerator 128 5 0.612 0.4 0.77 0.608\n",
" book 128 29 0.583 0.241 0.396 0.204\n", " book 128 29 0.553 0.207 0.387 0.2\n",
" clock 128 9 0.891 0.889 0.91 0.773\n", " clock 128 9 0.88 0.889 0.907 0.772\n",
" vase 128 2 0.506 1 0.828 0.745\n", " vase 128 2 0.508 1 0.828 0.745\n",
" scissors 128 1 1 0 0.142 0.0426\n", " scissors 128 1 1 0 0.142 0.0426\n",
" teddy bear 128 21 0.587 0.476 0.63 0.458\n", " teddy bear 128 21 0.662 0.476 0.603 0.442\n",
" toothbrush 128 5 0.784 0.736 0.898 0.544\n", " toothbrush 128 5 0.792 0.768 0.898 0.574\n",
"Speed: 2.0ms preprocess, 4.0ms inference, 0.0ms loss, 2.5ms postprocess per image\n", "Speed: 1.1ms preprocess, 5.4ms inference, 0.0ms loss, 2.9ms postprocess per image\n",
"Results saved to \u001b[1mruns/detect/train\u001b[0m\n" "Results saved to \u001b[1mruns/detect/train\u001b[0m\n"
] ]
} }
@ -479,26 +485,26 @@
"base_uri": "https://localhost:8080/" "base_uri": "https://localhost:8080/"
}, },
"id": "CYIjW4igCjqD", "id": "CYIjW4igCjqD",
"outputId": "69cab2fb-cbfa-4acf-8e29-9c4fb6f4a38f" "outputId": "49b5bb9d-2c16-415b-c3e7-ec95c15a9e62"
}, },
"execution_count": null, "execution_count": 6,
"outputs": [ "outputs": [
{ {
"output_type": "stream", "output_type": "stream",
"name": "stdout", "name": "stdout",
"text": [ "text": [
"Ultralytics YOLOv8.0.24 🚀 Python-3.8.10 torch-1.13.1+cu116 CPU\n", "Ultralytics YOLOv8.0.57 🚀 Python-3.9.16 torch-1.13.1+cu116 CPU\n",
"YOLOv8n summary (fused): 168 layers, 3151904 parameters, 0 gradients, 8.7 GFLOPs\n", "YOLOv8n summary (fused): 168 layers, 3151904 parameters, 0 gradients, 8.7 GFLOPs\n",
"\n", "\n",
"\u001b[34m\u001b[1mPyTorch:\u001b[0m starting from yolov8n.pt with output shape (1, 84, 8400) (6.2 MB)\n", "\u001b[34m\u001b[1mPyTorch:\u001b[0m starting from yolov8n.pt with input shape (1, 3, 640, 640) BCHW and output shape(s) (1, 84, 8400) (6.2 MB)\n",
"\n", "\n",
"\u001b[34m\u001b[1mTorchScript:\u001b[0m starting export with torch 1.13.1+cu116...\n", "\u001b[34m\u001b[1mTorchScript:\u001b[0m starting export with torch 1.13.1+cu116...\n",
"\u001b[34m\u001b[1mTorchScript:\u001b[0m export success ✅ 1.7s, saved as yolov8n.torchscript (12.4 MB)\n", "\u001b[34m\u001b[1mTorchScript:\u001b[0m export success ✅ 1.9s, saved as yolov8n.torchscript (12.4 MB)\n",
"\n", "\n",
"Export complete (2.2s)\n", "Export complete (2.6s)\n",
"Results saved to \u001b[1m/content\u001b[0m\n", "Results saved to \u001b[1m/content\u001b[0m\n",
"Predict: yolo task=detect mode=predict model=yolov8n.torchscript -WARNING ⚠️ not yet supported for YOLOv8 exported models\n", "Predict: yolo predict task=detect model=yolov8n.torchscript imgsz=640 \n",
"Validate: yolo task=detect mode=val model=yolov8n.torchscript -WARNING ⚠️ not yet supported for YOLOv8 exported models\n", "Validate: yolo val task=detect model=yolov8n.torchscript imgsz=640 data=coco.yaml \n",
"Visualize: https://netron.app\n" "Visualize: https://netron.app\n"
] ]
} }

@ -1,6 +1,6 @@
# Ultralytics YOLO 🚀, GPL-3.0 license # Ultralytics YOLO 🚀, GPL-3.0 license
__version__ = '8.0.57' __version__ = '8.0.58'
from ultralytics.yolo.engine.model import YOLO from ultralytics.yolo.engine.model import YOLO
from ultralytics.yolo.utils.checks import check_yolo as checks from ultralytics.yolo.utils.checks import check_yolo as checks

@ -25,8 +25,8 @@ def check_class_names(names):
if isinstance(names, list): # names is a list if isinstance(names, list): # names is a list
names = dict(enumerate(names)) # convert to dict names = dict(enumerate(names)) # convert to dict
if isinstance(names, dict): if isinstance(names, dict):
if not all(isinstance(k, int) for k in names.keys()): # convert string keys to int, i.e. '0' to 0 # convert 1) string keys to int, i.e. '0' to 0, and non-string values to strings, i.e. True to 'True'
names = {int(k): v for k, v in names.items()} names = {int(k): str(v) for k, v in names.items()}
n = len(names) n = len(names)
if max(names.keys()) >= n: if max(names.keys()) >= n:
raise KeyError(f'{n}-class dataset requires class indices 0-{n - 1}, but you have invalid class indices ' raise KeyError(f'{n}-class dataset requires class indices 0-{n - 1}, but you have invalid class indices '

@ -245,7 +245,7 @@ class SegmentationModel(DetectionModel):
super().__init__(cfg, ch, nc, verbose) super().__init__(cfg, ch, nc, verbose)
def _forward_augment(self, x): def _forward_augment(self, x):
raise NotImplementedError('WARNING ⚠️ SegmentationModel has not supported augment inference yet!') raise NotImplementedError(emojis('WARNING ⚠️ SegmentationModel has not supported augment inference yet!'))
class ClassificationModel(BaseModel): class ClassificationModel(BaseModel):

@ -3,9 +3,7 @@
import torch import torch
from ultralytics.yolo.utils import IterableSimpleNamespace, yaml_load from ultralytics.yolo.utils import IterableSimpleNamespace, yaml_load
from ultralytics.yolo.utils.checks import check_requirements, check_yaml from ultralytics.yolo.utils.checks import check_yaml
check_requirements('lap') # for linear_assignment
from .trackers import BOTSORT, BYTETracker from .trackers import BOTSORT, BYTETracker

@ -1,12 +1,20 @@
# Ultralytics YOLO 🚀, GPL-3.0 license # Ultralytics YOLO 🚀, GPL-3.0 license
import lap
import numpy as np import numpy as np
import scipy import scipy
from scipy.spatial.distance import cdist from scipy.spatial.distance import cdist
from .kalman_filter import chi2inv95 from .kalman_filter import chi2inv95
try:
import lap # for linear_assignment
assert lap.__version__ # verify package is not directory
except (ImportError, AssertionError, AttributeError):
from ultralytics.yolo.utils.checks import check_requirements
check_requirements('lap>=0.4') # install
import lap
def merge_matches(m1, m2, shape): def merge_matches(m1, m2, shape):
O, P, Q = shape O, P, Q = shape

@ -12,8 +12,8 @@ import numpy as np
from torch.utils.data import Dataset from torch.utils.data import Dataset
from tqdm import tqdm from tqdm import tqdm
from ..utils import NUM_THREADS, TQDM_BAR_FORMAT from ..utils import LOCAL_RANK, NUM_THREADS, TQDM_BAR_FORMAT
from .utils import HELP_URL, IMG_FORMATS, LOCAL_RANK from .utils import HELP_URL, IMG_FORMATS
class BaseDataset(Dataset): class BaseDataset(Dataset):

@ -14,10 +14,10 @@ from ultralytics.yolo.data.dataloaders.stream_loaders import (LOADERS, LoadImage
from ultralytics.yolo.data.utils import IMG_FORMATS, VID_FORMATS from ultralytics.yolo.data.utils import IMG_FORMATS, VID_FORMATS
from ultralytics.yolo.utils.checks import check_file from ultralytics.yolo.utils.checks import check_file
from ..utils import LOGGER, colorstr from ..utils import LOGGER, RANK, colorstr
from ..utils.torch_utils import torch_distributed_zero_first from ..utils.torch_utils import torch_distributed_zero_first
from .dataset import ClassificationDataset, YOLODataset from .dataset import ClassificationDataset, YOLODataset
from .utils import PIN_MEMORY, RANK from .utils import PIN_MEMORY
class InfiniteDataLoader(dataloader.DataLoader): class InfiniteDataLoader(dataloader.DataLoader):

@ -335,6 +335,7 @@ class LoadTensor:
def __init__(self, imgs) -> None: def __init__(self, imgs) -> None:
self.im0 = imgs self.im0 = imgs
self.bs = imgs.shape[0] self.bs = imgs.shape[0]
self.mode = 'image'
def __iter__(self): def __iter__(self):
self.count = 0 self.count = 0
@ -346,6 +347,9 @@ class LoadTensor:
self.count += 1 self.count += 1
return None, self.im0, self.im0, None, '' # self.paths, im, self.im0, None, '' return None, self.im0, self.im0, None, '' # self.paths, im, self.im0, None, ''
def __len__(self):
return self.bs
def autocast_list(source): def autocast_list(source):
""" """

@ -10,10 +10,10 @@ import torch
import torchvision import torchvision
from tqdm import tqdm from tqdm import tqdm
from ..utils import NUM_THREADS, TQDM_BAR_FORMAT, is_dir_writeable from ..utils import LOCAL_RANK, NUM_THREADS, TQDM_BAR_FORMAT, is_dir_writeable
from .augment import Compose, Format, Instances, LetterBox, classify_albumentations, classify_transforms, v8_transforms from .augment import Compose, Format, Instances, LetterBox, classify_albumentations, classify_transforms, v8_transforms
from .base import BaseDataset from .base import BaseDataset
from .utils import HELP_URL, LOCAL_RANK, LOGGER, get_hash, img2label_paths, verify_image_label from .utils import HELP_URL, LOGGER, get_hash, img2label_paths, verify_image_label
class YOLODataset(BaseDataset): class YOLODataset(BaseDataset):

@ -25,8 +25,6 @@ from ultralytics.yolo.utils.ops import segments2boxes
HELP_URL = 'See https://github.com/ultralytics/yolov5/wiki/Train-Custom-Data' HELP_URL = 'See https://github.com/ultralytics/yolov5/wiki/Train-Custom-Data'
IMG_FORMATS = 'bmp', 'dng', 'jpeg', 'jpg', 'mpo', 'png', 'tif', 'tiff', 'webp', 'pfm' # image suffixes IMG_FORMATS = 'bmp', 'dng', 'jpeg', 'jpg', 'mpo', 'png', 'tif', 'tiff', 'webp', 'pfm' # image suffixes
VID_FORMATS = 'asf', 'avi', 'gif', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'ts', 'wmv', 'webm' # video suffixes VID_FORMATS = 'asf', 'avi', 'gif', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'ts', 'wmv', 'webm' # video suffixes
LOCAL_RANK = int(os.getenv('LOCAL_RANK', -1)) # https://pytorch.org/docs/stable/elastic/run.html
RANK = int(os.getenv('RANK', -1))
PIN_MEMORY = str(os.getenv('PIN_MEMORY', True)).lower() == 'true' # global pin_memory for dataloaders PIN_MEMORY = str(os.getenv('PIN_MEMORY', True)).lower() == 'true' # global pin_memory for dataloaders
IMAGENET_MEAN = 0.485, 0.456, 0.406 # RGB mean IMAGENET_MEAN = 0.485, 0.456, 0.406 # RGB mean
IMAGENET_STD = 0.229, 0.224, 0.225 # RGB standard deviation IMAGENET_STD = 0.229, 0.224, 0.225 # RGB standard deviation

@ -2,6 +2,7 @@
import sys import sys
from pathlib import Path from pathlib import Path
from typing import Union
from ultralytics import yolo # noqa from ultralytics import yolo # noqa
from ultralytics.nn.tasks import (ClassificationModel, DetectionModel, SegmentationModel, attempt_load_one_weight, from ultralytics.nn.tasks import (ClassificationModel, DetectionModel, SegmentationModel, attempt_load_one_weight,
@ -67,7 +68,7 @@ class YOLO:
list(ultralytics.yolo.engine.results.Results): The prediction results. list(ultralytics.yolo.engine.results.Results): The prediction results.
""" """
def __init__(self, model='yolov8n.pt', task=None, session=None) -> None: def __init__(self, model: Union[str, Path] = 'yolov8n.pt', task=None, session=None) -> None:
""" """
Initializes the YOLO model. Initializes the YOLO model.
@ -87,6 +88,7 @@ class YOLO:
self.session = session # HUB session self.session = session # HUB session
# Load or create new YOLO model # Load or create new YOLO model
model = str(model).strip() # strip spaces
suffix = Path(model).suffix suffix = Path(model).suffix
if not suffix and Path(model).stem in GITHUB_ASSET_STEMS: if not suffix and Path(model).stem in GITHUB_ASSET_STEMS:
model, suffix = Path(model).with_suffix('.pt'), '.pt' # add suffix, i.e. yolov8n -> yolov8n.pt model, suffix = Path(model).with_suffix('.pt'), '.pt' # add suffix, i.e. yolov8n -> yolov8n.pt

@ -42,6 +42,18 @@ from ultralytics.yolo.utils.checks import check_imgsz, check_imshow
from ultralytics.yolo.utils.files import increment_path from ultralytics.yolo.utils.files import increment_path
from ultralytics.yolo.utils.torch_utils import select_device, smart_inference_mode from ultralytics.yolo.utils.torch_utils import select_device, smart_inference_mode
STREAM_WARNING = """
WARNING stream/video/webcam/dir predict source will accumulate results in RAM unless `stream=True` is passed,
causing potential out-of-memory errors for large sources or long-running streams/videos.
Usage:
results = model(source=..., stream=True) # generator of Results objects
for r in results:
boxes = r.boxes # Boxes object for bbox outputs
masks = r.masks # Masks object for segment masks outputs
probs = r.probs # Class probabilities for classification outputs
"""
class BasePredictor: class BasePredictor:
""" """
@ -108,6 +120,7 @@ class BasePredictor:
return preds return preds
def __call__(self, source=None, model=None, stream=False): def __call__(self, source=None, model=None, stream=False):
self.stream = stream
if stream: if stream:
return self.stream_inference(source, model) return self.stream_inference(source, model)
else: else:
@ -132,6 +145,10 @@ class BasePredictor:
stride=self.model.stride, stride=self.model.stride,
auto=self.model.pt) auto=self.model.pt)
self.source_type = self.dataset.source_type self.source_type = self.dataset.source_type
if not getattr(self, 'stream', True) and (self.dataset.mode == 'stream' or # streams
len(self.dataset) > 1000 or # images
any(getattr(self.dataset, 'video_flag', [False]))): # videos
LOGGER.warning(STREAM_WARNING)
self.vid_path, self.vid_writer = [None] * self.dataset.bs, [None] * self.dataset.bs self.vid_path, self.vid_writer = [None] * self.dataset.bs, [None] * self.dataset.bs
@smart_inference_mode() @smart_inference_mode()

@ -5,7 +5,6 @@ Ultralytics Results, Boxes and Masks classes for handling inference results
Usage: See https://docs.ultralytics.com/modes/predict/ Usage: See https://docs.ultralytics.com/modes/predict/
""" """
import pprint
from copy import deepcopy from copy import deepcopy
from functools import lru_cache from functools import lru_cache
@ -13,11 +12,11 @@ import numpy as np
import torch import torch
import torchvision.transforms.functional as F import torchvision.transforms.functional as F
from ultralytics.yolo.utils import LOGGER, ops from ultralytics.yolo.utils import LOGGER, SimpleClass, ops
from ultralytics.yolo.utils.plotting import Annotator, colors from ultralytics.yolo.utils.plotting import Annotator, colors
class Results: class Results(SimpleClass):
""" """
A class for storing and manipulating inference results. A class for storing and manipulating inference results.
@ -96,17 +95,6 @@ class Results:
for k in self.keys: for k in self.keys:
return len(getattr(self, k)) return len(getattr(self, k))
def __str__(self):
attr = {k: v for k, v in vars(self).items() if not isinstance(v, type(self))}
return pprint.pformat(attr, indent=2, width=120, depth=10, compact=True)
def __repr__(self):
return self.__str__()
def __getattr__(self, attr):
name = self.__class__.__name__
raise AttributeError(f"'{name}' object has no attribute '{attr}'. See valid attributes below.\n{self.__doc__}")
@property @property
def keys(self): def keys(self):
return [k for k in self._keys if getattr(self, k) is not None] return [k for k in self._keys if getattr(self, k) is not None]
@ -153,7 +141,7 @@ class Results:
return np.asarray(annotator.im) if annotator.pil else annotator.im return np.asarray(annotator.im) if annotator.pil else annotator.im
class Boxes: class Boxes(SimpleClass):
""" """
A class for storing and manipulating detection boxes. A class for storing and manipulating detection boxes.
@ -242,15 +230,6 @@ class Boxes:
def pandas(self): def pandas(self):
LOGGER.info('results.pandas() method not yet implemented') LOGGER.info('results.pandas() method not yet implemented')
'''
new = copy(self) # return copy
ca = 'xmin', 'ymin', 'xmax', 'ymax', 'confidence', 'class', 'name' # xyxy columns
cb = 'xcenter', 'ycenter', 'width', 'height', 'confidence', 'class', 'name' # xywh columns
for k, c in zip(['xyxy', 'xyxyn', 'xywh', 'xywhn'], [ca, ca, cb, cb]):
a = [[x[:5] + [int(x[5]), self.names[int(x[5])]] for x in x.tolist()] for x in getattr(self, k)] # update
setattr(new, k, [pd.DataFrame(x, columns=c) for x in a])
return new
'''
@property @property
def shape(self): def shape(self):
@ -263,25 +242,11 @@ class Boxes:
def __len__(self): # override len(results) def __len__(self): # override len(results)
return len(self.boxes) return len(self.boxes)
def __str__(self):
return self.boxes.__str__()
def __repr__(self):
return (f'{self.__class__.__module__}.{self.__class__.__name__}\n'
f'type: {self.boxes.__class__.__module__}.{self.boxes.__class__.__name__}\n'
f'shape: {self.boxes.shape}\n'
f'dtype: {self.boxes.dtype}\n'
f'{self.boxes.__repr__()}')
def __getitem__(self, idx): def __getitem__(self, idx):
return Boxes(self.boxes[idx], self.orig_shape) return Boxes(self.boxes[idx], self.orig_shape)
def __getattr__(self, attr):
name = self.__class__.__name__
raise AttributeError(f"'{name}' object has no attribute '{attr}'. See valid attributes below.\n{self.__doc__}")
class Masks(SimpleClass):
class Masks:
""" """
A class for storing and manipulating detection masks. A class for storing and manipulating detection masks.
@ -301,11 +266,6 @@ class Masks:
numpy(): Returns a copy of the masks tensor as a numpy array. numpy(): Returns a copy of the masks tensor as a numpy array.
cuda(): Returns a copy of the masks tensor on GPU memory. cuda(): Returns a copy of the masks tensor on GPU memory.
to(): Returns a copy of the masks tensor with the specified device and dtype. to(): Returns a copy of the masks tensor with the specified device and dtype.
__len__(): Returns the number of masks in the tensor.
__str__(): Returns a string representation of the masks tensor.
__repr__(): Returns a detailed string representation of the masks tensor.
__getitem__(): Returns a new Masks object with the masks at the specified index.
__getattr__(): Raises an AttributeError with a list of valid attributes and properties.
""" """
def __init__(self, masks, orig_shape) -> None: def __init__(self, masks, orig_shape) -> None:
@ -342,19 +302,5 @@ class Masks:
def __len__(self): # override len(results) def __len__(self): # override len(results)
return len(self.masks) return len(self.masks)
def __str__(self):
return self.masks.__str__()
def __repr__(self):
return (f'{self.__class__.__module__}.{self.__class__.__name__}\n'
f'type: {self.masks.__class__.__module__}.{self.masks.__class__.__name__}\n'
f'shape: {self.masks.shape}\n'
f'dtype: {self.masks.dtype}\n'
f'{self.masks.__repr__()}')
def __getitem__(self, idx): def __getitem__(self, idx):
return Masks(self.masks[idx], self.orig_shape) return Masks(self.masks[idx], self.orig_shape)
def __getattr__(self, attr):
name = self.__class__.__name__
raise AttributeError(f"'{name}' object has no attribute '{attr}'. See valid attributes below.\n{self.__doc__}")

@ -174,7 +174,12 @@ class BaseTrainer:
# Run subprocess if DDP training, else train normally # Run subprocess if DDP training, else train normally
if world_size > 1 and 'LOCAL_RANK' not in os.environ: if world_size > 1 and 'LOCAL_RANK' not in os.environ:
cmd, file = generate_ddp_command(world_size, self) # security vulnerability in Snyk scans # Argument checks
if self.args.rect:
LOGGER.warning("WARNING ⚠️ 'rect=True' is incompatible with Multi-GPU training, setting rect=False")
self.args.rect = False
# Command
cmd, file = generate_ddp_command(world_size, self)
try: try:
LOGGER.info(f'Running DDP command {cmd}') LOGGER.info(f'Running DDP command {cmd}')
subprocess.run(cmd, check=True) subprocess.run(cmd, check=True)
@ -183,17 +188,15 @@ class BaseTrainer:
finally: finally:
ddp_cleanup(self, str(file)) ddp_cleanup(self, str(file))
else: else:
self._do_train(RANK, world_size) self._do_train(world_size)
def _setup_ddp(self, rank, world_size): def _setup_ddp(self, world_size):
# os.environ['MASTER_ADDR'] = 'localhost' torch.cuda.set_device(RANK)
# os.environ['MASTER_PORT'] = '9020' self.device = torch.device('cuda', RANK)
torch.cuda.set_device(rank) LOGGER.info(f'DDP settings: RANK {RANK}, WORLD_SIZE {world_size}, DEVICE {self.device}')
self.device = torch.device('cuda', rank) dist.init_process_group('nccl' if dist.is_nccl_available() else 'gloo', rank=RANK, world_size=world_size)
LOGGER.info(f'DDP settings: RANK {rank}, WORLD_SIZE {world_size}, DEVICE {self.device}')
dist.init_process_group('nccl' if dist.is_nccl_available() else 'gloo', rank=rank, world_size=world_size)
def _setup_train(self, rank, world_size): def _setup_train(self, world_size):
""" """
Builds dataloaders and optimizer on correct rank process. Builds dataloaders and optimizer on correct rank process.
""" """
@ -213,7 +216,7 @@ class BaseTrainer:
self.amp = bool(self.amp) # as boolean self.amp = bool(self.amp) # as boolean
self.scaler = amp.GradScaler(enabled=self.amp) self.scaler = amp.GradScaler(enabled=self.amp)
if world_size > 1: if world_size > 1:
self.model = DDP(self.model, device_ids=[rank]) self.model = DDP(self.model, device_ids=[RANK])
# Check imgsz # Check imgsz
gs = max(int(self.model.stride.max() if hasattr(self.model, 'stride') else 32), 32) # grid size (max stride) gs = max(int(self.model.stride.max() if hasattr(self.model, 'stride') else 32), 32) # grid size (max stride)
self.args.imgsz = check_imgsz(self.args.imgsz, stride=gs, floor=gs, max_dim=1) self.args.imgsz = check_imgsz(self.args.imgsz, stride=gs, floor=gs, max_dim=1)
@ -243,8 +246,8 @@ class BaseTrainer:
# dataloaders # dataloaders
batch_size = self.batch_size // world_size if world_size > 1 else self.batch_size batch_size = self.batch_size // world_size if world_size > 1 else self.batch_size
self.train_loader = self.get_dataloader(self.trainset, batch_size=batch_size, rank=rank, mode='train') self.train_loader = self.get_dataloader(self.trainset, batch_size=batch_size, rank=RANK, mode='train')
if rank in (-1, 0): if RANK in (-1, 0):
self.test_loader = self.get_dataloader(self.testset, batch_size=batch_size * 2, rank=-1, mode='val') self.test_loader = self.get_dataloader(self.testset, batch_size=batch_size * 2, rank=-1, mode='val')
self.validator = self.get_validator() self.validator = self.get_validator()
metric_keys = self.validator.metrics.keys + self.label_loss_items(prefix='val') metric_keys = self.validator.metrics.keys + self.label_loss_items(prefix='val')
@ -256,11 +259,11 @@ class BaseTrainer:
self.scheduler.last_epoch = self.start_epoch - 1 # do not move self.scheduler.last_epoch = self.start_epoch - 1 # do not move
self.run_callbacks('on_pretrain_routine_end') self.run_callbacks('on_pretrain_routine_end')
def _do_train(self, rank=-1, world_size=1): def _do_train(self, world_size=1):
if world_size > 1: if world_size > 1:
self._setup_ddp(rank, world_size) self._setup_ddp(world_size)
self._setup_train(rank, world_size) self._setup_train(world_size)
self.epoch_time = None self.epoch_time = None
self.epoch_time_start = time.time() self.epoch_time_start = time.time()
@ -280,7 +283,7 @@ class BaseTrainer:
self.epoch = epoch self.epoch = epoch
self.run_callbacks('on_train_epoch_start') self.run_callbacks('on_train_epoch_start')
self.model.train() self.model.train()
if rank != -1: if RANK != -1:
self.train_loader.sampler.set_epoch(epoch) self.train_loader.sampler.set_epoch(epoch)
pbar = enumerate(self.train_loader) pbar = enumerate(self.train_loader)
# Update dataloader attributes (optional) # Update dataloader attributes (optional)
@ -291,7 +294,7 @@ class BaseTrainer:
if hasattr(self.train_loader.dataset, 'close_mosaic'): if hasattr(self.train_loader.dataset, 'close_mosaic'):
self.train_loader.dataset.close_mosaic(hyp=self.args) self.train_loader.dataset.close_mosaic(hyp=self.args)
if rank in (-1, 0): if RANK in (-1, 0):
LOGGER.info(self.progress_string()) LOGGER.info(self.progress_string())
pbar = tqdm(enumerate(self.train_loader), total=nb, bar_format=TQDM_BAR_FORMAT) pbar = tqdm(enumerate(self.train_loader), total=nb, bar_format=TQDM_BAR_FORMAT)
self.tloss = None self.tloss = None
@ -315,7 +318,7 @@ class BaseTrainer:
batch = self.preprocess_batch(batch) batch = self.preprocess_batch(batch)
preds = self.model(batch['img']) preds = self.model(batch['img'])
self.loss, self.loss_items = self.criterion(preds, batch) self.loss, self.loss_items = self.criterion(preds, batch)
if rank != -1: if RANK != -1:
self.loss *= world_size self.loss *= world_size
self.tloss = (self.tloss * i + self.loss_items) / (i + 1) if self.tloss is not None \ self.tloss = (self.tloss * i + self.loss_items) / (i + 1) if self.tloss is not None \
else self.loss_items else self.loss_items
@ -332,7 +335,7 @@ class BaseTrainer:
mem = f'{torch.cuda.memory_reserved() / 1E9 if torch.cuda.is_available() else 0:.3g}G' # (GB) mem = f'{torch.cuda.memory_reserved() / 1E9 if torch.cuda.is_available() else 0:.3g}G' # (GB)
loss_len = self.tloss.shape[0] if len(self.tloss.size()) else 1 loss_len = self.tloss.shape[0] if len(self.tloss.size()) else 1
losses = self.tloss if loss_len > 1 else torch.unsqueeze(self.tloss, 0) losses = self.tloss if loss_len > 1 else torch.unsqueeze(self.tloss, 0)
if rank in (-1, 0): if RANK in (-1, 0):
pbar.set_description( pbar.set_description(
('%11s' * 2 + '%11.4g' * (2 + loss_len)) % ('%11s' * 2 + '%11.4g' * (2 + loss_len)) %
(f'{epoch + 1}/{self.epochs}', mem, *losses, batch['cls'].shape[0], batch['img'].shape[-1])) (f'{epoch + 1}/{self.epochs}', mem, *losses, batch['cls'].shape[0], batch['img'].shape[-1]))
@ -347,7 +350,7 @@ class BaseTrainer:
self.scheduler.step() self.scheduler.step()
self.run_callbacks('on_train_epoch_end') self.run_callbacks('on_train_epoch_end')
if rank in (-1, 0): if RANK in (-1, 0):
# Validation # Validation
self.ema.update_attr(self.model, include=['yaml', 'nc', 'args', 'names', 'stride', 'class_weights']) self.ema.update_attr(self.model, include=['yaml', 'nc', 'args', 'names', 'stride', 'class_weights'])
@ -377,7 +380,7 @@ class BaseTrainer:
if self.stop: if self.stop:
break # must break all DDP ranks break # must break all DDP ranks
if rank in (-1, 0): if RANK in (-1, 0):
# Do final val with best.pt # Do final val with best.pt
LOGGER.info(f'\n{epoch - self.start_epoch + 1} epochs completed in ' LOGGER.info(f'\n{epoch - self.start_epoch + 1} epochs completed in '
f'{(time.time() - self.train_time_start) / 3600:.3f} hours.') f'{(time.time() - self.train_time_start) / 3600:.3f} hours.')
@ -408,7 +411,8 @@ class BaseTrainer:
torch.save(ckpt, self.wdir / f'epoch{self.epoch}.pt') torch.save(ckpt, self.wdir / f'epoch{self.epoch}.pt')
del ckpt del ckpt
def get_dataset(self, data): @staticmethod
def get_dataset(data):
""" """
Get train, val path from data dict if it exists. Returns None if data format is not recognized. Get train, val path from data dict if it exists. Returns None if data format is not recognized.
""" """

@ -22,11 +22,15 @@ import yaml
from ultralytics import __version__ from ultralytics import __version__
# Constants # PyTorch Multi-GPU DDP Constants
RANK = int(os.getenv('RANK', -1))
LOCAL_RANK = int(os.getenv('LOCAL_RANK', -1)) # https://pytorch.org/docs/stable/elastic/run.html
WORLD_SIZE = int(os.getenv('WORLD_SIZE', 1))
# Other Constants
FILE = Path(__file__).resolve() FILE = Path(__file__).resolve()
ROOT = FILE.parents[2] # YOLO ROOT = FILE.parents[2] # YOLO
DEFAULT_CFG_PATH = ROOT / 'yolo/cfg/default.yaml' DEFAULT_CFG_PATH = ROOT / 'yolo/cfg/default.yaml'
RANK = int(os.getenv('RANK', -1))
NUM_THREADS = min(8, max(1, os.cpu_count() - 1)) # number of YOLOv5 multiprocessing threads NUM_THREADS = min(8, max(1, os.cpu_count() - 1)) # number of YOLOv5 multiprocessing threads
AUTOINSTALL = str(os.getenv('YOLO_AUTOINSTALL', True)).lower() == 'true' # global auto-install mode AUTOINSTALL = str(os.getenv('YOLO_AUTOINSTALL', True)).lower() == 'true' # global auto-install mode
VERBOSE = str(os.getenv('YOLO_VERBOSE', True)).lower() == 'true' # global verbose mode VERBOSE = str(os.getenv('YOLO_VERBOSE', True)).lower() == 'true' # global verbose mode
@ -92,25 +96,59 @@ HELP_MSG = \
""" """
# Settings # Settings
torch.set_printoptions(linewidth=320, precision=5, profile='long') torch.set_printoptions(linewidth=320, precision=4, profile='default')
np.set_printoptions(linewidth=320, formatter={'float_kind': '{:11.5g}'.format}) # format short g, %precision=5 np.set_printoptions(linewidth=320, formatter={'float_kind': '{:11.5g}'.format}) # format short g, %precision=5
cv2.setNumThreads(0) # prevent OpenCV from multithreading (incompatible with PyTorch DataLoader) cv2.setNumThreads(0) # prevent OpenCV from multithreading (incompatible with PyTorch DataLoader)
os.environ['NUMEXPR_MAX_THREADS'] = str(NUM_THREADS) # NumExpr max threads os.environ['NUMEXPR_MAX_THREADS'] = str(NUM_THREADS) # NumExpr max threads
os.environ['CUBLAS_WORKSPACE_CONFIG'] = ':4096:8' # for deterministic training os.environ['CUBLAS_WORKSPACE_CONFIG'] = ':4096:8' # for deterministic training
class SimpleClass:
"""
Ultralytics SimpleClass is a base class providing helpful string representation, error reporting, and attribute
access methods for easier debugging and usage.
"""
def __str__(self):
"""Return a human-readable string representation of the object."""
attr = []
for a in dir(self):
v = getattr(self, a)
if not callable(v) and not a.startswith('__'):
if isinstance(v, SimpleClass):
# Display only the module and class name for subclasses
s = f'{a}: {v.__module__}.{v.__class__.__name__} object'
else:
s = f'{a}: {repr(v)}'
attr.append(s)
return f'{self.__module__}.{self.__class__.__name__} object with attributes:\n\n' + '\n'.join(attr)
def __repr__(self):
"""Return a machine-readable string representation of the object."""
return self.__str__()
def __getattr__(self, attr):
"""Custom attribute access error message with helpful information."""
name = self.__class__.__name__
raise AttributeError(f"'{name}' object has no attribute '{attr}'. See valid attributes below.\n{self.__doc__}")
class IterableSimpleNamespace(SimpleNamespace): class IterableSimpleNamespace(SimpleNamespace):
""" """
Iterable SimpleNamespace class to allow SimpleNamespace to be used with dict() and in for loops Ultralytics IterableSimpleNamespace is an extension class of SimpleNamespace that adds iterable functionality and
enables usage with dict() and for loops.
""" """
def __iter__(self): def __iter__(self):
"""Return an iterator of key-value pairs from the namespace's attributes."""
return iter(vars(self).items()) return iter(vars(self).items())
def __str__(self): def __str__(self):
"""Return a human-readable string representation of the object."""
return '\n'.join(f'{k}={v}' for k, v in vars(self).items()) return '\n'.join(f'{k}={v}' for k, v in vars(self).items())
def __getattr__(self, attr): def __getattr__(self, attr):
"""Custom attribute access error message with helpful information."""
name = self.__class__.__name__ name = self.__class__.__name__
raise AttributeError(f""" raise AttributeError(f"""
'{name}' object has no attribute '{attr}'. This may be caused by a modified or out of date ultralytics '{name}' object has no attribute '{attr}'. This may be caused by a modified or out of date ultralytics
@ -120,6 +158,7 @@ class IterableSimpleNamespace(SimpleNamespace):
""") """)
def get(self, key, default=None): def get(self, key, default=None):
"""Return the value of the specified key if it exists; otherwise, return the default value."""
return getattr(self, key, default) return getattr(self, key, default)

@ -8,7 +8,7 @@ try:
assert clearml.__version__ # verify package is not directory assert clearml.__version__ # verify package is not directory
assert not TESTS_RUNNING # do not log pytest assert not TESTS_RUNNING # do not log pytest
except (ImportError, AssertionError): except (ImportError, AssertionError, AttributeError):
clearml = None clearml = None

@ -7,7 +7,7 @@ try:
assert not TESTS_RUNNING # do not log pytest assert not TESTS_RUNNING # do not log pytest
assert comet_ml.__version__ # verify package is not directory assert comet_ml.__version__ # verify package is not directory
except (ImportError, AssertionError): except (ImportError, AssertionError, AttributeError):
comet_ml = None comet_ml = None

@ -239,7 +239,7 @@ def check_suffix(file='yolov8n.pt', suffix='.pt', msg=''):
if isinstance(suffix, str): if isinstance(suffix, str):
suffix = (suffix, ) suffix = (suffix, )
for f in file if isinstance(file, (list, tuple)) else [file]: for f in file if isinstance(file, (list, tuple)) else [file]:
s = Path(f).suffix.lower() # file suffix s = Path(f).suffix.lower().strip() # file suffix
if len(s): if len(s):
assert s in suffix, f'{msg}{f} acceptable suffix is {suffix}, not {s}' assert s in suffix, f'{msg}{f} acceptable suffix is {suffix}, not {s}'
@ -261,7 +261,7 @@ def check_yolov5u_filename(file: str, verbose: bool = True):
def check_file(file, suffix='', download=True, hard=True): def check_file(file, suffix='', download=True, hard=True):
# Search/download file (if necessary) and return path # Search/download file (if necessary) and return path
check_suffix(file, suffix) # optional check_suffix(file, suffix) # optional
file = str(file) # convert to string file = str(file).strip() # convert to string and strip spaces
file = check_yolov5u_filename(file) # yolov5n -> yolov5nu file = check_yolov5u_filename(file) # yolov5n -> yolov5nu
if not file or ('://' not in file and Path(file).exists()): # exists ('://' check required in Windows Python<3.10) if not file or ('://' not in file and Path(file).exists()): # exists ('://' check required in Windows Python<3.10)
return file return file

@ -11,7 +11,7 @@ import numpy as np
import torch import torch
import torch.nn as nn import torch.nn as nn
from ultralytics.yolo.utils import LOGGER, TryExcept from ultralytics.yolo.utils import LOGGER, SimpleClass, TryExcept
# boxes # boxes
@ -425,7 +425,7 @@ def ap_per_class(tp, conf, pred_cls, target_cls, plot=False, save_dir=Path(), na
return tp, fp, p, r, f1, ap, unique_classes.astype(int) return tp, fp, p, r, f1, ap, unique_classes.astype(int)
class Metric: class Metric(SimpleClass):
""" """
Class for computing evaluation metrics for YOLOv8 model. Class for computing evaluation metrics for YOLOv8 model.
@ -461,10 +461,6 @@ class Metric:
self.ap_class_index = [] # (nc, ) self.ap_class_index = [] # (nc, )
self.nc = 0 self.nc = 0
def __getattr__(self, attr):
name = self.__class__.__name__
raise AttributeError(f"'{name}' object has no attribute '{attr}'. See valid attributes below.\n{self.__doc__}")
@property @property
def ap50(self): def ap50(self):
"""AP@0.5 of all classes. """AP@0.5 of all classes.
@ -550,7 +546,7 @@ class Metric:
self.p, self.r, self.f1, self.all_ap, self.ap_class_index = results self.p, self.r, self.f1, self.all_ap, self.ap_class_index = results
class DetMetrics: class DetMetrics(SimpleClass):
""" """
This class is a utility class for computing detection metrics such as precision, recall, and mean average precision This class is a utility class for computing detection metrics such as precision, recall, and mean average precision
(mAP) of an object detection model. (mAP) of an object detection model.
@ -585,10 +581,6 @@ class DetMetrics:
self.box = Metric() self.box = Metric()
self.speed = {'preprocess': 0.0, 'inference': 0.0, 'loss': 0.0, 'postprocess': 0.0} self.speed = {'preprocess': 0.0, 'inference': 0.0, 'loss': 0.0, 'postprocess': 0.0}
def __getattr__(self, attr):
name = self.__class__.__name__
raise AttributeError(f"'{name}' object has no attribute '{attr}'. See valid attributes below.\n{self.__doc__}")
def process(self, tp, conf, pred_cls, target_cls): def process(self, tp, conf, pred_cls, target_cls):
results = ap_per_class(tp, conf, pred_cls, target_cls, plot=self.plot, save_dir=self.save_dir, results = ap_per_class(tp, conf, pred_cls, target_cls, plot=self.plot, save_dir=self.save_dir,
names=self.names)[2:] names=self.names)[2:]
@ -622,7 +614,7 @@ class DetMetrics:
return dict(zip(self.keys + ['fitness'], self.mean_results() + [self.fitness])) return dict(zip(self.keys + ['fitness'], self.mean_results() + [self.fitness]))
class SegmentMetrics: class SegmentMetrics(SimpleClass):
""" """
Calculates and aggregates detection and segmentation metrics over a given set of classes. Calculates and aggregates detection and segmentation metrics over a given set of classes.
@ -657,10 +649,6 @@ class SegmentMetrics:
self.seg = Metric() self.seg = Metric()
self.speed = {'preprocess': 0.0, 'inference': 0.0, 'loss': 0.0, 'postprocess': 0.0} self.speed = {'preprocess': 0.0, 'inference': 0.0, 'loss': 0.0, 'postprocess': 0.0}
def __getattr__(self, attr):
name = self.__class__.__name__
raise AttributeError(f"'{name}' object has no attribute '{attr}'. See valid attributes below.\n{self.__doc__}")
def process(self, tp_m, tp_b, conf, pred_cls, target_cls): def process(self, tp_m, tp_b, conf, pred_cls, target_cls):
""" """
Processes the detection and segmentation metrics over the given set of predictions. Processes the detection and segmentation metrics over the given set of predictions.
@ -724,7 +712,7 @@ class SegmentMetrics:
return dict(zip(self.keys + ['fitness'], self.mean_results() + [self.fitness])) return dict(zip(self.keys + ['fitness'], self.mean_results() + [self.fitness]))
class ClassifyMetrics: class ClassifyMetrics(SimpleClass):
""" """
Class for computing classification metrics including top-1 and top-5 accuracy. Class for computing classification metrics including top-1 and top-5 accuracy.
@ -747,10 +735,6 @@ class ClassifyMetrics:
self.top5 = 0 self.top5 = 0
self.speed = {'preprocess': 0.0, 'inference': 0.0, 'loss': 0.0, 'postprocess': 0.0} self.speed = {'preprocess': 0.0, 'inference': 0.0, 'loss': 0.0, 'postprocess': 0.0}
def __getattr__(self, attr):
name = self.__class__.__name__
raise AttributeError(f"'{name}' object has no attribute '{attr}'. See valid attributes below.\n{self.__doc__}")
def process(self, targets, pred): def process(self, targets, pred):
# target classes and predicted classes # target classes and predicted classes
pred, targets = torch.cat(pred), torch.cat(targets) pred, targets = torch.cat(pred), torch.cat(targets)

@ -295,7 +295,7 @@ def plot_images(images,
for j, box in enumerate(boxes.T.tolist()): for j, box in enumerate(boxes.T.tolist()):
c = classes[j] c = classes[j]
color = colors(c) color = colors(c)
c = names[c] if names else c c = names.get(c, c) if names else c
if labels or conf[j] > 0.25: # 0.25 conf thresh if labels or conf[j] > 0.25: # 0.25 conf thresh
label = f'{c}' if labels else f'{c} {conf[j]:.1f}' label = f'{c}' if labels else f'{c} {conf[j]:.1f}'
annotator.box_label(box, label, color=color) annotator.box_label(box, label, color=color)

@ -8,6 +8,7 @@ import time
from contextlib import contextmanager from contextlib import contextmanager
from copy import deepcopy from copy import deepcopy
from pathlib import Path from pathlib import Path
from typing import Union
import numpy as np import numpy as np
import thop import thop
@ -15,15 +16,10 @@ import torch
import torch.distributed as dist import torch.distributed as dist
import torch.nn as nn import torch.nn as nn
import torch.nn.functional as F import torch.nn.functional as F
from torch.nn.parallel import DistributedDataParallel as DDP
from ultralytics.yolo.utils import DEFAULT_CFG_DICT, DEFAULT_CFG_KEYS, LOGGER, __version__ from ultralytics.yolo.utils import DEFAULT_CFG_DICT, DEFAULT_CFG_KEYS, LOGGER, RANK, __version__
from ultralytics.yolo.utils.checks import check_version from ultralytics.yolo.utils.checks import check_version
LOCAL_RANK = int(os.getenv('LOCAL_RANK', -1)) # https://pytorch.org/docs/stable/elastic/run.html
RANK = int(os.getenv('RANK', -1))
WORLD_SIZE = int(os.getenv('WORLD_SIZE', 1))
TORCH_1_9 = check_version(torch.__version__, '1.9.0') TORCH_1_9 = check_version(torch.__version__, '1.9.0')
TORCH_1_11 = check_version(torch.__version__, '1.11.0') TORCH_1_11 = check_version(torch.__version__, '1.11.0')
TORCH_1_12 = check_version(torch.__version__, '1.12.0') TORCH_1_12 = check_version(torch.__version__, '1.12.0')
@ -49,17 +45,6 @@ def smart_inference_mode():
return decorate return decorate
def DDP_model(model):
# Model DDP creation with checks
assert not check_version(torch.__version__, '1.12.0', pinned=True), \
'torch==1.12.0 torchvision==0.13.0 DDP training is not supported due to a known issue. ' \
'Please upgrade or downgrade torch to use DDP. See https://github.com/ultralytics/yolov5/issues/8395'
if TORCH_1_11:
return DDP(model, device_ids=[LOCAL_RANK], output_device=LOCAL_RANK, static_graph=True)
else:
return DDP(model, device_ids=[LOCAL_RANK], output_device=LOCAL_RANK)
def select_device(device='', batch=0, newline=False, verbose=True): def select_device(device='', batch=0, newline=False, verbose=True):
# device = None or 'cpu' or 0 or '0' or '0,1,2,3' # device = None or 'cpu' or 0 or '0' or '0,1,2,3'
s = f'Ultralytics YOLOv{__version__} 🚀 Python-{platform.python_version()} torch-{torch.__version__} ' s = f'Ultralytics YOLOv{__version__} 🚀 Python-{platform.python_version()} torch-{torch.__version__} '
@ -141,6 +126,7 @@ def fuse_conv_and_bn(conv, bn):
def fuse_deconv_and_bn(deconv, bn): def fuse_deconv_and_bn(deconv, bn):
# Fuse ConvTranspose2d() and BatchNorm2d() layers
fuseddconv = nn.ConvTranspose2d(deconv.in_channels, fuseddconv = nn.ConvTranspose2d(deconv.in_channels,
deconv.out_channels, deconv.out_channels,
kernel_size=deconv.kernel_size, kernel_size=deconv.kernel_size,
@ -186,14 +172,17 @@ def model_info(model, detailed=False, verbose=True, imgsz=640):
def get_num_params(model): def get_num_params(model):
# Return the total number of parameters in a YOLO model
return sum(x.numel() for x in model.parameters()) return sum(x.numel() for x in model.parameters())
def get_num_gradients(model): def get_num_gradients(model):
# Return the total number of parameters with gradients in a YOLO model
return sum(x.numel() for x in model.parameters() if x.requires_grad) return sum(x.numel() for x in model.parameters() if x.requires_grad)
def get_flops(model, imgsz=640): def get_flops(model, imgsz=640):
# Return a YOLO model's FLOPs
try: try:
model = de_parallel(model) model = de_parallel(model)
p = next(model.parameters()) p = next(model.parameters())
@ -208,6 +197,7 @@ def get_flops(model, imgsz=640):
def initialize_weights(model): def initialize_weights(model):
# Initialize model weights to random values
for m in model.modules(): for m in model.modules():
t = type(m) t = type(m)
if t is nn.Conv2d: if t is nn.Conv2d:
@ -239,7 +229,7 @@ def make_divisible(x, divisor):
def copy_attr(a, b, include=(), exclude=()): def copy_attr(a, b, include=(), exclude=()):
# Copy attributes from b to a, options to only include [...] and to exclude [...] # Copy attributes from 'b' to 'a', options to only include [...] and to exclude [...]
for k, v in b.__dict__.items(): for k, v in b.__dict__.items():
if (len(include) and k not in include) or k.startswith('_') or k in exclude: if (len(include) and k not in include) or k.startswith('_') or k in exclude:
continue continue
@ -322,7 +312,7 @@ class ModelEMA:
copy_attr(self.ema, model, include, exclude) copy_attr(self.ema, model, include, exclude)
def strip_optimizer(f='best.pt', s=''): def strip_optimizer(f: Union[str, Path] = 'best.pt', s: str = '') -> None:
""" """
Strip optimizer from 'f' to finalize training, optionally save as 's'. Strip optimizer from 'f' to finalize training, optionally save as 's'.

@ -126,11 +126,11 @@ class SegLoss(Loss):
# WARNING: lines below prevents Multi-GPU DDP 'unused gradient' PyTorch errors, do not remove # WARNING: lines below prevents Multi-GPU DDP 'unused gradient' PyTorch errors, do not remove
else: else:
loss[1] += proto.sum() * 0 + pred_masks.sum() * 0 loss[1] += (proto * 0).sum() + (pred_masks * 0).sum() # inf sums may lead to nan loss
# WARNING: lines below prevent Multi-GPU DDP 'unused gradient' PyTorch errors, do not remove # WARNING: lines below prevent Multi-GPU DDP 'unused gradient' PyTorch errors, do not remove
else: else:
loss[1] += proto.sum() * 0 + pred_masks.sum() * 0 loss[1] += (proto * 0).sum() + (pred_masks * 0).sum() # inf sums may lead to nan loss
loss[0] *= self.hyp.box # box gain loss[0] *= self.hyp.box # box gain
loss[1] *= self.hyp.box / batch_size # seg gain loss[1] *= self.hyp.box / batch_size # seg gain

Loading…
Cancel
Save