ultralytics 8.0.187 deprecate ultralytics.yolo usage (#5084)

Co-authored-by: Francisco Javier Gañán <95186237+javierganan99@users.noreply.github.com>
This commit is contained in:
Glenn Jocher 2023-09-26 02:25:35 +02:00 committed by GitHub
parent eb976f5ad2
commit f2ed207571
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 33 additions and 118 deletions

View File

@ -23,9 +23,8 @@ RUN apt upgrade --no-install-recommends -y openssl tar
WORKDIR /usr/src/ultralytics WORKDIR /usr/src/ultralytics
# Copy contents # Copy contents
COPY . /usr/src/ultralytics
# COPY . /usr/src/ultralytics # git permission issues inside container # COPY . /usr/src/ultralytics # git permission issues inside container
# RUN git clone https://github.com/ultralytics/ultralytics -b main /usr/src/ultralytics RUN git clone https://github.com/ultralytics/ultralytics -b main /usr/src/ultralytics
ADD https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8n.pt /usr/src/ultralytics/ ADD https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8n.pt /usr/src/ultralytics/
# Install pip packages # Install pip packages

View File

@ -1,6 +1,6 @@
# Ultralytics YOLO 🚀, AGPL-3.0 license # Ultralytics YOLO 🚀, AGPL-3.0 license
__version__ = '8.0.186' __version__ = '8.0.187'
from ultralytics.models import RTDETR, SAM, YOLO from ultralytics.models import RTDETR, SAM, YOLO
from ultralytics.models.fastsam import FastSAM from ultralytics.models.fastsam import FastSAM

View File

@ -1,7 +1,6 @@
# Ultralytics YOLO 🚀, AGPL-3.0 license # Ultralytics YOLO 🚀, AGPL-3.0 license
import contextlib import contextlib
import re
import shutil import shutil
import sys import sys
from pathlib import Path from pathlib import Path
@ -291,19 +290,20 @@ def handle_yolo_settings(args: List[str]) -> None:
def parse_key_value_pair(pair): def parse_key_value_pair(pair):
"""Parse one 'key=value' pair and return key and value.""" """Parse one 'key=value' pair and return key and value."""
re.sub(r' *= *', '=', pair) # remove spaces around equals sign
k, v = pair.split('=', 1) # split on first '=' sign k, v = pair.split('=', 1) # split on first '=' sign
k, v = k.strip(), v.strip() # remove spaces
assert v, f"missing '{k}' value" assert v, f"missing '{k}' value"
return k, smart_value(v) return k, smart_value(v)
def smart_value(v): def smart_value(v):
"""Convert a string to an underlying type such as int, float, bool, etc.""" """Convert a string to an underlying type such as int, float, bool, etc."""
if v.lower() == 'none': v_lower = v.lower()
if v_lower == 'none':
return None return None
elif v.lower() == 'true': elif v_lower == 'true':
return True return True
elif v.lower() == 'false': elif v_lower == 'false':
return False return False
else: else:
with contextlib.suppress(Exception): with contextlib.suppress(Exception):

View File

@ -430,19 +430,12 @@ class Boxes(BaseTensor):
xywh[..., [1, 3]] /= self.orig_shape[0] xywh[..., [1, 3]] /= self.orig_shape[0]
return xywh return xywh
@property
def boxes(self):
"""Return the raw bboxes tensor (deprecated)."""
LOGGER.warning("WARNING ⚠️ 'Boxes.boxes' is deprecated. Use 'Boxes.data' instead.")
return self.data
class Masks(BaseTensor): class Masks(BaseTensor):
""" """
A class for storing and manipulating detection masks. A class for storing and manipulating detection masks.
Attributes: Attributes:
segments (list): Deprecated property for segments (normalized).
xy (list): A list of segments in pixel coordinates. xy (list): A list of segments in pixel coordinates.
xyn (list): A list of normalized segments. xyn (list): A list of normalized segments.
@ -459,15 +452,6 @@ class Masks(BaseTensor):
masks = masks[None, :] masks = masks[None, :]
super().__init__(masks, orig_shape) super().__init__(masks, orig_shape)
@property
@lru_cache(maxsize=1)
def segments(self):
"""Return segments (normalized). Deprecated; use xyn property instead."""
LOGGER.warning(
"WARNING ⚠️ 'Masks.segments' is deprecated. Use 'Masks.xyn' for segments (normalized) and 'Masks.xy' for segments (pixels) instead."
)
return self.xyn
@property @property
@lru_cache(maxsize=1) @lru_cache(maxsize=1)
def xyn(self): def xyn(self):
@ -484,12 +468,6 @@ class Masks(BaseTensor):
ops.scale_coords(self.data.shape[1:], x, self.orig_shape, normalize=False) ops.scale_coords(self.data.shape[1:], x, self.orig_shape, normalize=False)
for x in ops.masks2segments(self.data)] for x in ops.masks2segments(self.data)]
@property
def masks(self):
"""Return the raw masks tensor. Deprecated; use data attribute instead."""
LOGGER.warning("WARNING ⚠️ 'Masks.masks' is deprecated. Use 'Masks.data' instead.")
return self.data
class Keypoints(BaseTensor): class Keypoints(BaseTensor):
""" """

