`ultralytics 8.0.20` CLI `yolo` simplifications, DDP and ONNX fixes (#608)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Sid Prabhakaran <s2siddhu@gmail.com>
single_channel
Glenn Jocher 2 years ago committed by GitHub
parent 59d4335664
commit 15b3b0365a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

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

@ -1,14 +1,19 @@
# Ultralytics YOLO 🚀, GPL-3.0 license
import os
import platform
import shutil
import sys
import threading
import time
from pathlib import Path
from random import random
import requests
from ultralytics.yolo.utils import DEFAULT_CFG_DICT, LOGGER, RANK, SETTINGS, TryExcept, colorstr, emojis
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)
PREFIX = colorstr('Ultralytics: ')
HELP_MSG = 'If this issue persists please visit https://github.com/ultralytics/hub/issues for assistance.'
@ -131,21 +136,57 @@ def smart_request(*args, retry=3, timeout=30, thread=True, code=-1, method="post
return func(*args, **kwargs)
@TryExcept(verbose=False)
def traces(cfg, all_keys=False, traces_sample_rate=0.0):
"""
Sync traces data if enabled in the global settings
Args:
cfg (IterableSimpleNamespace): Configuration for the task and mode.
all_keys (bool): Sync all items, not just non-default values.
traces_sample_rate (float): Fraction of traces captured from 0.0 to 1.0
"""
if SETTINGS['sync'] and RANK in {-1, 0} and (random() < traces_sample_rate):
cfg = vars(cfg) # convert type from IterableSimpleNamespace to dict
if not all_keys:
cfg = {k: v for k, v in cfg.items() if v != DEFAULT_CFG_DICT.get(k, None)} # retain non-default values
cfg['uuid'] = SETTINGS['uuid'] # add the device UUID to the configuration data
# Send a request to the HUB API to sync analytics
smart_request(f'{HUB_API_ROOT}/v1/usage/anonymous', json=cfg, headers=None, code=3, retry=0, verbose=False)
class Traces:
def __init__(self):
"""
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 = time.time() # rate limit timer (seconds)
self.metadata = {
"sys_argv_name": Path(sys.argv[0]).name,
"install": 'git' if is_git_dir() else 'pip' if is_pip_package() else 'other',
"python": platform.python_version(),
"release": __version__,
"environment": env}
self.enabled = SETTINGS['sync'] and \
RANK in {-1, 0} 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")
@TryExcept(verbose=False)
def __call__(self, cfg, all_keys=False, traces_sample_rate=1.0):
"""
Sync traces data if enabled in the global settings
Args:
cfg (IterableSimpleNamespace): Configuration for the task and mode.
all_keys (bool): Sync all items, not just non-default values.
traces_sample_rate (float): Fraction of traces captured from 0.0 to 1.0
"""
t = time.time() # current time
if self.enabled and random() < traces_sample_rate and (t - self.t) > self.rate_limit:
self.t = t # reset rate limit timer
cfg = vars(cfg) # convert type from IterableSimpleNamespace to dict
if not all_keys: # filter cfg
include_keys = {'task', 'mode'} # always include
cfg = {k: v for k, v in cfg.items() if v != DEFAULT_CFG_DICT.get(k, None) or k in include_keys}
trace = {'uuid': SETTINGS['uuid'], 'cfg': cfg, 'metadata': self.metadata}
# Send a request to the HUB API to sync analytics
smart_request(f'{HUB_API_ROOT}/v1/usage/anonymous',
json=trace,
headers=None,
code=3,
retry=0,
verbose=False)
# Run below code on hub/utils init -------------------------------------------------------------------------------------
traces = Traces()

@ -472,10 +472,13 @@ def guess_model_task(model):
Raises:
SyntaxError: If the task of the model could not be determined.
"""
cfg, task = None, None
cfg = None
if isinstance(model, dict):
cfg = model
elif isinstance(model, nn.Module): # PyTorch model
for x in 'model.args', 'model.model.args', 'model.model.model.args':
with contextlib.suppress(Exception):
return eval(x)['task']
for x in 'model.yaml', 'model.model.yaml', 'model.model.model.yaml':
with contextlib.suppress(Exception):
cfg = eval(x)
@ -485,25 +488,22 @@ def guess_model_task(model):
if cfg:
m = cfg["head"][-1][-2].lower() # output module name
if m in ["classify", "classifier", "cls", "fc"]:
task = "classify"
return "classify"
if m in ["detect"]:
task = "detect"
return "detect"
if m in ["segment"]:
task = "segment"
return "segment"
# Guess from PyTorch model
if task is None and isinstance(model, nn.Module):
if isinstance(model, nn.Module):
for m in model.modules():
if isinstance(m, Detect):
task = "detect"
return "detect"
elif isinstance(m, Segment):
task = "segment"
return "segment"
elif isinstance(m, Classify):
task = "classify"
return "classify"
# Unable to determine task from model
if task is None:
raise SyntaxError("YOLO is unable to automatically guess model task. Explicitly define task for your model, "
"i.e. 'task=detect', 'task=segment' or 'task=classify'.")
else:
return task
raise SyntaxError("YOLO is unable to automatically guess model task. Explicitly define task for your model, "
"i.e. 'task=detect', 'task=segment' or 'task=classify'.")

@ -8,8 +8,8 @@ from pathlib import Path
from types import SimpleNamespace
from typing import Dict, List, Union
from ultralytics import __version__, yolo
from ultralytics.yolo.utils import (DEFAULT_CFG_DICT, DEFAULT_CFG_PATH, LOGGER, PREFIX, USER_CONFIG_DIR,
from ultralytics import __version__
from ultralytics.yolo.utils import (DEFAULT_CFG_DICT, DEFAULT_CFG_PATH, LOGGER, PREFIX, ROOT, USER_CONFIG_DIR,
IterableSimpleNamespace, colorstr, yaml_load, yaml_print)
from ultralytics.yolo.utils.checks import check_yolo
@ -211,30 +211,42 @@ def entrypoint(debug=False):
else:
raise argument_error(a)
cfg = get_cfg(DEFAULT_CFG_DICT, overrides) # create CFG instance
# Checks error catch
if cfg.mode == 'checks':
LOGGER.warning(
"WARNING ⚠️ 'yolo mode=checks' is deprecated and will be removed in the future. Use 'yolo checks' instead.")
# Mode
mode = overrides.pop('mode', None)
model = overrides.pop('model', None)
if mode == 'checks':
LOGGER.warning("WARNING ⚠️ 'yolo mode=checks' is deprecated. Use 'yolo checks' instead.")
check_yolo()
return
# Mapping from task to module
module = {"detect": yolo.v8.detect, "segment": yolo.v8.segment, "classify": yolo.v8.classify}.get(cfg.task)
if not module:
raise SyntaxError(f"yolo task={cfg.task} is invalid. Valid tasks are: {', '.join(tasks)}\n{CLI_HELP_MSG}")
# Mapping from mode to function
func = {
"train": module.train,
"val": module.val,
"predict": module.predict,
"export": yolo.engine.exporter.export}.get(cfg.mode)
if not func:
raise SyntaxError(f"yolo mode={cfg.mode} is invalid. Valid modes are: {', '.join(modes)}\n{CLI_HELP_MSG}")
func(cfg)
elif mode is None:
mode = DEFAULT_CFG_DICT['mode'] or 'predict'
LOGGER.warning(f"WARNING ⚠️ 'mode' is missing. Valid modes are {modes}. Using default 'mode={mode}'.")
# Model
if model is None:
model = DEFAULT_CFG_DICT['model'] or 'yolov8n.pt'
LOGGER.warning(f"WARNING ⚠️ 'model' is missing. Using default 'model={model}'.")
from ultralytics.yolo.engine.model import YOLO
model = YOLO(model)
task = model.task
# Task
if mode == 'predict' and 'source' not in overrides:
overrides['source'] = DEFAULT_CFG_DICT['source'] or ROOT / "assets" if (ROOT / "assets").exists() \
else "https://ultralytics.com/images/bus.jpg"
LOGGER.warning(f"WARNING ⚠️ 'source' is missing. Using default 'source={overrides['source']}'.")
elif mode in ('train', 'val'):
if 'data' not in overrides:
overrides['data'] = DEFAULT_CFG_DICT['data'] or 'mnist160' if task == 'classify' \
else 'coco128-seg.yaml' if task == 'segment' else 'coco128.yaml'
LOGGER.warning(f"WARNING ⚠️ 'data' is missing. Using default 'data={overrides['data']}'.")
elif mode == 'export':
if 'format' not in overrides:
overrides['format'] = DEFAULT_CFG_DICT['format'] or 'torchscript'
LOGGER.warning(f"WARNING ⚠️ 'format' is missing. Using default 'format={overrides['format']}'.")
# Run command in python
getattr(model, mode)(verbose=True, **overrides)
# Special modes --------------------------------------------------------------------------------------------------------

@ -1,26 +1,26 @@
# Ultralytics YOLO 🚀, GPL-3.0 license
# Default training settings and hyperparameters for medium-augmentation COCO training
task: "detect" # inference task, i.e. detect, segment, classify
mode: "train" # YOLO mode, i.e. train, val, predict, export
task: detect # inference task, i.e. detect, segment, classify
mode: train # YOLO mode, i.e. train, val, predict, export
# Train settings -------------------------------------------------------------------------------------------------------
model: null # path to model file, i.e. yolov8n.pt, yolov8n.yaml
data: null # path to data file, i.e. i.e. coco128.yaml
model: # path to model file, i.e. yolov8n.pt, yolov8n.yaml
data: # path to data file, i.e. i.e. coco128.yaml
epochs: 100 # number of epochs to train for
patience: 50 # epochs to wait for no observable improvement for early stopping of training
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
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
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)
project: null # project name
name: null # experiment name
project: # project name
name: # experiment name
exist_ok: False # whether to overwrite existing experiment
pretrained: False # whether to use a pretrained model
optimizer: 'SGD' # optimizer to use, choices=['SGD', 'Adam', 'AdamW', 'RMSProp']
verbose: False # whether to print verbose output
optimizer: SGD # optimizer to use, choices=['SGD', 'Adam', 'AdamW', 'RMSProp']
verbose: True # whether to print verbose output
seed: 0 # random seed for reproducibility
deterministic: True # whether to enable deterministic mode
single_cls: False # train multi-class data as single-class
@ -39,7 +39,7 @@ dropout: 0.0 # use dropout regularization (classify train only)
val: True # validate/test during training
save_json: False # save results to JSON file
save_hybrid: False # save hybrid version of labels (labels + additional predictions)
conf: null # object confidence threshold for detection (default 0.25 predict, 0.001 val)
conf: # object confidence threshold for detection (default 0.25 predict, 0.001 val)
iou: 0.7 # intersection over union (IoU) threshold for NMS
max_det: 300 # maximum number of detections per image
half: False # use half precision (FP16)
@ -47,7 +47,7 @@ dnn: False # use OpenCV DNN for ONNX inference
plots: True # save plots during train/val
# Prediction settings --------------------------------------------------------------------------------------------------
source: null # source directory for images or videos
source: # source directory for images or videos
show: False # show results if possible
save_txt: False # save results as .txt file
save_conf: False # save results with confidence scores
@ -59,7 +59,7 @@ line_thickness: 3 # bounding box thickness (pixels)
visualize: False # visualize model features
augment: False # apply image augmentation to prediction sources
agnostic_nms: False # class-agnostic NMS
classes: null # filter results by class, i.e. class=0, or class=[0,2,3]
classes: # filter results by class, i.e. class=0, or class=[0,2,3]
retina_masks: False # use high-resolution segmentation masks
boxes: True # Show boxes in segmentation predictions
@ -70,7 +70,7 @@ optimize: False # TorchScript: optimize for mobile
int8: False # CoreML/TF INT8 quantization
dynamic: False # ONNX/TF/TensorRT: dynamic axes
simplify: False # ONNX: simplify model
opset: 17 # ONNX: opset version
opset: # ONNX: opset version (optional)
workspace: 4 # TensorRT: workspace size (GB)
nms: False # CoreML: add NMS
@ -103,7 +103,7 @@ mixup: 0.0 # image mixup (probability)
copy_paste: 0.0 # segment copy-paste (probability)
# Custom config.yaml ---------------------------------------------------------------------------------------------------
cfg: null # for overriding defaults.yaml
cfg: # for overriding defaults.yaml
# Debug, do not modify -------------------------------------------------------------------------------------------------
v5loader: False # use legacy YOLOv5 dataloader

@ -116,6 +116,9 @@ class IterableSimpleNamespace(SimpleNamespace):
# Default configuration
with open(DEFAULT_CFG_PATH, errors='ignore') as f:
DEFAULT_CFG_DICT = yaml.safe_load(f)
for k, v in DEFAULT_CFG_DICT.items():
if isinstance(v, str) and v.lower() == 'none':
DEFAULT_CFG_DICT[k] = None
DEFAULT_CFG_KEYS = DEFAULT_CFG_DICT.keys()
DEFAULT_CFG = IterableSimpleNamespace(**DEFAULT_CFG_DICT)
@ -448,13 +451,13 @@ def set_sentry():
"""
def before_send(event, hint):
oss = 'colab' if is_colab() else 'kaggle' if is_kaggle() else 'jupyter' if is_jupyter() else \
'docker' if is_docker() else platform.system()
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": oss}
"os": env}
return event
if SETTINGS['sync'] and \
@ -529,7 +532,7 @@ def set_settings(kwargs, file=USER_CONFIG_DIR / 'settings.yaml'):
yaml_save(file, SETTINGS)
# Run below code on utils init -----------------------------------------------------------------------------------------
# Run below code on yolo/utils init ------------------------------------------------------------------------------------
# Set logger
set_logging(LOGGING_NAME) # run before defining LOGGER

@ -48,19 +48,19 @@ def on_train_end(trainer):
def on_train_start(trainer):
traces(trainer.args, traces_sample_rate=0.0)
traces(trainer.args, traces_sample_rate=1.0)
def on_val_start(validator):
traces(validator.args, traces_sample_rate=0.0)
traces(validator.args, traces_sample_rate=1.0)
def on_predict_start(predictor):
traces(predictor.args, traces_sample_rate=0.0)
traces(predictor.args, traces_sample_rate=1.0)
def on_export_start(exporter):
traces(exporter.args, traces_sample_rate=0.0)
traces(exporter.args, traces_sample_rate=1.0)
callbacks = {

@ -31,7 +31,7 @@ WORLD_SIZE = int(os.getenv('WORLD_SIZE', 1))
@contextmanager
def torch_distributed_zero_first(local_rank: int):
# Decorator to make all processes in distributed training wait for each local_master to do something
initialized = torch.distributed.is_initialized() # prevent 'Default process group has not been initialized' errors
initialized = torch.distributed.is_available() and torch.distributed.is_initialized()
if initialized and local_rank not in {-1, 0}:
dist.barrier(device_ids=[local_rank])
yield

@ -1,4 +1,5 @@
# Ultralytics YOLO 🚀, GPL-3.0 license
import sys
import torch
@ -63,12 +64,18 @@ class ClassificationPredictor(BasePredictor):
return log_string
def predict(cfg=DEFAULT_CFG):
cfg.model = cfg.model or "yolov8n-cls.pt" # or "resnet18"
cfg.source = cfg.source if cfg.source is not None else ROOT / "assets" if (ROOT / "assets").exists() \
def predict(cfg=DEFAULT_CFG, use_python=False):
model = cfg.model or "yolov8n-cls.pt" # or "resnet18"
source = cfg.source if cfg.source is not None else ROOT / "assets" if (ROOT / "assets").exists() \
else "https://ultralytics.com/images/bus.jpg"
predictor = ClassificationPredictor(cfg)
predictor.predict_cli()
args = dict(model=model, source=source, verbose=True)
if use_python:
from ultralytics import YOLO
YOLO(model)(**args)
else:
predictor = ClassificationPredictor(args)
predictor.predict_cli()
if __name__ == "__main__":

@ -1,4 +1,5 @@
# Ultralytics YOLO 🚀, GPL-3.0 license
import sys
import torch
import torchvision
@ -135,22 +136,18 @@ class ClassificationTrainer(BaseTrainer):
# self.run_callbacks('on_fit_epoch_end')
def train(cfg=DEFAULT_CFG):
cfg.model = cfg.model or "yolov8n-cls.pt" # or "resnet18"
cfg.data = cfg.data or "mnist160" # or yolo.ClassificationDataset("mnist")
def train(cfg=DEFAULT_CFG, use_python=False):
model = cfg.model or "yolov8n-cls.pt" # or "resnet18"
data = cfg.data or "mnist160" # or yolo.ClassificationDataset("mnist")
device = cfg.device if cfg.device is not None else ''
# Reproduce ImageNet results
# cfg.lr0 = 0.1
# cfg.weight_decay = 5e-5
# cfg.label_smoothing = 0.1
# cfg.warmup_epochs = 0.0
cfg.device = cfg.device if cfg.device is not None else ''
# trainer = ClassificationTrainer(cfg)
# trainer.train()
from ultralytics import YOLO
model = YOLO(cfg.model)
model.train(**vars(cfg))
args = dict(model=model, data=data, device=device, verbose=True)
if use_python:
from ultralytics import YOLO
YOLO(model).train(**args)
else:
trainer = ClassificationTrainer(args)
trainer.train()
if __name__ == "__main__":

@ -1,4 +1,5 @@
# Ultralytics YOLO 🚀, GPL-3.0 license
import sys
from ultralytics.yolo.data import build_classification_dataloader
from ultralytics.yolo.engine.validator import BaseValidator
@ -45,11 +46,17 @@ class ClassificationValidator(BaseValidator):
self.logger.info(pf % ("all", self.metrics.top1, self.metrics.top5))
def val(cfg=DEFAULT_CFG):
cfg.model = cfg.model or "yolov8n-cls.pt" # or "resnet18"
cfg.data = cfg.data or "mnist160"
validator = ClassificationValidator(args=cfg)
validator(model=cfg.model)
def val(cfg=DEFAULT_CFG, use_python=False):
model = cfg.model or "yolov8n-cls.pt" # or "resnet18"
data = cfg.data or "mnist160"
args = dict(model=model, data=data, verbose=True)
if use_python:
from ultralytics import YOLO
YOLO(model).val(**args)
else:
validator = ClassificationValidator(args=args)
validator(model=args['model'])
if __name__ == "__main__":

@ -1,4 +1,5 @@
# Ultralytics YOLO 🚀, GPL-3.0 license
import sys
import torch
@ -81,12 +82,18 @@ class DetectionPredictor(BasePredictor):
return log_string
def predict(cfg=DEFAULT_CFG):
cfg.model = cfg.model or "yolov8n.pt"
cfg.source = cfg.source if cfg.source is not None else ROOT / "assets" if (ROOT / "assets").exists() \
def predict(cfg=DEFAULT_CFG, use_python=False):
model = cfg.model or "yolov8n.pt"
source = cfg.source if cfg.source is not None else ROOT / "assets" if (ROOT / "assets").exists() \
else "https://ultralytics.com/images/bus.jpg"
predictor = DetectionPredictor(cfg)
predictor.predict_cli()
args = dict(model=model, source=source, verbose=True)
if use_python:
from ultralytics import YOLO
YOLO(model)(**args)
else:
predictor = DetectionPredictor(args)
predictor.predict_cli()
if __name__ == "__main__":

@ -1,5 +1,5 @@
# Ultralytics YOLO 🚀, GPL-3.0 license
import sys
from copy import copy
import torch
@ -194,15 +194,18 @@ class Loss:
return loss.sum() * batch_size, loss.detach() # loss(box, cls, dfl)
def train(cfg=DEFAULT_CFG):
cfg.model = cfg.model or "yolov8n.pt"
cfg.data = cfg.data or "coco128.yaml" # or yolo.ClassificationDataset("mnist")
cfg.device = cfg.device if cfg.device is not None else ''
# trainer = DetectionTrainer(cfg)
# trainer.train()
from ultralytics import YOLO
model = YOLO(cfg.model)
model.train(**vars(cfg))
def train(cfg=DEFAULT_CFG, use_python=False):
model = cfg.model or "yolov8n.pt"
data = cfg.data or "coco128.yaml" # or yolo.ClassificationDataset("mnist")
device = cfg.device if cfg.device is not None else ''
args = dict(model=model, data=data, device=device, verbose=True)
if use_python:
from ultralytics import YOLO
YOLO(model).train(**args)
else:
trainer = DetectionTrainer(args)
trainer.train()
if __name__ == "__main__":

@ -1,6 +1,7 @@
# Ultralytics YOLO 🚀, GPL-3.0 license
import os
import sys
from pathlib import Path
import numpy as np
@ -232,11 +233,17 @@ class DetectionValidator(BaseValidator):
return stats
def val(cfg=DEFAULT_CFG):
cfg.model = cfg.model or "yolov8n.pt"
cfg.data = cfg.data or "coco128.yaml"
validator = DetectionValidator(args=cfg)
validator(model=cfg.model)
def val(cfg=DEFAULT_CFG, use_python=False):
model = cfg.model or "yolov8n.pt"
data = cfg.data or "coco128.yaml"
args = dict(model=model, data=data, verbose=True)
if use_python:
from ultralytics import YOLO
YOLO(model).val(**args)
else:
validator = DetectionValidator(args=args)
validator(model=args['model'])
if __name__ == "__main__":

@ -1,5 +1,7 @@
# Ultralytics YOLO 🚀, GPL-3.0 license
import sys
import torch
from ultralytics.yolo.engine.results import Results
@ -98,12 +100,18 @@ class SegmentationPredictor(DetectionPredictor):
return log_string
def predict(cfg=DEFAULT_CFG):
cfg.model = cfg.model or "yolov8n-seg.pt"
cfg.source = cfg.source if cfg.source is not None else ROOT / "assets" if (ROOT / "assets").exists() \
def predict(cfg=DEFAULT_CFG, use_python=False):
model = cfg.model or "yolov8n-seg.pt"
source = cfg.source if cfg.source is not None else ROOT / "assets" if (ROOT / "assets").exists() \
else "https://ultralytics.com/images/bus.jpg"
predictor = SegmentationPredictor(cfg)
predictor.predict_cli()
args = dict(model=model, source=source, verbose=True)
if use_python:
from ultralytics import YOLO
YOLO(model)(**args)
else:
predictor = SegmentationPredictor(args)
predictor.predict_cli()
if __name__ == "__main__":

@ -1,5 +1,5 @@
# Ultralytics YOLO 🚀, GPL-3.0 license
import sys
from copy import copy
import torch
@ -140,15 +140,18 @@ class SegLoss(Loss):
return (crop_mask(loss, xyxy).mean(dim=(1, 2)) / area).mean()
def train(cfg=DEFAULT_CFG):
cfg.model = cfg.model or "yolov8n-seg.pt"
cfg.data = cfg.data or "coco128-seg.yaml" # or yolo.ClassificationDataset("mnist")
cfg.device = cfg.device if cfg.device is not None else ''
# trainer = SegmentationTrainer(cfg)
# trainer.train()
from ultralytics import YOLO
model = YOLO(cfg.model)
model.train(**vars(cfg))
def train(cfg=DEFAULT_CFG, use_python=False):
model = cfg.model or "yolov8n-seg.pt"
data = cfg.data or "coco128-seg.yaml" # or yolo.ClassificationDataset("mnist")
device = cfg.device if cfg.device is not None else ''
args = dict(model=model, data=data, device=device, verbose=True)
if use_python:
from ultralytics import YOLO
YOLO(model).train(**args)
else:
trainer = SegmentationTrainer(args)
trainer.train()
if __name__ == "__main__":

@ -1,6 +1,7 @@
# Ultralytics YOLO 🚀, GPL-3.0 license
import os
import sys
from multiprocessing.pool import ThreadPool
from pathlib import Path
@ -242,10 +243,17 @@ class SegmentationValidator(DetectionValidator):
return stats
def val(cfg=DEFAULT_CFG):
cfg.data = cfg.data or "coco128-seg.yaml"
validator = SegmentationValidator(args=cfg)
validator(model=cfg.model)
def val(cfg=DEFAULT_CFG, use_python=False):
model = cfg.model or "yolov8n-seg.pt"
data = cfg.data or "coco128-seg.yaml"
args = dict(model=model, data=data, verbose=True)
if use_python:
from ultralytics import YOLO
YOLO(model).val(**args)
else:
validator = SegmentationValidator(args=args)
validator(model=args['model'])
if __name__ == "__main__":

Loading…
Cancel
Save