DDP, Comet, URLError fixes, improved error handling (#658)

Co-authored-by: Ayush Chaurasia <ayush.chaurarsia@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Tungway1990 <68179274+Tungway1990@users.noreply.github.com>
single_channel
Glenn Jocher 2 years ago committed by GitHub
parent 6c44ce21d9
commit a5410ed79e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -52,26 +52,6 @@ To request an Enterprise License please complete the form at [Ultralytics Licens
</div> </div>
</div> </div>
## <div align="center">Ultralytics Live Session</div>
<div align="center">
[Ultralytics Live Session 3](https://youtu.be/IPcpYO5ITa8) ✨ is here! Join us on January 24th at 18 CET as we dive into
the latest advancements in YOLOv8, and demonstrate how to use this cutting-edge, SOTA model to improve your object
detection, instance segmentation, and image classification projects. See firsthand how YOLOv8's speed, accuracy, and
ease of use make it a top choice for professionals and researchers alike.
In addition to learning about the exciting new features and improvements of Ultralytics YOLOv8, you will also have the
opportunity to ask questions and interact with our team during the live Q&A session. We encourage you to come prepared
with any questions you may have.
To join the webinar, visit our YouTube [Channel](https://www.youtube.com/@Ultralytics/streams) and turn on your
notifications!
<a align="center" href="https://youtu.be/IPcpYO5ITa8" target="_blank">
<img width="80%" src="https://user-images.githubusercontent.com/107626595/212887899-e94b006c-5192-40fa-8b24-7b5428e065e8.png"></a>
</div>
## <div align="center">Documentation</div> ## <div align="center">Documentation</div>
See below for a quickstart installation and usage example, and see the [YOLOv8 Docs](https://docs.ultralytics.com) for See below for a quickstart installation and usage example, and see the [YOLOv8 Docs](https://docs.ultralytics.com) for

@ -50,6 +50,8 @@ def test_val_classify():
def test_predict_detect(): def test_predict_detect():
run(f"yolo predict detect model={MODEL}.pt source={ROOT / 'assets'} imgsz=32") run(f"yolo predict detect model={MODEL}.pt source={ROOT / 'assets'} imgsz=32")
run(f"yolo predict detect model={MODEL}.pt source=https://ultralytics.com/images/bus.jpg imgsz=32") run(f"yolo predict detect model={MODEL}.pt source=https://ultralytics.com/images/bus.jpg imgsz=32")
run(f"yolo predict detect model={MODEL}.pt source=https://ultralytics.com/assets/decelera_landscape.mov imgsz=32")
run(f"yolo predict detect model={MODEL}.pt source=https://ultralytics.com/assets/decelera_portrait.mov imgsz=32")
def test_predict_segment(): def test_predict_segment():

@ -1,6 +1,6 @@
# Ultralytics YOLO 🚀, GPL-3.0 license # Ultralytics YOLO 🚀, GPL-3.0 license
__version__ = "8.0.21" __version__ = "8.0.22"
from ultralytics.yolo.engine.model import YOLO from ultralytics.yolo.engine.model import YOLO
from ultralytics.yolo.utils import ops from ultralytics.yolo.utils import ops

@ -4,7 +4,6 @@ Common modules
""" """
import math import math
import warnings
import torch import torch
import torch.nn as nn import torch.nn as nn
@ -155,7 +154,7 @@ class C3(nn.Module):
self.cv1 = Conv(c1, c_, 1, 1) self.cv1 = Conv(c1, c_, 1, 1)
self.cv2 = Conv(c1, c_, 1, 1) self.cv2 = Conv(c1, c_, 1, 1)
self.cv3 = Conv(2 * c_, c2, 1) # optional act=FReLU(c2) self.cv3 = Conv(2 * c_, c2, 1) # optional act=FReLU(c2)
self.m = nn.Sequential(*(Bottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n))) self.m = nn.Sequential(*(Bottleneck(c_, c_, shortcut, g, k=((1, 1), (3, 3)), e=1.0) for _ in range(n)))
def forward(self, x): def forward(self, x):
return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), 1)) return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), 1))
@ -274,9 +273,7 @@ class SPP(nn.Module):
def forward(self, x): def forward(self, x):
x = self.cv1(x) x = self.cv1(x)
with warnings.catch_warnings(): return self.cv2(torch.cat([x] + [m(x) for m in self.m], 1))
warnings.simplefilter('ignore') # suppress torch 1.9.0 max_pool2d() warning
return self.cv2(torch.cat([x] + [m(x) for m in self.m], 1))
class SPPF(nn.Module): class SPPF(nn.Module):
@ -290,11 +287,9 @@ class SPPF(nn.Module):
def forward(self, x): def forward(self, x):
x = self.cv1(x) x = self.cv1(x)
with warnings.catch_warnings(): y1 = self.m(x)
warnings.simplefilter('ignore') # suppress torch 1.9.0 max_pool2d() warning y2 = self.m(y1)
y1 = self.m(x) return self.cv2(torch.cat((x, y1, y2, self.m(y2)), 1))
y2 = self.m(y1)
return self.cv2(torch.cat((x, y1, y2, self.m(y2)), 1))
class Focus(nn.Module): class Focus(nn.Module):