View File

@ -11,7 +11,7 @@ import shutil
import subprocess import subprocess
import sys import sys
import time import time
from importlib.metadata import PackageNotFoundError, version from importlib import metadata
from pathlib import Path from pathlib import Path
from typing import Optional from typing import Optional
@ -26,19 +26,32 @@ from ultralytics.utils import (ASSETS, AUTOINSTALL, LINUX, LOGGER, ONLINE, ROOT,
is_jupyter, is_kaggle, is_online, is_pip_package, url2file) is_jupyter, is_kaggle, is_online, is_pip_package, url2file)
def parse_requirements(file_path=ROOT.parent / 'requirements.txt'): def parse_requirements(file_path=ROOT.parent / 'requirements.txt', package=''):
""" """
Parse a requirements.txt file, ignoring lines that start with '#' and any text after '#'. Parse a requirements.txt file, ignoring lines that start with '#' and any text after '#'.
Args: Args:
file_path (Path): Path to the requirements.txt file. file_path (Path): Path to the requirements.txt file.
package (str, optional): Python package to use instead of requirements.txt file, i.e. package='ultralytics'.
Returns: Returns:
(List[Dict[str, str]]): List of parsed requirements as dictionaries with `name` and `specifier` keys. (List[Dict[str, str]]): List of parsed requirements as dictionaries with `name` and `specifier` keys.
Example:
```python
from ultralytics.utils.checks import parse_requirements
parse_requirements(package='ultralytics')
```
""" """
if package:
requires = [x for x in metadata.distribution(package).requires if 'extra == ' not in x]
else:
requires = Path(file_path).read_text().splitlines()
requirements = [] requirements = []
for line in Path(file_path).read_text().splitlines(): for line in requires:
line = line.strip() line = line.strip()
if line and not line.startswith('#'): if line and not line.startswith('#'):
line = line.split('#')[0].strip() # ignore inline comments line = line.split('#')[0].strip() # ignore inline comments
@ -63,9 +76,8 @@ def parse_version(version='0.0.0') -> tuple:
try: try:
return tuple(map(int, re.findall(r'\d+', version)[:3])) # '2.0.1+cpu' -> (2, 0, 1) return tuple(map(int, re.findall(r'\d+', version)[:3])) # '2.0.1+cpu' -> (2, 0, 1)
except Exception as e: except Exception as e:
LOGGER.warning(f'WARNING ⚠️ failure for parse_version({version}), reverting to deprecated pkg_resources: {e}') LOGGER.warning(f'WARNING ⚠️ failure for parse_version({version}), returning (0, 0, 0): {e}')
import pkg_resources return 0, 0, 0
return pkg_resources.parse_version(version).release
def is_ascii(s) -> bool: def is_ascii(s) -> bool:
@ -172,8 +184,8 @@ def check_version(current: str = '0.0.0',
elif not current[0].isdigit(): # current is package name rather than version string, i.e. current='ultralytics' elif not current[0].isdigit(): # current is package name rather than version string, i.e. current='ultralytics'
try: try:
name = current # assigned package name to 'name' arg name = current # assigned package name to 'name' arg
current = version(current) # get version string from package name current = metadata.version(current) # get version string from package name
except PackageNotFoundError: except metadata.PackageNotFoundError:
if hard: if hard:
raise ModuleNotFoundError(emojis(f'WARNING ⚠️ {current} package is required but not installed')) raise ModuleNotFoundError(emojis(f'WARNING ⚠️ {current} package is required but not installed'))
else: else:
@ -329,8 +341,8 @@ def check_requirements(requirements=ROOT.parent / 'requirements.txt', exclude=()
match = re.match(r'([a-zA-Z0-9-_]+)([<>!=~]+.*)?', r_stripped) match = re.match(r'([a-zA-Z0-9-_]+)([<>!=~]+.*)?', r_stripped)
name, required = match[1], match[2].strip() if match[2] else '' name, required = match[1], match[2].strip() if match[2] else ''
try: try:
assert check_version(version(name), required) # exception if requirements not met assert check_version(metadata.version(name), required) # exception if requirements not met
except (AssertionError, PackageNotFoundError): except (AssertionError, metadata.PackageNotFoundError):
pkgs.append(r) pkgs.append(r)
s = ' '.join(f'"{x}"' for x in pkgs) # console string s = ' '.join(f'"{x}"' for x in pkgs) # console string
@ -503,14 +515,8 @@ def collect_system_info():
f"{'CPU':<20}{get_cpu_info()}\n" f"{'CPU':<20}{get_cpu_info()}\n"
f"{'CUDA':<20}{torch.version.cuda if torch and torch.cuda.is_available() else None}\n") f"{'CUDA':<20}{torch.version.cuda if torch and torch.cuda.is_available() else None}\n")
if (ROOT.parent / 'requirements.txt').exists(): # git install for r in parse_requirements(package='ultralytics'):
requirements = parse_requirements() current = metadata.version(r.name)
else: # pip install
from pkg_resources import get_distribution
requirements = get_distribution('ultralytics').requires()
for r in requirements:
current = version(r.name)
is_met = '' if check_version(current, str(r.specifier)) else '' is_met = '' if check_version(current, str(r.specifier)) else ''
LOGGER.info(f'{r.name:<20}{is_met}{current}{r.specifier}') LOGGER.info(f'{r.name:<20}{is_met}{current}{r.specifier}')
@ -559,9 +565,8 @@ def check_amp(model):
except ConnectionError: except ConnectionError:
LOGGER.warning(f'{prefix}checks skipped ⚠️, offline and unable to download YOLOv8n. {warning_msg}') LOGGER.warning(f'{prefix}checks skipped ⚠️, offline and unable to download YOLOv8n. {warning_msg}')
except (AttributeError, ModuleNotFoundError): except (AttributeError, ModuleNotFoundError):
LOGGER.warning( LOGGER.warning(f'{prefix}checks skipped ⚠️. '
f'{prefix}checks skipped ⚠️. Unable to load YOLOv8n due to possible Ultralytics package modifications. {warning_msg}' f'Unable to load YOLOv8n due to possible Ultralytics package modifications. {warning_msg}')
)
except AssertionError: except AssertionError:
LOGGER.warning(f'{prefix}checks failed ❌. Anomalies were detected with AMP on your system that may lead to ' LOGGER.warning(f'{prefix}checks failed ❌. Anomalies were detected with AMP on your system that may lead to '
f'NaN losses or zero-mAP results, so AMP will be disabled during training.') f'NaN losses or zero-mAP results, so AMP will be disabled during training.')

