ultralytics 8.0.18
new python callbacks and minor fixes (#580)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Jeroen Rombouts <36196499+jarombouts@users.noreply.github.com> Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com>
This commit is contained in:
@ -68,7 +68,7 @@ HELP_MSG = \
|
||||
yolo detect train data=coco128.yaml model=yolov8n.pt epochs=10 lr0=0.01
|
||||
|
||||
- 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 segment predict model=yolov8n-seg.pt source='https://youtu.be/Zgi9g1ksQHc' imgsz=320
|
||||
|
||||
- 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
|
||||
@ -109,6 +109,9 @@ class IterableSimpleNamespace(SimpleNamespace):
|
||||
def __str__(self):
|
||||
return '\n'.join(f"{k}={v}" for k, v in vars(self).items())
|
||||
|
||||
def get(self, key, default=None):
|
||||
return getattr(self, key, default)
|
||||
|
||||
|
||||
# Default configuration
|
||||
with open(DEFAULT_CFG_PATH, errors='ignore') as f:
|
||||
|
@ -106,36 +106,36 @@ def on_export_end(exporter):
|
||||
|
||||
default_callbacks = {
|
||||
# Run in trainer
|
||||
'on_pretrain_routine_start': on_pretrain_routine_start,
|
||||
'on_pretrain_routine_end': on_pretrain_routine_end,
|
||||
'on_train_start': on_train_start,
|
||||
'on_train_epoch_start': on_train_epoch_start,
|
||||
'on_train_batch_start': on_train_batch_start,
|
||||
'optimizer_step': optimizer_step,
|
||||
'on_before_zero_grad': on_before_zero_grad,
|
||||
'on_train_batch_end': on_train_batch_end,
|
||||
'on_train_epoch_end': on_train_epoch_end,
|
||||
'on_fit_epoch_end': on_fit_epoch_end, # fit = train + val
|
||||
'on_model_save': on_model_save,
|
||||
'on_train_end': on_train_end,
|
||||
'on_params_update': on_params_update,
|
||||
'teardown': teardown,
|
||||
'on_pretrain_routine_start': [on_pretrain_routine_start],
|
||||
'on_pretrain_routine_end': [on_pretrain_routine_end],
|
||||
'on_train_start': [on_train_start],
|
||||
'on_train_epoch_start': [on_train_epoch_start],
|
||||
'on_train_batch_start': [on_train_batch_start],
|
||||
'optimizer_step': [optimizer_step],
|
||||
'on_before_zero_grad': [on_before_zero_grad],
|
||||
'on_train_batch_end': [on_train_batch_end],
|
||||
'on_train_epoch_end': [on_train_epoch_end],
|
||||
'on_fit_epoch_end': [on_fit_epoch_end], # fit = train + val
|
||||
'on_model_save': [on_model_save],
|
||||
'on_train_end': [on_train_end],
|
||||
'on_params_update': [on_params_update],
|
||||
'teardown': [teardown],
|
||||
|
||||
# Run in validator
|
||||
'on_val_start': on_val_start,
|
||||
'on_val_batch_start': on_val_batch_start,
|
||||
'on_val_batch_end': on_val_batch_end,
|
||||
'on_val_end': on_val_end,
|
||||
'on_val_start': [on_val_start],
|
||||
'on_val_batch_start': [on_val_batch_start],
|
||||
'on_val_batch_end': [on_val_batch_end],
|
||||
'on_val_end': [on_val_end],
|
||||
|
||||
# Run in predictor
|
||||
'on_predict_start': on_predict_start,
|
||||
'on_predict_batch_start': on_predict_batch_start,
|
||||
'on_predict_batch_end': on_predict_batch_end,
|
||||
'on_predict_end': on_predict_end,
|
||||
'on_predict_start': [on_predict_start],
|
||||
'on_predict_batch_start': [on_predict_batch_start],
|
||||
'on_predict_batch_end': [on_predict_batch_end],
|
||||
'on_predict_end': [on_predict_end],
|
||||
|
||||
# Run in exporter
|
||||
'on_export_start': on_export_start,
|
||||
'on_export_end': on_export_end}
|
||||
'on_export_start': [on_export_start],
|
||||
'on_export_end': [on_export_end]}
|
||||
|
||||
|
||||
def add_integration_callbacks(instance):
|
||||
|
@ -307,18 +307,20 @@ def strip_optimizer(f='best.pt', s=''):
|
||||
LOGGER.info(f"Optimizer stripped from {f},{f' saved as {s},' if s else ''} {mb:.1f}MB")
|
||||
|
||||
|
||||
def guess_task_from_head(head):
|
||||
task = None
|
||||
if head.lower() in ["classify", "classifier", "cls", "fc"]:
|
||||
task = "classify"
|
||||
if head.lower() in ["detect"]:
|
||||
task = "detect"
|
||||
if head.lower() in ["segment"]:
|
||||
task = "segment"
|
||||
|
||||
if not task:
|
||||
raise SyntaxError("task or model not recognized! Please refer the docs at : ") # TODO: add docs links
|
||||
|
||||
def guess_task_from_model_yaml(model):
|
||||
try:
|
||||
cfg = model if isinstance(model, dict) else model.yaml # model cfg dict
|
||||
m = cfg["head"][-1][-2].lower() # output module name
|
||||
task = None
|
||||
if m in ["classify", "classifier", "cls", "fc"]:
|
||||
task = "classify"
|
||||
if m in ["detect"]:
|
||||
task = "detect"
|
||||
if m in ["segment"]:
|
||||
task = "segment"
|
||||
except Exception as e:
|
||||
raise SyntaxError('Unknown task. Define task explicitly, i.e. task=detect when running your command. '
|
||||
'Valid tasks are detect, segment, classify.') from e
|
||||
return task
|
||||
|
||||
|
||||
@ -374,14 +376,36 @@ def profile(input, ops, n=10, device=None):
|
||||
|
||||
|
||||
class EarlyStopping:
|
||||
# early stopper
|
||||
"""
|
||||
Early stopping class that stops training when a specified number of epochs have passed without improvement.
|
||||
"""
|
||||
|
||||
def __init__(self, patience=30):
|
||||
"""
|
||||
Initialize early stopping object
|
||||
|
||||
Args:
|
||||
patience (int, optional): Number of epochs to wait after fitness stops improving before stopping. Default is 30.
|
||||
"""
|
||||
self.best_fitness = 0.0 # i.e. mAP
|
||||
self.best_epoch = 0
|
||||
self.patience = patience or float('inf') # epochs to wait after fitness stops improving to stop
|
||||
self.possible_stop = False # possible stop may occur next epoch
|
||||
|
||||
def __call__(self, epoch, fitness):
|
||||
"""
|
||||
Check whether to stop training
|
||||
|
||||
Args:
|
||||
epoch (int): Current epoch of training
|
||||
fitness (float): Fitness value of current epoch
|
||||
|
||||
Returns:
|
||||
bool: True if training should stop, False otherwise
|
||||
"""
|
||||
if fitness is None: # check if fitness=None (happens when val=False)
|
||||
return False
|
||||
|
||||
if fitness >= self.best_fitness: # >= 0 to allow for early zero-fitness stage of training
|
||||
self.best_epoch = epoch
|
||||
self.best_fitness = fitness
|
||||
|
Reference in New Issue
Block a user