@ -88,6 +88,11 @@ def get_cfg(cfg: Union[str, Path, Dict, SimpleNamespace] = DEFAULT_CFG, override
check_cfg_mismatch(cfg, overrides) check_cfg_mismatch(cfg, overrides)
cfg = {**cfg, **overrides} # merge cfg and overrides dicts (prefer overrides) cfg = {**cfg, **overrides} # merge cfg and overrides dicts (prefer overrides)
# Type checks
for k in 'project', 'name':
if isinstance(cfg[k], (int, float)):
cfg[k] = str(cfg[k])
# Return instance # Return instance
return IterableSimpleNamespace(**cfg) return IterableSimpleNamespace(**cfg)
@ -211,12 +216,15 @@ def entrypoint(debug=False):
else: else:
raise argument_error(a) raise argument_error(a)
# Defaults
task2model = dict(detect='yolov8n.pt', segment='yolov8n-seg.pt', classify='yolov8n-cls.pt')
task2data = dict(detect='coco128.yaml', segment='coco128-seg.yaml', classify='mnist160')
# Mode # Mode
mode = overrides.pop('mode', None) mode = overrides['mode']
model = overrides.pop('model', None)
if mode is None: if mode is None:
mode = DEFAULT_CFG.mode or 'predict' mode = DEFAULT_CFG.mode or 'predict'
LOGGER.warning(f"WARNING ⚠️ 'mode' is missing. Valid modes are {modes}. Using default 'mode={mode}'.") LOGGER.warning(f"WARNING ⚠️ 'mode=' is missing. Valid modes are {modes}. Using default 'mode={mode}'.")
elif mode not in modes: elif mode not in modes:
if mode != 'checks': if mode != 'checks':
raise ValueError(emojis(f"ERROR ❌ Invalid 'mode={mode}'. Valid modes are {modes}.")) raise ValueError(emojis(f"ERROR ❌ Invalid 'mode={mode}'. Valid modes are {modes}."))
@ -225,27 +233,33 @@ def entrypoint(debug=False):
return return
# Model # Model
model = overrides.pop('model', DEFAULT_CFG.model)
task = overrides.pop('task', None)
if model is None: if model is None:
model = DEFAULT_CFG.model or 'yolov8n.pt' model = task2model.get(task, 'yolov8n.pt')
LOGGER.warning(f"WARNING ⚠️ 'model' is missing. Using default 'model={model}'.") LOGGER.warning(f"WARNING ⚠️ 'model=' is missing. Using default 'model={model}'.")
from ultralytics.yolo.engine.model import YOLO from ultralytics.yolo.engine.model import YOLO
overrides['model'] = model
model = YOLO(model) model = YOLO(model)
task = model.task
# Task # Task
if task and task != model.task:
LOGGER.warning(f"WARNING ⚠️ 'task={task}' conflicts with {model.task} model {overrides['model']}. "
f"Inheriting 'task={model.task}' from {overrides['model']} and ignoring 'task={task}'.")
task = model.task
overrides['task'] = task
if mode == 'predict' and 'source' not in overrides: if mode == 'predict' and 'source' not in overrides:
overrides['source'] = DEFAULT_CFG.source or ROOT / "assets" if (ROOT / "assets").exists() \ overrides['source'] = DEFAULT_CFG.source or ROOT / "assets" if (ROOT / "assets").exists() \
else "https://ultralytics.com/images/bus.jpg" else "https://ultralytics.com/images/bus.jpg"
LOGGER.warning(f"WARNING ⚠️ 'source' is missing. Using default 'source={overrides['source']}'.") LOGGER.warning(f"WARNING ⚠️ 'source=' is missing. Using default 'source={overrides['source']}'.")
elif mode in ('train', 'val'): elif mode in ('train', 'val'):
if 'data' not in overrides: if 'data' not in overrides:
overrides['data'] = DEFAULT_CFG.data or 'mnist160' if task == 'classify' \ overrides['data'] = task2data.get(task, DEFAULT_CFG.data)
else 'coco128-seg.yaml' if task == 'segment' else 'coco128.yaml' LOGGER.warning(f"WARNING ⚠️ 'data=' is missing. Using {model.task} default 'data={overrides['data']}'.")
LOGGER.warning(f"WARNING ⚠️ 'data' is missing. Using default 'data={overrides['data']}'.")
elif mode == 'export': elif mode == 'export':
if 'format' not in overrides: if 'format' not in overrides:
overrides['format'] = DEFAULT_CFG.format or 'torchscript' overrides['format'] = DEFAULT_CFG.format or 'torchscript'
LOGGER.warning(f"WARNING ⚠️ 'format' is missing. Using default 'format={overrides['format']}'.") LOGGER.warning(f"WARNING ⚠️ 'format=' is missing. Using default 'format={overrides['format']}'.")
# Run command in python # Run command in python
getattr(model, mode)(**overrides) getattr(model, mode)(**overrides)

@ -186,6 +186,7 @@ class LoadImages:
self.transforms = transforms # optional self.transforms = transforms # optional
self.vid_stride = vid_stride # video frame-rate stride self.vid_stride = vid_stride # video frame-rate stride
if any(videos): if any(videos):
self.orientation = None # rotation degrees
self._new_video(videos[0]) # new video self._new_video(videos[0]) # new video
else: else:
self.cap = None self.cap = None
@ -243,8 +244,10 @@ class LoadImages:
self.frame = 0 self.frame = 0
self.cap = cv2.VideoCapture(path) self.cap = cv2.VideoCapture(path)
self.frames = int(self.cap.get(cv2.CAP_PROP_FRAME_COUNT) / self.vid_stride) self.frames = int(self.cap.get(cv2.CAP_PROP_FRAME_COUNT) / self.vid_stride)
self.orientation = int(self.cap.get(cv2.CAP_PROP_ORIENTATION_META)) # rotation degrees if hasattr(cv2, 'CAP_PROP_ORIENTATION_META'): # cv2<4.6.0 compatibility
# self.cap.set(cv2.CAP_PROP_ORIENTATION_AUTO, 0) # disable https://github.com/ultralytics/yolov5/issues/8493 self.orientation = int(self.cap.get(cv2.CAP_PROP_ORIENTATION_META)) # rotation degrees
# Disable auto-orientation due to known issues in https://github.com/ultralytics/yolov5/issues/8493
# self.cap.set(cv2.CAP_PROP_ORIENTATION_AUTO, 0)
def _cv2_rotate(self, im): def _cv2_rotate(self, im):
# Rotate a cv2 video manually # Rotate a cv2 video manually

@ -16,7 +16,7 @@ from PIL import ExifTags, Image, ImageOps
from ultralytics.yolo.utils import DATASETS_DIR, LOGGER, ROOT, colorstr, emojis, yaml_load from ultralytics.yolo.utils import DATASETS_DIR, LOGGER, ROOT, colorstr, emojis, yaml_load
from ultralytics.yolo.utils.checks import check_file, check_font, is_ascii from ultralytics.yolo.utils.checks import check_file, check_font, is_ascii
from ultralytics.yolo.utils.downloads import download from ultralytics.yolo.utils.downloads import download, safe_download
from ultralytics.yolo.utils.files import unzip_file from ultralytics.yolo.utils.files import unzip_file
from ultralytics.yolo.utils.ops import segments2boxes from ultralytics.yolo.utils.ops import segments2boxes
@ -238,8 +238,7 @@ def check_det_dataset(dataset, autodownload=True):
t = time.time() t = time.time()
if s.startswith('http') and s.endswith('.zip'): # URL if s.startswith('http') and s.endswith('.zip'): # URL
f = Path(s).name # filename f = Path(s).name # filename
LOGGER.info(f'Downloading {s} to {f}...') safe_download(file=f, url=s)
torch.hub.download_url_to_file(s, f)
Path(DATASETS_DIR).mkdir(parents=True, exist_ok=True) # create root Path(DATASETS_DIR).mkdir(parents=True, exist_ok=True) # create root
unzip_file(f, path=DATASETS_DIR) # unzip unzip_file(f, path=DATASETS_DIR) # unzip
Path(f).unlink() # remove zip Path(f).unlink() # remove zip

@ -233,7 +233,7 @@ class BasePredictor:
device = select_device(self.args.device) device = select_device(self.args.device)
model = model or self.args.model model = model or self.args.model
self.args.half &= device.type != 'cpu' # half precision only supported on CUDA self.args.half &= device.type != 'cpu' # half precision only supported on CUDA
self.model = AutoBackend(model, device=device, dnn=self.args.dnn, fp16=self.args.half) self.model = AutoBackend(model, device=device, dnn=self.args.dnn, data=self.args.data, fp16=self.args.half)
self.device = device self.device = device
self.model.eval() self.model.eval()

@ -6,7 +6,7 @@ try:
import clearml import clearml
from clearml import Task from clearml import Task
assert hasattr(clearml, '__version__') assert clearml.__version__ # verify package is not directory
except (ImportError, AssertionError): except (ImportError, AssertionError):
clearml = None clearml = None

@ -5,7 +5,7 @@ from ultralytics.yolo.utils.torch_utils import get_flops, get_num_params
try: try:
import comet_ml import comet_ml
except (ModuleNotFoundError, ImportError): except ImportError:
comet_ml = None comet_ml = None
@ -35,7 +35,7 @@ def on_fit_epoch_end(trainer):
def on_train_end(trainer): def on_train_end(trainer):
experiment = comet_ml.get_global_experiment() experiment = comet_ml.get_global_experiment()
experiment.log_model("YOLOv8", file_or_folder=trainer.best, file_name="best.pt", overwrite=True) experiment.log_model("YOLOv8", file_or_folder=str(trainer.best), file_name="best.pt", overwrite=True)
callbacks = { callbacks = {

@ -18,8 +18,8 @@ import psutil
import torch import torch
from IPython import display from IPython import display
from ultralytics.yolo.utils import (AUTOINSTALL, FONT, LOGGER, ROOT, USER_CONFIG_DIR, TryExcept, colorstr, emojis, from ultralytics.yolo.utils import (AUTOINSTALL, FONT, LOGGER, ROOT, USER_CONFIG_DIR, TryExcept, colorstr, downloads,
is_colab, is_docker, is_jupyter) emojis, is_colab, is_docker, is_jupyter)
def is_ascii(s) -> bool: def is_ascii(s) -> bool:
@ -123,9 +123,7 @@ def check_font(font: str = FONT, progress: bool = False) -> None:
# Check if font file exists at the source or destination path # Check if font file exists at the source or destination path
if not font.exists() and not file.exists(): if not font.exists() and not file.exists():
# Download font file # Download font file
url = f'https://ultralytics.com/assets/{font.name}' downloads.safe_download(file=file, url=f'https://ultralytics.com/assets/{font.name}', progress=progress)
LOGGER.info(f'Downloading {url} to {file}...')
torch.hub.download_url_to_file(url, str(file), progress=progress)
def check_online() -> bool: def check_online() -> bool:
@ -215,9 +213,7 @@ def check_file(file, suffix=''):
if Path(file).is_file(): if Path(file).is_file():
LOGGER.info(f'Found {url} locally at {file}') # file already exists LOGGER.info(f'Found {url} locally at {file}') # file already exists
else: else:
LOGGER.info(f'Downloading {url} to {file}...') downloads.safe_download(file=file, url=url)
torch.hub.download_url_to_file(url, file)
assert Path(file).exists() and Path(file).stat().st_size > 0, f'File download failed: {url}' # check
return file return file
else: # search else: # search
files = [] files = []

@ -12,16 +12,16 @@ from zipfile import ZipFile
import requests import requests
import torch import torch
from ultralytics.yolo.utils import LOGGER, SETTINGS from ultralytics.yolo.utils import LOGGER
def safe_download(file, url, url2=None, min_bytes=1E0, error_msg=''): def safe_download(file, url, url2=None, min_bytes=1E0, error_msg='', progress=True):
# Attempts to download file from url or url2, checks and removes incomplete downloads < min_bytes # Attempts to download file from url or url2, checks and removes incomplete downloads < min_bytes
file = Path(file) file = Path(file)
assert_msg = f"Downloaded file '{file}' does not exist or size is < min_bytes={min_bytes}" assert_msg = f"Downloaded file '{file}' does not exist or size is < min_bytes={min_bytes}"
try: # url1 try: # url1
LOGGER.info(f'Downloading {url} to {file}...') LOGGER.info(f'Downloading {url} to {file}...')
torch.hub.download_url_to_file(url, str(file), progress=LOGGER.level <= logging.INFO) torch.hub.download_url_to_file(url, str(file), progress=progress and LOGGER.level <= logging.INFO)
assert file.exists() and file.stat().st_size > min_bytes, assert_msg # check assert file.exists() and file.stat().st_size > min_bytes, assert_msg # check
except Exception as e: # url2 except Exception as e: # url2
if file.exists(): if file.exists():
@ -32,7 +32,7 @@ def safe_download(file, url, url2=None, min_bytes=1E0, error_msg=''):
if not file.exists() or file.stat().st_size < min_bytes: # check if not file.exists() or file.stat().st_size < min_bytes: # check
if file.exists(): if file.exists():
file.unlink() # remove partial downloads file.unlink() # remove partial downloads
LOGGER.info(f"ERROR: {assert_msg}\n{error_msg}") LOGGER.warning(f"ERROR: {assert_msg}\n{error_msg}")
LOGGER.info('') LOGGER.info('')
@ -49,6 +49,7 @@ def is_url(url, check=True):
def attempt_download(file, repo='ultralytics/assets', release='v0.0.0'): def attempt_download(file, repo='ultralytics/assets', release='v0.0.0'):
# Attempt file download from GitHub release assets if not found locally. release = 'latest', 'v6.2', etc. # Attempt file download from GitHub release assets if not found locally. release = 'latest', 'v6.2', etc.
from ultralytics.yolo.utils import SETTINGS
def github_assets(repository, version='latest'): def github_assets(repository, version='latest'):
# Return GitHub repo tag and assets (i.e. ['yolov8n.pt', 'yolov5m.pt', ...]) # Return GitHub repo tag and assets (i.e. ['yolov8n.pt', 'yolov5m.pt', ...])
@ -76,7 +77,6 @@ def attempt_download(file, repo='ultralytics/assets', release='v0.0.0'):
return file return file
# GitHub assets # GitHub assets
assets = [f'yolov5{size}{suffix}.pt' for size in 'nsmlx' for suffix in ('', '6', '-cls', '-seg')] # default
assets = [f'yolov8{size}{suffix}.pt' for size in 'nsmlx' for suffix in ('', '6', '-cls', '-seg')] # default assets = [f'yolov8{size}{suffix}.pt' for size in 'nsmlx' for suffix in ('', '6', '-cls', '-seg')] # default
try: try:
tag, assets = github_assets(repo, release) tag, assets = github_assets(repo, release)
@ -110,13 +110,12 @@ def download(url, dir=Path.cwd(), unzip=True, delete=True, curl=False, threads=1
f = dir / Path(url).name f = dir / Path(url).name
LOGGER.info(f'Downloading {url} to {f}...') LOGGER.info(f'Downloading {url} to {f}...')
for i in range(retry + 1): for i in range(retry + 1):
if curl: if curl: # curl download with retry, continue
s = 'sS' if threads > 1 else '' # silent s = 'sS' * (threads > 1) # silent
r = os.system( r = os.system(f'curl -# -{s}L "{url}" -o "{f}" --retry 9 -C -')
f'curl -# -{s}L "{url}" -o "{f}" --retry 9 -C -') # curl download with retry, continue
success = r == 0 success = r == 0
else: else: # torch download
torch.hub.download_url_to_file(url, f, progress=threads == 1) # torch download torch.hub.download_url_to_file(url, f, progress=threads == 1)
success = f.is_file() success = f.is_file()
if success: if success:
break break

@ -67,9 +67,19 @@ def select_device(device='', batch=0, newline=False):
if cpu or mps: if cpu or mps:
os.environ['CUDA_VISIBLE_DEVICES'] = '-1' # force torch.cuda.is_available() = False os.environ['CUDA_VISIBLE_DEVICES'] = '-1' # force torch.cuda.is_available() = False
elif device: # non-cpu device requested elif device: # non-cpu device requested
visible = os.environ.get('CUDA_VISIBLE_DEVICES', None)
os.environ['CUDA_VISIBLE_DEVICES'] = device # set environment variable - must be before assert is_available() os.environ['CUDA_VISIBLE_DEVICES'] = device # set environment variable - must be before assert is_available()
if not (torch.cuda.is_available() and torch.cuda.device_count() >= len(device.replace(',', ''))): if not (torch.cuda.is_available() and torch.cuda.device_count() >= len(device.replace(',', ''))):
raise ValueError(f"Invalid CUDA 'device={device}' requested, use 'device=cpu' or pass valid CUDA device(s)") LOGGER.info(s)
install = "See https://pytorch.org/get-started/locally/ for up-to-date torch install instructions if no " \
"CUDA devices are seen by torch.\n" if torch.cuda.device_count() == 0 else ""
raise ValueError(f"Invalid CUDA 'device={device}' requested."
f" Use 'device=cpu' or pass valid CUDA device(s) if available,"
f" i.e. 'device=0' or 'device=0,1,2,3' for Multi-GPU.\n"
f"\ntorch.cuda.is_available(): {torch.cuda.is_available()}"
f"\ntorch.cuda.device_count(): {torch.cuda.device_count()}"
f"\nos.environ['CUDA_VISIBLE_DEVICES']: {visible}\n"
f"{install}")
if not cpu and not mps and torch.cuda.is_available(): # prefer GPU if available if not cpu and not mps and torch.cuda.is_available(): # prefer GPU if available
devices = device.split(',') if device else '0' # range(torch.cuda.device_count()) # i.e. 0,1,6,7 devices = device.split(',') if device else '0' # range(torch.cuda.device_count()) # i.e. 0,1,6,7

@ -69,7 +69,7 @@ def predict(cfg=DEFAULT_CFG, use_python=False):
source = cfg.source if cfg.source is not None else ROOT / "assets" if (ROOT / "assets").exists() \ source = cfg.source if cfg.source is not None else ROOT / "assets" if (ROOT / "assets").exists() \
else "https://ultralytics.com/images/bus.jpg" else "https://ultralytics.com/images/bus.jpg"
args = dict(model=model, source=source, verbose=True) args = dict(model=model, source=source)
if use_python: if use_python:
from ultralytics import YOLO from ultralytics import YOLO
YOLO(model)(**args) YOLO(model)(**args)

@ -141,7 +141,7 @@ def train(cfg=DEFAULT_CFG, use_python=False):
data = cfg.data or "mnist160" # or yolo.ClassificationDataset("mnist") data = cfg.data or "mnist160" # or yolo.ClassificationDataset("mnist")
device = cfg.device if cfg.device is not None else '' device = cfg.device if cfg.device is not None else ''
args = dict(model=model, data=data, device=device, verbose=True) args = dict(model=model, data=data, device=device)
if use_python: if use_python:
from ultralytics import YOLO from ultralytics import YOLO
YOLO(model).train(**args) YOLO(model).train(**args)

@ -50,7 +50,7 @@ def val(cfg=DEFAULT_CFG, use_python=False):
model = cfg.model or "yolov8n-cls.pt" # or "resnet18" model = cfg.model or "yolov8n-cls.pt" # or "resnet18"
data = cfg.data or "mnist160" data = cfg.data or "mnist160"
args = dict(model=model, data=data, verbose=True) args = dict(model=model, data=data)
if use_python: if use_python:
from ultralytics import YOLO from ultralytics import YOLO
YOLO(model).val(**args) YOLO(model).val(**args)

@ -87,7 +87,7 @@ def predict(cfg=DEFAULT_CFG, use_python=False):
source = cfg.source if cfg.source is not None else ROOT / "assets" if (ROOT / "assets").exists() \ source = cfg.source if cfg.source is not None else ROOT / "assets" if (ROOT / "assets").exists() \
else "https://ultralytics.com/images/bus.jpg" else "https://ultralytics.com/images/bus.jpg"
args = dict(model=model, source=source, verbose=True) args = dict(model=model, source=source)
if use_python: if use_python:
from ultralytics import YOLO from ultralytics import YOLO
YOLO(model)(**args) YOLO(model)(**args)

@ -199,7 +199,7 @@ def train(cfg=DEFAULT_CFG, use_python=False):
data = cfg.data or "coco128.yaml" # or yolo.ClassificationDataset("mnist") data = cfg.data or "coco128.yaml" # or yolo.ClassificationDataset("mnist")
device = cfg.device if cfg.device is not None else '' device = cfg.device if cfg.device is not None else ''
args = dict(model=model, data=data, device=device, verbose=True) args = dict(model=model, data=data, device=device)
if use_python: if use_python:
from ultralytics import YOLO from ultralytics import YOLO
YOLO(model).train(**args) YOLO(model).train(**args)

@ -129,7 +129,7 @@ class DetectionValidator(BaseValidator):
f'WARNING ⚠️ no labels found in {self.args.task} set, can not compute metrics without labels') f'WARNING ⚠️ no labels found in {self.args.task} set, can not compute metrics without labels')
# Print results per class # Print results per class
if (self.args.verbose or not self.training) and self.nc > 1 and len(self.stats): if self.args.verbose and not self.training and self.nc > 1 and len(self.stats):
for i, c in enumerate(self.metrics.ap_class_index): for i, c in enumerate(self.metrics.ap_class_index):
self.logger.info(pf % (self.names[c], self.seen, self.nt_per_class[c], *self.metrics.class_result(i))) self.logger.info(pf % (self.names[c], self.seen, self.nt_per_class[c], *self.metrics.class_result(i)))
@ -237,7 +237,7 @@ def val(cfg=DEFAULT_CFG, use_python=False):
model = cfg.model or "yolov8n.pt" model = cfg.model or "yolov8n.pt"
data = cfg.data or "coco128.yaml" data = cfg.data or "coco128.yaml"
args = dict(model=model, data=data, verbose=True) args = dict(model=model, data=data)
if use_python: if use_python:
from ultralytics import YOLO from ultralytics import YOLO
YOLO(model).val(**args) YOLO(model).val(**args)

@ -105,7 +105,7 @@ def predict(cfg=DEFAULT_CFG, use_python=False):
source = cfg.source if cfg.source is not None else ROOT / "assets" if (ROOT / "assets").exists() \ source = cfg.source if cfg.source is not None else ROOT / "assets" if (ROOT / "assets").exists() \
else "https://ultralytics.com/images/bus.jpg" else "https://ultralytics.com/images/bus.jpg"
args = dict(model=model, source=source, verbose=True) args = dict(model=model, source=source)
if use_python: if use_python:
from ultralytics import YOLO from ultralytics import YOLO
YOLO(model)(**args) YOLO(model)(**args)

@ -145,7 +145,7 @@ def train(cfg=DEFAULT_CFG, use_python=False):
data = cfg.data or "coco128-seg.yaml" # or yolo.ClassificationDataset("mnist") data = cfg.data or "coco128-seg.yaml" # or yolo.ClassificationDataset("mnist")
device = cfg.device if cfg.device is not None else '' device = cfg.device if cfg.device is not None else ''
args = dict(model=model, data=data, device=device, verbose=True) args = dict(model=model, data=data, device=device)
if use_python: if use_python:
from ultralytics import YOLO from ultralytics import YOLO
YOLO(model).train(**args) YOLO(model).train(**args)

@ -247,7 +247,7 @@ def val(cfg=DEFAULT_CFG, use_python=False):
model = cfg.model or "yolov8n-seg.pt" model = cfg.model or "yolov8n-seg.pt"
data = cfg.data or "coco128-seg.yaml" data = cfg.data or "coco128-seg.yaml"
args = dict(model=model, data=data, verbose=True) args = dict(model=model, data=data)
if use_python: if use_python:
from ultralytics import YOLO from ultralytics import YOLO
YOLO(model).val(**args) YOLO(model).val(**args)

Loading…
Cancel
Save