From d32b339373f33f54251db3e58b98f71c2967ba96 Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Sat, 11 Feb 2023 01:26:44 +0400 Subject: [PATCH] `ultralytics 8.0.34` security updates and fixes (#924) Co-authored-by: Laughing <61612323+Laughing-q@users.noreply.github.com> Co-authored-by: Fabian Greavu Co-authored-by: Yonghye Kwon Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- docker/Dockerfile | 4 ++ docs/cfg.md | 1 + docs/reference/ops.md | 44 +++++++++---------- mkdocs.yml | 5 ++- ultralytics/__init__.py | 2 +- ultralytics/hub/__init__.py | 2 +- ultralytics/hub/session.py | 3 +- ultralytics/hub/utils.py | 14 +++--- ultralytics/models/v8/seg/yolov8l-seg.yaml | 8 ++-- ultralytics/models/v8/seg/yolov8m-seg.yaml | 8 ++-- ultralytics/models/v8/seg/yolov8n-seg.yaml | 8 ++-- ultralytics/models/v8/seg/yolov8s-seg.yaml | 8 ++-- ultralytics/models/v8/seg/yolov8x-seg.yaml | 8 ++-- ultralytics/models/v8/yolov8l.yaml | 8 ++-- ultralytics/models/v8/yolov8m.yaml | 8 ++-- ultralytics/models/v8/yolov8n.yaml | 8 ++-- ultralytics/models/v8/yolov8s.yaml | 8 ++-- ultralytics/models/v8/yolov8x.yaml | 8 ++-- ultralytics/yolo/cfg/__init__.py | 33 +++++++------- ultralytics/yolo/cfg/default.yaml | 1 + .../yolo/data/dataloaders/stream_loaders.py | 2 +- ultralytics/yolo/data/dataloaders/v5loader.py | 1 + ultralytics/yolo/data/dataset.py | 2 +- ultralytics/yolo/engine/exporter.py | 7 ++- ultralytics/yolo/engine/model.py | 10 +++-- ultralytics/yolo/engine/trainer.py | 9 ++-- ultralytics/yolo/utils/__init__.py | 16 ++++--- ultralytics/yolo/utils/checks.py | 2 +- ultralytics/yolo/utils/downloads.py | 11 +++-- ultralytics/yolo/utils/torch_utils.py | 3 +- ultralytics/yolo/v8/classify/train.py | 2 +- 31 files changed, 134 insertions(+), 120 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index c49534b..61f43ab 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -16,6 +16,10 @@ RUN TZ=Etc/UTC apt install -y tzdata RUN apt install --no-install-recommends -y gcc git zip curl htop libgl1-mesa-glx libglib2.0-0 libpython3-dev gnupg # RUN alias python=python3 +# Security updates +# https://security.snyk.io/vuln/SNYK-UBUNTU1804-OPENSSL-3314796 +RUN apt upgrade --no-install-recommends -y openssl + # Create working directory RUN mkdir -p /usr/src/ultralytics WORKDIR /usr/src/ultralytics diff --git a/docs/cfg.md b/docs/cfg.md index c5eca3a..1b73abb 100644 --- a/docs/cfg.md +++ b/docs/cfg.md @@ -75,6 +75,7 @@ task. | batch | 16 | number of images per batch (-1 for AutoBatch) | | imgsz | 640 | size of input images as integer or w,h | | save | True | save train checkpoints and predict results | +| save_period | -1 | Save checkpoint every x epochs (disabled if < 1) | | cache | False | True/ram, disk or False. Use cache for data loading | | device | null | device to run on, i.e. cuda device=0 or device=0,1,2,3 or device=cpu | | workers | 8 | number of worker threads for data loading (per RANK if DDP) | diff --git a/docs/reference/ops.md b/docs/reference/ops.md index ab0d46e..8c4f1b7 100644 --- a/docs/reference/ops.md +++ b/docs/reference/ops.md @@ -2,7 +2,7 @@ This module contains optimized deep learning related operations used in the Ultr ## Non-max suppression -:::ultralytics.ops.non_max_suppression +:::ultralytics.yolo.utils.ops.non_max_suppression handler: python options: show_source: false @@ -11,7 +11,7 @@ show_root_toc_entry: false ## Scale boxes -:::ultralytics.ops.scale_boxes +:::ultralytics.yolo.utils.ops.scale_boxes handler: python options: show_source: false @@ -20,7 +20,7 @@ show_root_toc_entry: false ## Scale image -:::ultralytics.ops.scale_image +:::ultralytics.yolo.utils.ops.scale_image handler: python options: show_source: false @@ -29,7 +29,7 @@ show_root_toc_entry: false ## clip boxes -:::ultralytics.ops.clip_boxes +:::ultralytics.yolo.utils.ops.clip_boxes handler: python options: show_source: false @@ -40,7 +40,7 @@ show_root_toc_entry: false ## xyxy2xywh -:::ultralytics.ops.xyxy2xywh +:::ultralytics.yolo.utils.ops.xyxy2xywh handler: python options: show_source: false @@ -49,7 +49,7 @@ show_root_toc_entry: false ## xywh2xyxy -:::ultralytics.ops.xywh2xyxy +:::ultralytics.yolo.utils.ops.xywh2xyxy handler: python options: show_source: false @@ -58,7 +58,7 @@ show_root_toc_entry: false ## xywhn2xyxy -:::ultralytics.ops.xywhn2xyxy +:::ultralytics.yolo.utils.ops.xywhn2xyxy handler: python options: show_source: false @@ -67,7 +67,7 @@ show_root_toc_entry: false ## xyxy2xywhn -:::ultralytics.ops.xyxy2xywhn +:::ultralytics.yolo.utils.ops.xyxy2xywhn handler: python options: show_source: false @@ -76,7 +76,7 @@ show_root_toc_entry: false ## xyn2xy -:::ultralytics.ops.xyn2xy +:::ultralytics.yolo.utils.ops.xyn2xy handler: python options: show_source: false @@ -85,7 +85,7 @@ show_root_toc_entry: false ## xywh2ltwh -:::ultralytics.ops.xywh2ltwh +:::ultralytics.yolo.utils.ops.xywh2ltwh handler: python options: show_source: false @@ -94,7 +94,7 @@ show_root_toc_entry: false ## xyxy2ltwh -:::ultralytics.ops.xyxy2ltwh +:::ultralytics.yolo.utils.ops.xyxy2ltwh handler: python options: show_source: false @@ -103,7 +103,7 @@ show_root_toc_entry: false ## ltwh2xywh -:::ultralytics.ops.ltwh2xywh +:::ultralytics.yolo.utils.ops.ltwh2xywh handler: python options: show_source: false @@ -112,7 +112,7 @@ show_root_toc_entry: false ## ltwh2xyxy -:::ultralytics.ops.ltwh2xyxy +:::ultralytics.yolo.utils.ops.ltwh2xyxy handler: python options: show_source: false @@ -121,7 +121,7 @@ show_root_toc_entry: false ## segment2box -:::ultralytics.ops.segment2box +:::ultralytics.yolo.utils.ops.segment2box handler: python options: show_source: false @@ -132,7 +132,7 @@ show_root_toc_entry: false ## resample_segments -:::ultralytics.ops.resample_segments +:::ultralytics.yolo.utils.ops.resample_segments handler: python options: show_source: false @@ -141,7 +141,7 @@ show_root_toc_entry: false ## crop_mask -:::ultralytics.ops.crop_mask +:::ultralytics.yolo.utils.ops.crop_mask handler: python options: show_source: false @@ -150,7 +150,7 @@ show_root_toc_entry: false ## process_mask_upsample -:::ultralytics.ops.process_mask_upsample +:::ultralytics.yolo.utils.ops.process_mask_upsample handler: python options: show_source: false @@ -159,7 +159,7 @@ show_root_toc_entry: false ## process_mask -:::ultralytics.ops.process_mask +:::ultralytics.yolo.utils.ops.process_mask handler: python options: show_source: false @@ -168,7 +168,7 @@ show_root_toc_entry: false ## process_mask_native -:::ultralytics.ops.process_mask_native +:::ultralytics.yolo.utils.ops.process_mask_native handler: python options: show_source: false @@ -177,7 +177,7 @@ show_root_toc_entry: false ## scale_segments -:::ultralytics.ops.scale_segments +:::ultralytics.yolo.utils.ops.scale_segments handler: python options: show_source: false @@ -186,7 +186,7 @@ show_root_toc_entry: false ## masks2segments -:::ultralytics.ops.masks2segments +:::ultralytics.yolo.utils.ops.masks2segments handler: python options: show_source: false @@ -195,7 +195,7 @@ show_root_toc_entry: false ## clip_segments -:::ultralytics.ops.clip_segments +:::ultralytics.yolo.utils.ops.clip_segments handler: python options: show_source: false diff --git a/mkdocs.yml b/mkdocs.yml index d19a474..2117aa8 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,11 +1,12 @@ -site_name: Ultralytics YOLOv8 Docs +site_name: YOLOv8 Docs repo_url: https://github.com/ultralytics/ultralytics edit_uri: https://github.com/ultralytics/ultralytics/tree/main/docs repo_name: ultralytics/ultralytics +remote_name: https://github.com/ultralytics/docs theme: name: "material" - logo: https://github.com/ultralytics/assets/raw/main/logo/Ultralytics-logomark-white.png + logo: https://github.com/ultralytics/assets/raw/main/logo/Ultralytics_Logotype_Reverse.svg favicon: https://github.com/ultralytics/assets/raw/main/logo/favicon-yolo.ico font: text: Roboto diff --git a/ultralytics/__init__.py b/ultralytics/__init__.py index db41f82..d9bdbec 100644 --- a/ultralytics/__init__.py +++ b/ultralytics/__init__.py @@ -1,6 +1,6 @@ # Ultralytics YOLO 🚀, GPL-3.0 license -__version__ = "8.0.33" +__version__ = "8.0.34" from ultralytics.yolo.engine.model import YOLO from ultralytics.yolo.utils.checks import check_yolo as checks diff --git a/ultralytics/hub/__init__.py b/ultralytics/hub/__init__.py index 6e7e8fb..935c84a 100644 --- a/ultralytics/hub/__init__.py +++ b/ultralytics/hub/__init__.py @@ -7,7 +7,7 @@ from ultralytics.hub.session import HubTrainingSession from ultralytics.hub.utils import split_key from ultralytics.yolo.engine.exporter import export_formats from ultralytics.yolo.engine.model import YOLO -from ultralytics.yolo.utils import LOGGER, emojis, PREFIX +from ultralytics.yolo.utils import LOGGER, PREFIX, emojis # Define all export formats EXPORT_FORMATS = list(export_formats()['Argument'][1:]) + ["ultralytics_tflite", "ultralytics_coreml"] diff --git a/ultralytics/hub/session.py b/ultralytics/hub/session.py index f6e8785..94e0a54 100644 --- a/ultralytics/hub/session.py +++ b/ultralytics/hub/session.py @@ -7,9 +7,8 @@ from time import sleep, time import requests -from ultralytics import __version__ from ultralytics.hub.utils import HUB_API_ROOT, check_dataset_disk_space, smart_request -from ultralytics.yolo.utils import is_colab, threaded, LOGGER, emojis, PREFIX +from ultralytics.yolo.utils import LOGGER, PREFIX, __version__, emojis, is_colab, threaded from ultralytics.yolo.utils.torch_utils import get_flops, get_num_params AGENT_NAME = f"python-{__version__}-colab" if is_colab() else f"python-{__version__}-local" diff --git a/ultralytics/hub/utils.py b/ultralytics/hub/utils.py index f2cff50..2e2e04b 100644 --- a/ultralytics/hub/utils.py +++ b/ultralytics/hub/utils.py @@ -11,9 +11,10 @@ from random import random import requests -from ultralytics.yolo.utils import (DEFAULT_CFG_DICT, LOGGER, RANK, SETTINGS, TryExcept, colorstr, emojis, - get_git_origin_url, is_colab, is_docker, is_git_dir, is_github_actions_ci, - is_jupyter, is_kaggle, is_pip_package, is_pytest_running) +from ultralytics.yolo.utils import (DEFAULT_CFG_DICT, ENVIRONMENT, LOGGER, RANK, SETTINGS, TryExcept, __version__, + colorstr, emojis, get_git_origin_url, is_git_dir, is_github_actions_ci, + is_pip_package, is_pytest_running) +from ultralytics.yolo.utils.checks import check_online PREFIX = colorstr('Ultralytics: ') HELP_MSG = 'If this issue persists please visit https://github.com/ultralytics/hub/issues for assistance.' @@ -143,9 +144,6 @@ class Traces: """ Initialize Traces for error tracking and reporting if tests are not currently running. """ - from ultralytics import __version__ - env = 'Colab' if is_colab() else 'Kaggle' if is_kaggle() else 'Jupyter' if is_jupyter() else \ - 'Docker' if is_docker() else platform.system() self.rate_limit = 3.0 # rate limit (seconds) self.t = 0.0 # rate limit timer (seconds) self.metadata = { @@ -153,9 +151,10 @@ class Traces: "install": 'git' if is_git_dir() else 'pip' if is_pip_package() else 'other', "python": platform.python_version(), "release": __version__, - "environment": env} + "environment": ENVIRONMENT} self.enabled = SETTINGS['sync'] and \ RANK in {-1, 0} and \ + check_online() and \ not is_pytest_running() and \ not is_github_actions_ci() and \ (is_pip_package() or get_git_origin_url() == "https://github.com/ultralytics/ultralytics.git") @@ -186,6 +185,7 @@ class Traces: headers=None, code=3, retry=0, + timeout=1.0, verbose=False) diff --git a/ultralytics/models/v8/seg/yolov8l-seg.yaml b/ultralytics/models/v8/seg/yolov8l-seg.yaml index 235dc76..72bf008 100644 --- a/ultralytics/models/v8/seg/yolov8l-seg.yaml +++ b/ultralytics/models/v8/seg/yolov8l-seg.yaml @@ -23,18 +23,18 @@ backbone: head: - [-1, 1, nn.Upsample, [None, 2, 'nearest']] - [[-1, 6], 1, Concat, [1]] # cat backbone P4 - - [-1, 3, C2f, [512]] # 13 + - [-1, 3, C2f, [512]] # 12 - [-1, 1, nn.Upsample, [None, 2, 'nearest']] - [[-1, 4], 1, Concat, [1]] # cat backbone P3 - - [-1, 3, C2f, [256]] # 17 (P3/8-small) + - [-1, 3, C2f, [256]] # 15 (P3/8-small) - [-1, 1, Conv, [256, 3, 2]] - [[-1, 12], 1, Concat, [1]] # cat head P4 - - [-1, 3, C2f, [512]] # 20 (P4/16-medium) + - [-1, 3, C2f, [512]] # 18 (P4/16-medium) - [-1, 1, Conv, [512, 3, 2]] - [[-1, 9], 1, Concat, [1]] # cat head P5 - - [-1, 3, C2f, [512]] # 23 (P5/32-large) + - [-1, 3, C2f, [512]] # 21 (P5/32-large) - [[15, 18, 21], 1, Segment, [nc, 32, 256]] # Detect(P3, P4, P5) diff --git a/ultralytics/models/v8/seg/yolov8m-seg.yaml b/ultralytics/models/v8/seg/yolov8m-seg.yaml index 17c07f6..7e74227 100644 --- a/ultralytics/models/v8/seg/yolov8m-seg.yaml +++ b/ultralytics/models/v8/seg/yolov8m-seg.yaml @@ -23,18 +23,18 @@ backbone: head: - [-1, 1, nn.Upsample, [None, 2, 'nearest']] - [[-1, 6], 1, Concat, [1]] # cat backbone P4 - - [-1, 3, C2f, [512]] # 13 + - [-1, 3, C2f, [512]] # 12 - [-1, 1, nn.Upsample, [None, 2, 'nearest']] - [[-1, 4], 1, Concat, [1]] # cat backbone P3 - - [-1, 3, C2f, [256]] # 17 (P3/8-small) + - [-1, 3, C2f, [256]] # 15 (P3/8-small) - [-1, 1, Conv, [256, 3, 2]] - [[-1, 12], 1, Concat, [1]] # cat head P4 - - [-1, 3, C2f, [512]] # 20 (P4/16-medium) + - [-1, 3, C2f, [512]] # 18 (P4/16-medium) - [-1, 1, Conv, [512, 3, 2]] - [[-1, 9], 1, Concat, [1]] # cat head P5 - - [-1, 3, C2f, [768]] # 23 (P5/32-large) + - [-1, 3, C2f, [768]] # 21 (P5/32-large) - [[15, 18, 21], 1, Segment, [nc, 32, 256]] # Detect(P3, P4, P5) diff --git a/ultralytics/models/v8/seg/yolov8n-seg.yaml b/ultralytics/models/v8/seg/yolov8n-seg.yaml index ffecc9d..5f39e10 100644 --- a/ultralytics/models/v8/seg/yolov8n-seg.yaml +++ b/ultralytics/models/v8/seg/yolov8n-seg.yaml @@ -23,18 +23,18 @@ backbone: head: - [-1, 1, nn.Upsample, [None, 2, 'nearest']] - [[-1, 6], 1, Concat, [1]] # cat backbone P4 - - [-1, 3, C2f, [512]] # 13 + - [-1, 3, C2f, [512]] # 12 - [-1, 1, nn.Upsample, [None, 2, 'nearest']] - [[-1, 4], 1, Concat, [1]] # cat backbone P3 - - [-1, 3, C2f, [256]] # 17 (P3/8-small) + - [-1, 3, C2f, [256]] # 15 (P3/8-small) - [-1, 1, Conv, [256, 3, 2]] - [[-1, 12], 1, Concat, [1]] # cat head P4 - - [-1, 3, C2f, [512]] # 20 (P4/16-medium) + - [-1, 3, C2f, [512]] # 18 (P4/16-medium) - [-1, 1, Conv, [512, 3, 2]] - [[-1, 9], 1, Concat, [1]] # cat head P5 - - [-1, 3, C2f, [1024]] # 23 (P5/32-large) + - [-1, 3, C2f, [1024]] # 21 (P5/32-large) - [[15, 18, 21], 1, Segment, [nc, 32, 256]] # Detect(P3, P4, P5) diff --git a/ultralytics/models/v8/seg/yolov8s-seg.yaml b/ultralytics/models/v8/seg/yolov8s-seg.yaml index dc828a1..2794616 100644 --- a/ultralytics/models/v8/seg/yolov8s-seg.yaml +++ b/ultralytics/models/v8/seg/yolov8s-seg.yaml @@ -23,18 +23,18 @@ backbone: head: - [-1, 1, nn.Upsample, [None, 2, 'nearest']] - [[-1, 6], 1, Concat, [1]] # cat backbone P4 - - [-1, 3, C2f, [512]] # 13 + - [-1, 3, C2f, [512]] # 12 - [-1, 1, nn.Upsample, [None, 2, 'nearest']] - [[-1, 4], 1, Concat, [1]] # cat backbone P3 - - [-1, 3, C2f, [256]] # 17 (P3/8-small) + - [-1, 3, C2f, [256]] # 15 (P3/8-small) - [-1, 1, Conv, [256, 3, 2]] - [[-1, 12], 1, Concat, [1]] # cat head P4 - - [-1, 3, C2f, [512]] # 20 (P4/16-medium) + - [-1, 3, C2f, [512]] # 18 (P4/16-medium) - [-1, 1, Conv, [512, 3, 2]] - [[-1, 9], 1, Concat, [1]] # cat head P5 - - [-1, 3, C2f, [1024]] # 23 (P5/32-large) + - [-1, 3, C2f, [1024]] # 21 (P5/32-large) - [[15, 18, 21], 1, Segment, [nc, 32, 256]] # Detect(P3, P4, P5) diff --git a/ultralytics/models/v8/seg/yolov8x-seg.yaml b/ultralytics/models/v8/seg/yolov8x-seg.yaml index 0572283..3edb030 100644 --- a/ultralytics/models/v8/seg/yolov8x-seg.yaml +++ b/ultralytics/models/v8/seg/yolov8x-seg.yaml @@ -23,18 +23,18 @@ backbone: head: - [-1, 1, nn.Upsample, [None, 2, 'nearest']] - [[-1, 6], 1, Concat, [1]] # cat backbone P4 - - [-1, 3, C2f, [512]] # 13 + - [-1, 3, C2f, [512]] # 12 - [-1, 1, nn.Upsample, [None, 2, 'nearest']] - [[-1, 4], 1, Concat, [1]] # cat backbone P3 - - [-1, 3, C2f, [256]] # 17 (P3/8-small) + - [-1, 3, C2f, [256]] # 15 (P3/8-small) - [-1, 1, Conv, [256, 3, 2]] - [[-1, 12], 1, Concat, [1]] # cat head P4 - - [-1, 3, C2f, [512]] # 20 (P4/16-medium) + - [-1, 3, C2f, [512]] # 18 (P4/16-medium) - [-1, 1, Conv, [512, 3, 2]] - [[-1, 9], 1, Concat, [1]] # cat head P5 - - [-1, 3, C2f, [512]] # 23 (P5/32-large) + - [-1, 3, C2f, [512]] # 21 (P5/32-large) - [[15, 18, 21], 1, Segment, [nc, 32, 256]] # Detect(P3, P4, P5) diff --git a/ultralytics/models/v8/yolov8l.yaml b/ultralytics/models/v8/yolov8l.yaml index 9ec170c..afbe4c6 100644 --- a/ultralytics/models/v8/yolov8l.yaml +++ b/ultralytics/models/v8/yolov8l.yaml @@ -23,18 +23,18 @@ backbone: head: - [-1, 1, nn.Upsample, [None, 2, 'nearest']] - [[-1, 6], 1, Concat, [1]] # cat backbone P4 - - [-1, 3, C2f, [512]] # 13 + - [-1, 3, C2f, [512]] # 12 - [-1, 1, nn.Upsample, [None, 2, 'nearest']] - [[-1, 4], 1, Concat, [1]] # cat backbone P3 - - [-1, 3, C2f, [256]] # 17 (P3/8-small) + - [-1, 3, C2f, [256]] # 15 (P3/8-small) - [-1, 1, Conv, [256, 3, 2]] - [[-1, 12], 1, Concat, [1]] # cat head P4 - - [-1, 3, C2f, [512]] # 20 (P4/16-medium) + - [-1, 3, C2f, [512]] # 18 (P4/16-medium) - [-1, 1, Conv, [512, 3, 2]] - [[-1, 9], 1, Concat, [1]] # cat head P5 - - [-1, 3, C2f, [512]] # 23 (P5/32-large) + - [-1, 3, C2f, [512]] # 21 (P5/32-large) - [[15, 18, 21], 1, Detect, [nc]] # Detect(P3, P4, P5) diff --git a/ultralytics/models/v8/yolov8m.yaml b/ultralytics/models/v8/yolov8m.yaml index f97cf05..a17763c 100644 --- a/ultralytics/models/v8/yolov8m.yaml +++ b/ultralytics/models/v8/yolov8m.yaml @@ -23,18 +23,18 @@ backbone: head: - [-1, 1, nn.Upsample, [None, 2, 'nearest']] - [[-1, 6], 1, Concat, [1]] # cat backbone P4 - - [-1, 3, C2f, [512]] # 13 + - [-1, 3, C2f, [512]] # 12 - [-1, 1, nn.Upsample, [None, 2, 'nearest']] - [[-1, 4], 1, Concat, [1]] # cat backbone P3 - - [-1, 3, C2f, [256]] # 17 (P3/8-small) + - [-1, 3, C2f, [256]] # 15 (P3/8-small) - [-1, 1, Conv, [256, 3, 2]] - [[-1, 12], 1, Concat, [1]] # cat head P4 - - [-1, 3, C2f, [512]] # 20 (P4/16-medium) + - [-1, 3, C2f, [512]] # 18 (P4/16-medium) - [-1, 1, Conv, [512, 3, 2]] - [[-1, 9], 1, Concat, [1]] # cat head P5 - - [-1, 3, C2f, [768]] # 23 (P5/32-large) + - [-1, 3, C2f, [768]] # 21 (P5/32-large) - [[15, 18, 21], 1, Detect, [nc]] # Detect(P3, P4, P5) diff --git a/ultralytics/models/v8/yolov8n.yaml b/ultralytics/models/v8/yolov8n.yaml index 83cf080..2519b40 100644 --- a/ultralytics/models/v8/yolov8n.yaml +++ b/ultralytics/models/v8/yolov8n.yaml @@ -23,18 +23,18 @@ backbone: head: - [-1, 1, nn.Upsample, [None, 2, 'nearest']] - [[-1, 6], 1, Concat, [1]] # cat backbone P4 - - [-1, 3, C2f, [512]] # 13 + - [-1, 3, C2f, [512]] # 12 - [-1, 1, nn.Upsample, [None, 2, 'nearest']] - [[-1, 4], 1, Concat, [1]] # cat backbone P3 - - [-1, 3, C2f, [256]] # 17 (P3/8-small) + - [-1, 3, C2f, [256]] # 15 (P3/8-small) - [-1, 1, Conv, [256, 3, 2]] - [[-1, 12], 1, Concat, [1]] # cat head P4 - - [-1, 3, C2f, [512]] # 20 (P4/16-medium) + - [-1, 3, C2f, [512]] # 18 (P4/16-medium) - [-1, 1, Conv, [512, 3, 2]] - [[-1, 9], 1, Concat, [1]] # cat head P5 - - [-1, 3, C2f, [1024]] # 23 (P5/32-large) + - [-1, 3, C2f, [1024]] # 21 (P5/32-large) - [[15, 18, 21], 1, Detect, [nc]] # Detect(P3, P4, P5) diff --git a/ultralytics/models/v8/yolov8s.yaml b/ultralytics/models/v8/yolov8s.yaml index 0c96d94..7905654 100644 --- a/ultralytics/models/v8/yolov8s.yaml +++ b/ultralytics/models/v8/yolov8s.yaml @@ -23,18 +23,18 @@ backbone: head: - [-1, 1, nn.Upsample, [None, 2, 'nearest']] - [[-1, 6], 1, Concat, [1]] # cat backbone P4 - - [-1, 3, C2f, [512]] # 13 + - [-1, 3, C2f, [512]] # 12 - [-1, 1, nn.Upsample, [None, 2, 'nearest']] - [[-1, 4], 1, Concat, [1]] # cat backbone P3 - - [-1, 3, C2f, [256]] # 17 (P3/8-small) + - [-1, 3, C2f, [256]] # 15 (P3/8-small) - [-1, 1, Conv, [256, 3, 2]] - [[-1, 12], 1, Concat, [1]] # cat head P4 - - [-1, 3, C2f, [512]] # 20 (P4/16-medium) + - [-1, 3, C2f, [512]] # 18 (P4/16-medium) - [-1, 1, Conv, [512, 3, 2]] - [[-1, 9], 1, Concat, [1]] # cat head P5 - - [-1, 3, C2f, [1024]] # 23 (P5/32-large) + - [-1, 3, C2f, [1024]] # 21 (P5/32-large) - [[15, 18, 21], 1, Detect, [nc]] # Detect(P3, P4, P5) diff --git a/ultralytics/models/v8/yolov8x.yaml b/ultralytics/models/v8/yolov8x.yaml index 20e4070..d254523 100644 --- a/ultralytics/models/v8/yolov8x.yaml +++ b/ultralytics/models/v8/yolov8x.yaml @@ -23,18 +23,18 @@ backbone: head: - [-1, 1, nn.Upsample, [None, 2, 'nearest']] - [[-1, 6], 1, Concat, [1]] # cat backbone P4 - - [-1, 3, C2f, [512]] # 13 + - [-1, 3, C2f, [512]] # 12 - [-1, 1, nn.Upsample, [None, 2, 'nearest']] - [[-1, 4], 1, Concat, [1]] # cat backbone P3 - - [-1, 3, C2f, [256]] # 17 (P3/8-small) + - [-1, 3, C2f, [256]] # 15 (P3/8-small) - [-1, 1, Conv, [256, 3, 2]] - [[-1, 12], 1, Concat, [1]] # cat head P4 - - [-1, 3, C2f, [512]] # 20 (P4/16-medium) + - [-1, 3, C2f, [512]] # 18 (P4/16-medium) - [-1, 1, Conv, [512, 3, 2]] - [[-1, 9], 1, Concat, [1]] # cat head P5 - - [-1, 3, C2f, [512]] # 23 (P5/32-large) + - [-1, 3, C2f, [512]] # 21 (P5/32-large) - [[15, 18, 21], 1, Detect, [nc]] # Detect(P3, P4, P5) diff --git a/ultralytics/yolo/cfg/__init__.py b/ultralytics/yolo/cfg/__init__.py index 34fd6f0..ec55e6d 100644 --- a/ultralytics/yolo/cfg/__init__.py +++ b/ultralytics/yolo/cfg/__init__.py @@ -8,9 +8,9 @@ from pathlib import Path from types import SimpleNamespace from typing import Dict, List, Union -from ultralytics import __version__ from ultralytics.yolo.utils import (DEFAULT_CFG, DEFAULT_CFG_DICT, DEFAULT_CFG_PATH, LOGGER, PREFIX, ROOT, - USER_CONFIG_DIR, IterableSimpleNamespace, colorstr, emojis, yaml_load, yaml_print) + USER_CONFIG_DIR, IterableSimpleNamespace, __version__, colorstr, emojis, yaml_load, + yaml_print) from ultralytics.yolo.utils.checks import check_yolo CLI_HELP_MSG = \ @@ -25,13 +25,13 @@ CLI_HELP_MSG = \ See all ARGS at https://docs.ultralytics.com/cfg or with 'yolo cfg' 1. Train a detection model for 10 epochs with an initial learning_rate of 0.01 - yolo detect train data=coco128.yaml model=yolov8n.pt epochs=10 lr0=0.01 + yolo train data=coco128.yaml model=yolov8n.pt epochs=10 lr0=0.01 2. Predict a YouTube video using a pretrained segmentation model at image size 320: - yolo segment predict model=yolov8n-seg.pt source='https://youtu.be/Zgi9g1ksQHc' imgsz=320 + yolo predict model=yolov8n-seg.pt source='https://youtu.be/Zgi9g1ksQHc' imgsz=320 3. Val a pretrained detection model at batch-size 1 and image size 640: - yolo detect val model=yolov8n.pt data=coco128.yaml batch=1 imgsz=640 + yolo val model=yolov8n.pt data=coco128.yaml batch=1 imgsz=640 4. Export a YOLOv8n classification model to ONNX format at image size 224 by 128 (no TASK required) yolo export model=yolov8n-cls.pt format=onnx imgsz=224,128 @@ -56,7 +56,7 @@ CFG_FRACTION_KEYS = { 'mixup', 'copy_paste', 'conf', 'iou'} CFG_INT_KEYS = { 'epochs', 'patience', 'batch', 'workers', 'seed', 'close_mosaic', 'mask_ratio', 'max_det', 'vid_stride', - 'line_thickness', 'workspace', 'nbs'} + 'line_thickness', 'workspace', 'nbs', 'save_period'} CFG_BOOL_KEYS = { 'save', 'exist_ok', 'pretrained', 'verbose', 'deterministic', 'single_cls', 'image_weights', 'rect', 'cos_lr', 'overlap_mask', 'val', 'save_json', 'save_hybrid', 'half', 'dnn', 'plots', 'show', 'save_txt', 'save_conf', @@ -131,7 +131,7 @@ def get_cfg(cfg: Union[str, Path, Dict, SimpleNamespace] = DEFAULT_CFG, override return IterableSimpleNamespace(**cfg) -def check_cfg_mismatch(base: Dict, custom: Dict): +def check_cfg_mismatch(base: Dict, custom: Dict, e=None): """ This function checks for any mismatched keys between a custom configuration list and a base configuration list. If any mismatched keys are found, the function prints out similar keys from the base list and exits the program. @@ -143,12 +143,12 @@ def check_cfg_mismatch(base: Dict, custom: Dict): base, custom = (set(x.keys()) for x in (base, custom)) mismatched = [x for x in custom if x not in base] if mismatched: + string = '' for x in mismatched: - matches = get_close_matches(x, base, 3, 0.6) - match_str = f"Similar arguments are {matches}." if matches else 'There are no similar arguments.' - LOGGER.warning(f"'{colorstr('red', 'bold', x)}' is not a valid YOLO argument. {match_str}") - LOGGER.warning(CLI_HELP_MSG) - sys.exit() + matches = get_close_matches(x, base) + match_str = f"Similar arguments are {matches}." if matches else '' + string += f"'{colorstr('red', 'bold', x)}' is not a valid YOLO argument. {match_str}\n" + raise SyntaxError(string + CLI_HELP_MSG) from e def merge_equals_args(args: List[str]) -> List[str]: @@ -178,10 +178,6 @@ def merge_equals_args(args: List[str]) -> List[str]: return new_args -def argument_error(arg): - return SyntaxError(f"'{arg}' is not a valid YOLO argument.\n{CLI_HELP_MSG}") - - def entrypoint(debug=''): """ This function is the ultralytics package entrypoint, it's responsible for parsing the command line arguments passed @@ -212,6 +208,7 @@ def entrypoint(debug=''): 'settings': lambda: yaml_print(USER_CONFIG_DIR / 'settings.yaml'), 'cfg': lambda: yaml_print(DEFAULT_CFG_PATH), 'copy-cfg': copy_default_cfg} + FULL_ARGS_DICT = {**DEFAULT_CFG_DICT, **{k: None for k in tasks}, **{k: None for k in modes}, **special} special = {**special, **{f'-{k}': v for k, v in special.items()}, **{f'--{k}': v for k, v in special.items()}} overrides = {} # basic overrides, i.e. imgsz=320 @@ -236,7 +233,7 @@ def entrypoint(debug=''): v = eval(v) overrides[k] = v except (NameError, SyntaxError, ValueError, AssertionError) as e: - raise argument_error(a) from e + check_cfg_mismatch(FULL_ARGS_DICT, {a: ""}, e) elif a in tasks: overrides['task'] = a @@ -251,7 +248,7 @@ def entrypoint(debug=''): raise SyntaxError(f"'{colorstr('red', 'bold', a)}' is a valid YOLO argument but is missing an '=' sign " f"to set its value, i.e. try '{a}={DEFAULT_CFG_DICT[a]}'\n{CLI_HELP_MSG}") else: - raise argument_error(a) + check_cfg_mismatch(FULL_ARGS_DICT, {a: ""}) # Defaults task2model = dict(detect='yolov8n.pt', segment='yolov8n-seg.pt', classify='yolov8n-cls.pt') diff --git a/ultralytics/yolo/cfg/default.yaml b/ultralytics/yolo/cfg/default.yaml index 6c0a7cd..54af7e4 100644 --- a/ultralytics/yolo/cfg/default.yaml +++ b/ultralytics/yolo/cfg/default.yaml @@ -12,6 +12,7 @@ patience: 50 # epochs to wait for no observable improvement for early stopping batch: 16 # number of images per batch (-1 for AutoBatch) imgsz: 640 # size of input images as integer or w,h save: True # save train checkpoints and predict results +save_period: -1 # Save checkpoint every x epochs (disabled if < 1) cache: False # True/ram, disk or False. Use cache for data loading device: # device to run on, i.e. cuda device=0 or device=0,1,2,3 or device=cpu workers: 8 # number of worker threads for data loading (per RANK if DDP) diff --git a/ultralytics/yolo/data/dataloaders/stream_loaders.py b/ultralytics/yolo/data/dataloaders/stream_loaders.py index a242eff..d9735b9 100644 --- a/ultralytics/yolo/data/dataloaders/stream_loaders.py +++ b/ultralytics/yolo/data/dataloaders/stream_loaders.py @@ -291,7 +291,7 @@ class LoadPilAndNumpy: self.mode = 'image' # generate fake paths self.paths = [f"image{i}.jpg" for i in range(len(self.im0))] - self.bs = 1 + self.bs = len(self.im0) @staticmethod def _single_check(im): diff --git a/ultralytics/yolo/data/dataloaders/v5loader.py b/ultralytics/yolo/data/dataloaders/v5loader.py index 37c1507..b27e613 100644 --- a/ultralytics/yolo/data/dataloaders/v5loader.py +++ b/ultralytics/yolo/data/dataloaders/v5loader.py @@ -34,6 +34,7 @@ from ultralytics.yolo.utils.checks import check_requirements, check_yaml from ultralytics.yolo.utils.downloads import unzip_file from ultralytics.yolo.utils.ops import clean_str, segments2boxes, xyn2xy, xywh2xyxy, xywhn2xyxy, xyxy2xywhn from ultralytics.yolo.utils.torch_utils import torch_distributed_zero_first + from .v5augmentations import (Albumentations, augment_hsv, classify_albumentations, classify_transforms, copy_paste, letterbox, mixup, random_perspective) diff --git a/ultralytics/yolo/data/dataset.py b/ultralytics/yolo/data/dataset.py index fc58f6c..5f98120 100644 --- a/ultralytics/yolo/data/dataset.py +++ b/ultralytics/yolo/data/dataset.py @@ -85,7 +85,6 @@ class YOLODataset(BaseDataset): x["results"] = nf, nm, ne, nc, len(self.im_files) x["msgs"] = msgs # warnings x["version"] = self.cache_version # cache version - self.im_files = [lb["im_file"] for lb in x["labels"]] # update im_files if is_dir_writeable(path.parent): np.save(str(path), x) # save cache for next time path.with_suffix(".cache.npy").rename(path) # remove .npy suffix @@ -117,6 +116,7 @@ class YOLODataset(BaseDataset): # Read cache [cache.pop(k) for k in ("hash", "version", "msgs")] # remove items labels = cache["labels"] + self.im_files = [lb["im_file"] for lb in labels] # update im_files # Check if the dataset is all boxes or all segments len_cls = sum(len(lb["cls"]) for lb in labels) diff --git a/ultralytics/yolo/engine/exporter.py b/ultralytics/yolo/engine/exporter.py index 760312f..053ba52 100644 --- a/ultralytics/yolo/engine/exporter.py +++ b/ultralytics/yolo/engine/exporter.py @@ -64,14 +64,13 @@ import numpy as np import pandas as pd import torch -import ultralytics from ultralytics.nn.autobackend import check_class_names from ultralytics.nn.modules import Detect, Segment from ultralytics.nn.tasks import DetectionModel, SegmentationModel from ultralytics.yolo.cfg import get_cfg from ultralytics.yolo.data.dataloaders.stream_loaders import LoadImages -from ultralytics.yolo.data.utils import check_det_dataset, IMAGENET_MEAN, IMAGENET_STD -from ultralytics.yolo.utils import DEFAULT_CFG, LOGGER, callbacks, colorstr, get_default_args, yaml_save +from ultralytics.yolo.data.utils import IMAGENET_MEAN, IMAGENET_STD, check_det_dataset +from ultralytics.yolo.utils import DEFAULT_CFG, LOGGER, __version__, callbacks, colorstr, get_default_args, yaml_save from ultralytics.yolo.utils.checks import check_imgsz, check_requirements, check_version, check_yaml from ultralytics.yolo.utils.files import file_size from ultralytics.yolo.utils.ops import Profile @@ -209,7 +208,7 @@ class Exporter: 'description': f"Ultralytics {self.pretty_name} model trained on {self.model.args['data']}", 'author': 'Ultralytics', 'license': 'GPL-3.0 https://ultralytics.com/license', - 'version': ultralytics.__version__, + 'version': __version__, 'stride': int(max(model.stride)), 'names': model.names} # model metadata diff --git a/ultralytics/yolo/engine/model.py b/ultralytics/yolo/engine/model.py index 7ae9bf7..7b0e61f 100644 --- a/ultralytics/yolo/engine/model.py +++ b/ultralytics/yolo/engine/model.py @@ -1,16 +1,17 @@ # Ultralytics YOLO 🚀, GPL-3.0 license +import sys from pathlib import Path from typing import List -import sys from ultralytics import yolo # noqa from ultralytics.nn.tasks import (ClassificationModel, DetectionModel, SegmentationModel, attempt_load_one_weight, guess_model_task) from ultralytics.yolo.cfg import get_cfg from ultralytics.yolo.engine.exporter import Exporter from ultralytics.yolo.utils import DEFAULT_CFG, LOGGER, RANK, callbacks, yaml_load -from ultralytics.yolo.utils.checks import check_yaml, check_imgsz +from ultralytics.yolo.utils.checks import check_imgsz, check_yaml +from ultralytics.yolo.utils.downloads import GITHUB_ASSET_STEMS from ultralytics.yolo.utils.torch_utils import smart_inference_mode # Map head to model, trainer, validator, and predictor classes @@ -58,10 +59,13 @@ class YOLO: # Load or create new YOLO model load_methods = {'.pt': self._load, '.yaml': self._new} suffix = Path(model).suffix + 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 if suffix in load_methods: {'.pt': self._load, '.yaml': self._new}[suffix](model) else: - raise NotImplementedError(f"'{suffix}' model loading not implemented") + raise NotImplementedError(f"'{suffix}' models not supported. Try a *.pt and *.yaml model, " + "i.e. model='yolov8n.pt' or model='yolov8n.yaml'") def __call__(self, source=None, stream=False, **kwargs): return self.predict(source, stream, **kwargs) diff --git a/ultralytics/yolo/engine/trainer.py b/ultralytics/yolo/engine/trainer.py index 3724d6a..0a81e6d 100644 --- a/ultralytics/yolo/engine/trainer.py +++ b/ultralytics/yolo/engine/trainer.py @@ -20,12 +20,11 @@ from torch.nn.parallel import DistributedDataParallel as DDP from torch.optim import lr_scheduler from tqdm import tqdm -from ultralytics import __version__ from ultralytics.nn.tasks import attempt_load_one_weight, attempt_load_weights from ultralytics.yolo.cfg import get_cfg from ultralytics.yolo.data.utils import check_cls_dataset, check_det_dataset -from ultralytics.yolo.utils import (DEFAULT_CFG, LOGGER, RANK, SETTINGS, TQDM_BAR_FORMAT, callbacks, colorstr, emojis, - yaml_save) +from ultralytics.yolo.utils import (DEFAULT_CFG, LOGGER, RANK, SETTINGS, TQDM_BAR_FORMAT, __version__, callbacks, + colorstr, emojis, yaml_save) from ultralytics.yolo.utils.autobatch import check_train_batch_size from ultralytics.yolo.utils.checks import check_file, check_imgsz, print_args from ultralytics.yolo.utils.dist import ddp_cleanup, generate_ddp_command @@ -51,6 +50,7 @@ class BaseTrainer: wdir (Path): Directory to save weights. last (Path): Path to last checkpoint. best (Path): Path to best checkpoint. + save_period (int): Save checkpoint every x epochs (disabled if < 1). batch_size (int): Batch size for training. epochs (int): Number of epochs to train for. start_epoch (int): Starting epoch for training. @@ -101,6 +101,7 @@ class BaseTrainer: self.args.save_dir = str(self.save_dir) yaml_save(self.save_dir / 'args.yaml', vars(self.args)) # save run args self.last, self.best = self.wdir / 'last.pt', self.wdir / 'best.pt' # checkpoint paths + self.save_period = self.args.save_period self.batch_size = self.args.batch self.epochs = self.args.epochs @@ -392,6 +393,8 @@ class BaseTrainer: torch.save(ckpt, self.last) if self.best_fitness == self.fitness: torch.save(ckpt, self.best) + if (self.epoch > 0) and (self.save_period > 0) and (self.epoch % self.save_period == 0): + torch.save(ckpt, self.wdir / f'epoch{self.epoch}.pt') del ckpt def get_dataset(self, data): diff --git a/ultralytics/yolo/utils/__init__.py b/ultralytics/yolo/utils/__init__.py index de59e9d..2309764 100644 --- a/ultralytics/yolo/utils/__init__.py +++ b/ultralytics/yolo/utils/__init__.py @@ -22,6 +22,8 @@ import requests import torch import yaml +from ultralytics import __version__ + # Constants FILE = Path(__file__).resolve() ROOT = FILE.parents[2] # YOLO @@ -520,30 +522,27 @@ def set_sentry(): if 'exc_info' in hint: exc_type, exc_value, tb = hint['exc_info'] if exc_type in (KeyboardInterrupt, FileNotFoundError) \ - or 'out of memory' in str(exc_value) \ - or not sys.argv[0].endswith('yolo'): + or 'out of memory' in str(exc_value): return None # do not send event - env = 'Colab' if is_colab() else 'Kaggle' if is_kaggle() else 'Jupyter' if is_jupyter() else \ - 'Docker' if is_docker() else platform.system() event['tags'] = { "sys_argv": sys.argv[0], "sys_argv_name": Path(sys.argv[0]).name, "install": 'git' if is_git_dir() else 'pip' if is_pip_package() else 'other', - "os": env} + "os": ENVIRONMENT} return event if SETTINGS['sync'] and \ RANK in {-1, 0} and \ - sys.argv[0].endswith('yolo') and \ + Path(sys.argv[0]).name == 'yolo' and \ not is_pytest_running() and \ not is_github_actions_ci() and \ ((is_pip_package() and not is_git_dir()) or (get_git_origin_url() == "https://github.com/ultralytics/ultralytics.git" and get_git_branch() == "main")): import hashlib + import sentry_sdk # noqa - from ultralytics import __version__ sentry_sdk.init( dsn="https://f805855f03bb4363bc1e16cb7d87b654@o4504521589325824.ingest.sentry.io/4504521592406016", @@ -572,6 +571,7 @@ def get_settings(file=USER_CONFIG_DIR / 'settings.yaml', version='0.0.2'): dict: Dictionary of settings key-value pairs. """ import hashlib + from ultralytics.yolo.utils.checks import check_version from ultralytics.yolo.utils.torch_utils import torch_distributed_zero_first @@ -628,4 +628,6 @@ if platform.system() == 'Windows': PREFIX = colorstr("Ultralytics: ") SETTINGS = get_settings() DATASETS_DIR = Path(SETTINGS['datasets_dir']) # global datasets directory +ENVIRONMENT = 'Colab' if is_colab() else 'Kaggle' if is_kaggle() else 'Jupyter' if is_jupyter() else \ + 'Docker' if is_docker() else platform.system() set_sentry() diff --git a/ultralytics/yolo/utils/checks.py b/ultralytics/yolo/utils/checks.py index 0bb8e61..9a03fc1 100644 --- a/ultralytics/yolo/utils/checks.py +++ b/ultralytics/yolo/utils/checks.py @@ -155,7 +155,7 @@ def check_online() -> bool: bool: True if connection is successful, False otherwise. """ import socket - with contextlib.suppress(subprocess.CalledProcessError): + with contextlib.suppress(Exception): host = socket.gethostbyname("www.github.com") socket.create_connection((host, 80), timeout=2) return True diff --git a/ultralytics/yolo/utils/downloads.py b/ultralytics/yolo/utils/downloads.py index ff2df8a..d80bb19 100644 --- a/ultralytics/yolo/utils/downloads.py +++ b/ultralytics/yolo/utils/downloads.py @@ -6,7 +6,7 @@ from itertools import repeat from multiprocessing.pool import ThreadPool from pathlib import Path from urllib import parse, request -from zipfile import ZipFile, is_zipfile, BadZipFile +from zipfile import BadZipFile, ZipFile, is_zipfile import requests import torch @@ -14,6 +14,11 @@ from tqdm import tqdm from ultralytics.yolo.utils import LOGGER +GITHUB_ASSET_NAMES = [f'yolov8{size}{suffix}.pt' for size in 'nsmlx' for suffix in ('', '6', '-cls', '-seg')] + \ + [f'yolov5{size}u.pt' for size in 'nsmlx'] + \ + [f'yolov3{size}u.pt' for size in ('', '-spp', '-tiny')] +GITHUB_ASSET_STEMS = [Path(k).stem for k in GITHUB_ASSET_NAMES] + def is_url(url, check=True): # Check if string is URL and check if URL exists @@ -158,9 +163,7 @@ def attempt_download_asset(file, repo='ultralytics/assets', release='v0.0.0'): return file # GitHub assets - assets = [f'yolov8{size}{suffix}.pt' for size in 'nsmlx' for suffix in ('', '6', '-cls', '-seg')] + \ - [f'yolov5{size}u.pt' for size in 'nsmlx'] + \ - [f'yolov3{size}u.pt' for size in ('', '-spp', '-tiny')] + assets = GITHUB_ASSET_NAMES try: tag, assets = github_assets(repo, release) except Exception: diff --git a/ultralytics/yolo/utils/torch_utils.py b/ultralytics/yolo/utils/torch_utils.py index 9cf5839..0f0114c 100644 --- a/ultralytics/yolo/utils/torch_utils.py +++ b/ultralytics/yolo/utils/torch_utils.py @@ -17,7 +17,7 @@ import torch.nn as nn 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 +from ultralytics.yolo.utils import DEFAULT_CFG_DICT, DEFAULT_CFG_KEYS, LOGGER, __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 @@ -61,7 +61,6 @@ def DDP_model(model): def select_device(device='', batch=0, newline=False): # device = None or 'cpu' or 0 or '0' or '0,1,2,3' - from ultralytics import __version__ s = f"Ultralytics YOLOv{__version__} 🚀 Python-{platform.python_version()} torch-{torch.__version__} " device = str(device).lower() for remove in 'cuda:', 'none', '(', ')', '[', ']', "'", ' ': diff --git a/ultralytics/yolo/v8/classify/train.py b/ultralytics/yolo/v8/classify/train.py index b35c868..2a149d1 100644 --- a/ultralytics/yolo/v8/classify/train.py +++ b/ultralytics/yolo/v8/classify/train.py @@ -8,7 +8,7 @@ from ultralytics.yolo import v8 from ultralytics.yolo.data import build_classification_dataloader from ultralytics.yolo.engine.trainer import BaseTrainer from ultralytics.yolo.utils import DEFAULT_CFG -from ultralytics.yolo.utils.torch_utils import strip_optimizer, is_parallel +from ultralytics.yolo.utils.torch_utils import is_parallel, strip_optimizer class ClassificationTrainer(BaseTrainer):