View File

@ -1,5 +0,0 @@
# Ultralytics YOLO 🚀, AGPL-3.0 license
from . import v8
__all__ = 'v8', # tuple or list

View File

@ -1,10 +0,0 @@
import importlib
import sys
from ultralytics.utils import LOGGER
# Set modules in sys.modules under their old name
sys.modules['ultralytics.yolo.cfg'] = importlib.import_module('ultralytics.cfg')
LOGGER.warning("WARNING ⚠️ 'ultralytics.yolo.cfg' is deprecated since '8.0.136' and will be removed in '8.1.0'. "
"Please use 'ultralytics.cfg' instead.")

View File

@ -1,17 +0,0 @@
import importlib
import sys
from ultralytics.utils import LOGGER
# Set modules in sys.modules under their old name
sys.modules['ultralytics.yolo.data'] = importlib.import_module('ultralytics.data')
# This is for updating old cls models, or the way in following warning won't work.
sys.modules['ultralytics.yolo.data.augment'] = importlib.import_module('ultralytics.data.augment')
DATA_WARNING = """WARNING ⚠️ 'ultralytics.yolo.data' is deprecated since '8.0.136' and will be removed in '8.1.0'. Please use 'ultralytics.data' instead.
Note this warning may be related to loading older models. You can update your model to current structure with:
import torch
ckpt = torch.load("model.pt") # applies to both official and custom models
torch.save(ckpt, "updated-model.pt")
"""
LOGGER.warning(DATA_WARNING)

View File

@ -1,10 +0,0 @@
import importlib
import sys
from ultralytics.utils import LOGGER
# Set modules in sys.modules under their old name
sys.modules['ultralytics.yolo.engine'] = importlib.import_module('ultralytics.engine')
LOGGER.warning("WARNING ⚠️ 'ultralytics.yolo.engine' is deprecated since '8.0.136' and will be removed in '8.1.0'. "
"Please use 'ultralytics.engine' instead.")

View File

@ -1,15 +0,0 @@
import importlib
import sys
from ultralytics.utils import LOGGER
# Set modules in sys.modules under their old name
sys.modules['ultralytics.yolo.utils'] = importlib.import_module('ultralytics.utils')
UTILS_WARNING = """WARNING ⚠️ 'ultralytics.yolo.utils' is deprecated since '8.0.136' and will be removed in '8.1.0'. Please use 'ultralytics.utils' instead.
Note this warning may be related to loading older models. You can update your model to current structure with:
import torch
ckpt = torch.load("model.pt") # applies to both official and custom models
torch.save(ckpt, "updated-model.pt")
"""
LOGGER.warning(UTILS_WARNING)

View File

@ -1,10 +0,0 @@
import importlib
import sys
from ultralytics.utils import LOGGER
# Set modules in sys.modules under their old name
sys.modules['ultralytics.yolo.v8'] = importlib.import_module('ultralytics.models.yolo')
LOGGER.warning("WARNING ⚠️ 'ultralytics.yolo.v8' is deprecated since '8.0.136' and will be removed in '8.1.0'. "
"Please use 'ultralytics.models.yolo' instead.")