mirror of
https://github.com/THU-MIG/yolov10.git
synced 2025-05-23 13:34:23 +08:00
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>
This commit is contained in:
parent
ef03e6732a
commit
ec10002a4a
5
.github/workflows/greetings.yml
vendored
5
.github/workflows/greetings.yml
vendored
@ -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
|
||||||
|
4
.github/workflows/links.yml
vendored
4
.github/workflows/links.yml
vendored
@ -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}}
|
||||||
|
27
README.md
27
README.md
@ -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…
x
Reference in New Issue
Block a user