ultralytics 8.0.51
add assets and CI actions (#1296)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Paul Kehrer <paulhkehrer@gmail.com>
This commit is contained in:
@ -327,4 +327,4 @@ def copy_default_cfg():
|
||||
|
||||
if __name__ == '__main__':
|
||||
# entrypoint(debug='yolo predict model=yolov8n.pt')
|
||||
entrypoint(debug='yolo train model=yolov8n-seg.pt')
|
||||
entrypoint(debug='')
|
||||
|
@ -210,8 +210,7 @@ def check_det_dataset(dataset, autodownload=True):
|
||||
for k in 'train', 'val', 'names':
|
||||
if k not in data:
|
||||
raise SyntaxError(
|
||||
emojis(f"{dataset} '{k}:' key missing ❌.\n"
|
||||
f"'train', 'val' and 'names' are required in data.yaml files."))
|
||||
emojis(f"{dataset} '{k}:' key missing ❌.\n'train', 'val' and 'names' are required in all data YAMLs."))
|
||||
data['names'] = check_class_names(data['names'])
|
||||
data['nc'] = len(data['names'])
|
||||
|
||||
@ -236,11 +235,11 @@ def check_det_dataset(dataset, autodownload=True):
|
||||
if val:
|
||||
val = [Path(x).resolve() for x in (val if isinstance(val, list) else [val])] # val path
|
||||
if not all(x.exists() for x in val):
|
||||
msg = f"\nDataset '{dataset}' not found ⚠️, missing paths %s" % [str(x) for x in val if not x.exists()]
|
||||
m = f"\nDataset '{dataset}' images not found ⚠️, missing paths %s" % [str(x) for x in val if not x.exists()]
|
||||
if s and autodownload:
|
||||
LOGGER.warning(msg)
|
||||
LOGGER.warning(m)
|
||||
else:
|
||||
raise FileNotFoundError(msg)
|
||||
raise FileNotFoundError(m)
|
||||
t = time.time()
|
||||
if s.startswith('http') and s.endswith('.zip'): # URL
|
||||
safe_download(url=s, dir=DATASETS_DIR, delete=True)
|
||||
|
@ -69,7 +69,7 @@ from ultralytics.yolo.data.dataloaders.stream_loaders import LoadImages
|
||||
from ultralytics.yolo.data.utils import IMAGENET_MEAN, IMAGENET_STD, check_det_dataset
|
||||
from ultralytics.yolo.utils import (DEFAULT_CFG, LINUX, LOGGER, MACOS, __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.checks import check_imgsz, check_requirements, check_version
|
||||
from ultralytics.yolo.utils.files import file_size
|
||||
from ultralytics.yolo.utils.ops import Profile
|
||||
from ultralytics.yolo.utils.torch_utils import get_latest_opset, select_device, smart_inference_mode
|
||||
@ -601,7 +601,7 @@ class Exporter:
|
||||
if n >= n_images:
|
||||
break
|
||||
|
||||
dataset = LoadImages(check_det_dataset(check_yaml(self.args.data))['train'], imgsz=imgsz, auto=False)
|
||||
dataset = LoadImages(check_det_dataset(self.args.data)['train'], imgsz=imgsz, auto=False)
|
||||
converter.representative_dataset = lambda: representative_dataset_gen(dataset, n_images=100)
|
||||
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
|
||||
converter.target_spec.supported_types = []
|
||||
|
@ -10,7 +10,7 @@ from ultralytics.yolo.cfg import get_cfg
|
||||
from ultralytics.yolo.engine.exporter import Exporter
|
||||
from ultralytics.yolo.utils import (DEFAULT_CFG, DEFAULT_CFG_DICT, DEFAULT_CFG_KEYS, LOGGER, ONLINE, RANK, ROOT,
|
||||
callbacks, is_git_dir, is_pip_package, yaml_load)
|
||||
from ultralytics.yolo.utils.checks import check_file, check_imgsz, check_pip_update, check_yaml
|
||||
from ultralytics.yolo.utils.checks import check_file, check_imgsz, check_pip_update_available, check_yaml
|
||||
from ultralytics.yolo.utils.downloads import GITHUB_ASSET_STEMS
|
||||
from ultralytics.yolo.utils.torch_utils import smart_inference_mode
|
||||
|
||||
@ -158,7 +158,7 @@ class YOLO:
|
||||
Inform user of ultralytics package update availability
|
||||
"""
|
||||
if ONLINE and is_pip_package():
|
||||
check_pip_update()
|
||||
check_pip_update_available()
|
||||
|
||||
def reset(self):
|
||||
"""
|
||||
|
@ -263,8 +263,11 @@ class Boxes:
|
||||
return self.boxes.__str__()
|
||||
|
||||
def __repr__(self):
|
||||
return (f'Ultralytics YOLO {self.__class__.__name__}\n' + f'type: {type(self.boxes)}\n' +
|
||||
f'shape: {self.boxes.shape}\n' + f'dtype: {self.boxes.dtype}\n + {self.boxes.__repr__()}')
|
||||
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):
|
||||
return Boxes(self.boxes[idx], self.orig_shape)
|
||||
@ -339,8 +342,11 @@ class Masks:
|
||||
return self.masks.__str__()
|
||||
|
||||
def __repr__(self):
|
||||
return (f'Ultralytics YOLO {self.__class__.__name__}\n' + f'type: {type(self.masks)}\n' +
|
||||
f'shape: {self.masks.shape}\n' + f'dtype: {self.masks.dtype}\n + {self.masks.__repr__()}')
|
||||
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):
|
||||
return Masks(self.masks[idx], self.orig_shape)
|
||||
|
@ -126,6 +126,37 @@ class IterableSimpleNamespace(SimpleNamespace):
|
||||
return getattr(self, key, default)
|
||||
|
||||
|
||||
def set_logging(name=LOGGING_NAME, verbose=True):
|
||||
# sets up logging for the given name
|
||||
rank = int(os.getenv('RANK', -1)) # rank in world for Multi-GPU trainings
|
||||
level = logging.INFO if verbose and rank in {-1, 0} else logging.ERROR
|
||||
logging.config.dictConfig({
|
||||
'version': 1,
|
||||
'disable_existing_loggers': False,
|
||||
'formatters': {
|
||||
name: {
|
||||
'format': '%(message)s'}},
|
||||
'handlers': {
|
||||
name: {
|
||||
'class': 'logging.StreamHandler',
|
||||
'formatter': name,
|
||||
'level': level}},
|
||||
'loggers': {
|
||||
name: {
|
||||
'level': level,
|
||||
'handlers': [name],
|
||||
'propagate': False}}})
|
||||
|
||||
|
||||
# Set logger
|
||||
set_logging(LOGGING_NAME, verbose=VERBOSE) # run before defining LOGGER
|
||||
LOGGER = logging.getLogger(LOGGING_NAME) # define globally (used in train.py, val.py, detect.py, etc.)
|
||||
if WINDOWS: # emoji-safe logging
|
||||
info_fn, warning_fn = LOGGER.info, LOGGER.warning
|
||||
setattr(LOGGER, info_fn.__name__, lambda x: info_fn(emojis(x)))
|
||||
setattr(LOGGER, warning_fn.__name__, lambda x: warning_fn(emojis(x)))
|
||||
|
||||
|
||||
def yaml_save(file='data.yaml', data=None):
|
||||
"""
|
||||
Save YAML data to a file.
|
||||
@ -163,10 +194,13 @@ def yaml_load(file='data.yaml', append_filename=False):
|
||||
dict: YAML data and file name.
|
||||
"""
|
||||
with open(file, errors='ignore', encoding='utf-8') as f:
|
||||
# Add YAML filename to dict and return
|
||||
s = f.read() # string
|
||||
if not s.isprintable(): # remove special characters
|
||||
|
||||
# Remove special characters
|
||||
if not s.isprintable():
|
||||
s = re.sub(r'[^\x09\x0A\x0D\x20-\x7E\x85\xA0-\uD7FF\uE000-\uFFFD\U00010000-\U0010ffff]+', '', s)
|
||||
|
||||
# Add YAML filename to dict and return
|
||||
return {**yaml.safe_load(s), 'yaml_file': str(file)} if append_filename else yaml.safe_load(s)
|
||||
|
||||
|
||||
@ -448,41 +482,6 @@ def colorstr(*input):
|
||||
return ''.join(colors[x] for x in args) + f'{string}' + colors['end']
|
||||
|
||||
|
||||
def remove_ansi_codes(string):
|
||||
"""
|
||||
Remove ANSI escape sequences from a string.
|
||||
|
||||
Args:
|
||||
string (str): The input string that may contain ANSI escape sequences.
|
||||
|
||||
Returns:
|
||||
str: The input string with ANSI escape sequences removed.
|
||||
"""
|
||||
return re.sub(r'\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]', '', string)
|
||||
|
||||
|
||||
def set_logging(name=LOGGING_NAME, verbose=True):
|
||||
# sets up logging for the given name
|
||||
rank = int(os.getenv('RANK', -1)) # rank in world for Multi-GPU trainings
|
||||
level = logging.INFO if verbose and rank in {-1, 0} else logging.ERROR
|
||||
logging.config.dictConfig({
|
||||
'version': 1,
|
||||
'disable_existing_loggers': False,
|
||||
'formatters': {
|
||||
name: {
|
||||
'format': '%(message)s'}},
|
||||
'handlers': {
|
||||
name: {
|
||||
'class': 'logging.StreamHandler',
|
||||
'formatter': name,
|
||||
'level': level}},
|
||||
'loggers': {
|
||||
name: {
|
||||
'level': level,
|
||||
'handlers': [name],
|
||||
'propagate': False}}})
|
||||
|
||||
|
||||
class TryExcept(contextlib.ContextDecorator):
|
||||
# YOLOv8 TryExcept class. Usage: @TryExcept() decorator or 'with TryExcept():' context manager
|
||||
def __init__(self, msg='', verbose=True):
|
||||
@ -609,13 +608,6 @@ def set_settings(kwargs, file=USER_CONFIG_DIR / 'settings.yaml'):
|
||||
|
||||
# Run below code on yolo/utils init ------------------------------------------------------------------------------------
|
||||
|
||||
# Set logger
|
||||
set_logging(LOGGING_NAME, verbose=VERBOSE) # run before defining LOGGER
|
||||
LOGGER = logging.getLogger(LOGGING_NAME) # define globally (used in train.py, val.py, detect.py, etc.)
|
||||
if WINDOWS:
|
||||
for fn in LOGGER.info, LOGGER.warning:
|
||||
setattr(LOGGER, fn.__name__, lambda x: fn(emojis(x))) # emoji safe logging
|
||||
|
||||
# Check first-install steps
|
||||
PREFIX = colorstr('Ultralytics: ')
|
||||
SETTINGS = get_settings()
|
||||
|
@ -134,12 +134,20 @@ def check_latest_pypi_version(package_name='ultralytics'):
|
||||
return None
|
||||
|
||||
|
||||
def check_pip_update():
|
||||
def check_pip_update_available():
|
||||
"""
|
||||
Checks if a new version of the ultralytics package is available on PyPI.
|
||||
|
||||
Returns:
|
||||
bool: True if an update is available, False otherwise.
|
||||
"""
|
||||
from ultralytics import __version__
|
||||
latest = check_latest_pypi_version()
|
||||
if pkg.parse_version(__version__) < pkg.parse_version(latest):
|
||||
if pkg.parse_version(__version__) < pkg.parse_version(latest): # update is available
|
||||
LOGGER.info(f'New https://pypi.org/project/ultralytics/{latest} available 😃 '
|
||||
f"Update with 'pip install -U ultralytics'")
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def check_font(font='Arial.ttf'):
|
||||
|
@ -9,7 +9,6 @@ import matplotlib
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import seaborn as sn
|
||||
import torch
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
from PIL import __version__ as pil_version
|
||||
@ -161,6 +160,8 @@ class Annotator:
|
||||
|
||||
@TryExcept() # known issue https://github.com/ultralytics/yolov5/issues/5395
|
||||
def plot_labels(boxes, cls, names=(), save_dir=Path('')):
|
||||
import seaborn as sn
|
||||
|
||||
# plot dataset labels
|
||||
LOGGER.info(f"Plotting labels to {save_dir / 'labels.jpg'}... ")
|
||||
b = boxes.transpose() # classes, boxes
|
||||
|
Reference in New Issue
Block a user