ultralytics 8.3.123__py3-none-any.whl → 8.3.125__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. tests/test_python.py +5 -8
  2. ultralytics/__init__.py +1 -1
  3. ultralytics/cfg/__init__.py +7 -14
  4. ultralytics/cfg/default.yaml +2 -2
  5. ultralytics/data/base.py +1 -2
  6. ultralytics/data/loaders.py +3 -4
  7. ultralytics/data/utils.py +8 -9
  8. ultralytics/engine/exporter.py +7 -7
  9. ultralytics/engine/model.py +7 -4
  10. ultralytics/engine/trainer.py +2 -2
  11. ultralytics/engine/tuner.py +3 -3
  12. ultralytics/hub/session.py +1 -1
  13. ultralytics/models/sam/model.py +2 -1
  14. ultralytics/models/sam/modules/tiny_encoder.py +2 -3
  15. ultralytics/models/sam/predict.py +4 -1
  16. ultralytics/models/yolo/model.py +3 -3
  17. ultralytics/nn/autobackend.py +4 -4
  18. ultralytics/nn/tasks.py +7 -7
  19. ultralytics/solutions/analytics.py +9 -8
  20. ultralytics/solutions/config.py +104 -0
  21. ultralytics/solutions/heatmap.py +1 -1
  22. ultralytics/solutions/object_blurrer.py +1 -1
  23. ultralytics/solutions/object_cropper.py +2 -2
  24. ultralytics/solutions/parking_management.py +2 -2
  25. ultralytics/solutions/security_alarm.py +1 -1
  26. ultralytics/solutions/solutions.py +6 -9
  27. ultralytics/solutions/speed_estimation.py +4 -4
  28. ultralytics/solutions/trackzone.py +1 -1
  29. ultralytics/solutions/vision_eye.py +1 -1
  30. ultralytics/trackers/track.py +2 -2
  31. ultralytics/utils/__init__.py +115 -59
  32. ultralytics/utils/benchmarks.py +4 -8
  33. ultralytics/utils/checks.py +4 -3
  34. ultralytics/utils/dist.py +2 -1
  35. ultralytics/utils/downloads.py +6 -1
  36. ultralytics/utils/metrics.py +6 -2
  37. ultralytics/utils/plotting.py +11 -5
  38. ultralytics/utils/torch_utils.py +10 -5
  39. {ultralytics-8.3.123.dist-info → ultralytics-8.3.125.dist-info}/METADATA +1 -1
  40. {ultralytics-8.3.123.dist-info → ultralytics-8.3.125.dist-info}/RECORD +44 -44
  41. {ultralytics-8.3.123.dist-info → ultralytics-8.3.125.dist-info}/WHEEL +1 -1
  42. ultralytics/cfg/solutions/default.yaml +0 -24
  43. {ultralytics-8.3.123.dist-info → ultralytics-8.3.125.dist-info}/entry_points.txt +0 -0
  44. {ultralytics-8.3.123.dist-info → ultralytics-8.3.125.dist-info}/licenses/LICENSE +0 -0
  45. {ultralytics-8.3.123.dist-info → ultralytics-8.3.125.dist-info}/top_level.txt +0 -0
tests/test_python.py CHANGED
@@ -10,7 +10,6 @@ import cv2
10
10
  import numpy as np
11
11
  import pytest
12
12
  import torch
13
- import yaml
14
13
  from PIL import Image
15
14
 
16
15
  from tests import CFG, MODEL, SOURCE, SOURCES_LIST, TMP
@@ -28,6 +27,7 @@ from ultralytics.utils import (
28
27
  ROOT,
29
28
  WEIGHTS_DIR,
30
29
  WINDOWS,
30
+ YAML,
31
31
  checks,
32
32
  is_dir_writeable,
33
33
  is_github_action_running,
@@ -190,13 +190,10 @@ def test_track_stream():
190
190
 
191
191
  # Test Global Motion Compensation (GMC) methods
192
192
  for gmc in "orb", "sift", "ecc":
193
- with open(ROOT / "cfg/trackers/botsort.yaml", encoding="utf-8") as f:
194
- data = yaml.safe_load(f)
195
- tracker = TMP / f"botsort-{gmc}.yaml"
196
- data["gmc_method"] = gmc
197
- with open(tracker, "w", encoding="utf-8") as f:
198
- yaml.safe_dump(data, f)
199
- model.track(video_url, imgsz=160, tracker=tracker)
193
+ default_args = YAML.load(ROOT / "cfg/trackers/botsort.yaml")
194
+ custom_yaml = TMP / f"botsort-{gmc}.yaml"
195
+ YAML.save(custom_yaml, {**default_args, "gmc_method": gmc})
196
+ model.track(video_url, imgsz=160, tracker=custom_yaml)
200
197
 
201
198
 
202
199
  def test_val():
ultralytics/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
2
2
 
3
- __version__ = "8.3.123"
3
+ __version__ = "8.3.125"
4
4
 
5
5
  import os
6
6
 
@@ -15,7 +15,6 @@ from ultralytics.utils import (
15
15
  DEFAULT_CFG,
16
16
  DEFAULT_CFG_DICT,
17
17
  DEFAULT_CFG_PATH,
18
- DEFAULT_SOL_DICT,
19
18
  IS_VSCODE,
20
19
  LOGGER,
21
20
  RANK,
@@ -24,13 +23,12 @@ from ultralytics.utils import (
24
23
  SETTINGS,
25
24
  SETTINGS_FILE,
26
25
  TESTS_RUNNING,
26
+ YAML,
27
27
  IterableSimpleNamespace,
28
28
  checks,
29
29
  colorstr,
30
30
  deprecation_warn,
31
31
  vscode_msg,
32
- yaml_load,
33
- yaml_print,
34
32
  )
35
33
 
36
34
  # Define valid solutions
@@ -271,7 +269,7 @@ def cfg2dict(cfg: Union[str, Path, Dict, SimpleNamespace]) -> Dict:
271
269
  - If cfg is already a dictionary, it's returned unchanged.
272
270
  """
273
271
  if isinstance(cfg, (str, Path)):
274
- cfg = yaml_load(cfg) # load dict
272
+ cfg = YAML.load(cfg) # load dict
275
273
  elif isinstance(cfg, SimpleNamespace):
276
274
  cfg = vars(cfg) # convert to dict
277
275
  return cfg
@@ -650,7 +648,6 @@ def handle_yolo_solutions(args: List[str]) -> None:
650
648
  >>> handle_yolo_solutions(["inference", "model=yolo11n.pt"])
651
649
 
652
650
  Notes:
653
- - Default configurations are merged from DEFAULT_SOL_DICT and DEFAULT_CFG_DICT
654
651
  - Arguments can be provided in the format 'key=value' or as boolean flags
655
652
  - Available solutions are defined in SOLUTION_MAP with their respective classes and methods
656
653
  - If an invalid solution is provided, defaults to 'count' solution
@@ -662,13 +659,9 @@ def handle_yolo_solutions(args: List[str]) -> None:
662
659
  - The inference solution will be launched using the 'streamlit run' command.
663
660
  - The Streamlit app file is located in the Ultralytics package directory.
664
661
  """
665
- full_args_dict = {
666
- **DEFAULT_SOL_DICT,
667
- **DEFAULT_CFG_DICT,
668
- "blur_ratio": 0.5,
669
- "vision_point": (20, 20),
670
- "crop_dir": "cropped-detections",
671
- } # arguments dictionary
662
+ from ultralytics.solutions.config import SolutionConfig
663
+
664
+ full_args_dict = vars(SolutionConfig()) # arguments dictionary
672
665
  overrides = {}
673
666
 
674
667
  # check dictionary alignment
@@ -859,7 +852,7 @@ def entrypoint(debug: str = "") -> None:
859
852
  "checks": checks.collect_system_info,
860
853
  "version": lambda: LOGGER.info(__version__),
861
854
  "settings": lambda: handle_yolo_settings(args[1:]),
862
- "cfg": lambda: yaml_print(DEFAULT_CFG_PATH),
855
+ "cfg": lambda: YAML.print(DEFAULT_CFG_PATH),
863
856
  "hub": lambda: handle_yolo_hub(args[1:]),
864
857
  "login": lambda: handle_yolo_hub(args),
865
858
  "logout": lambda: handle_yolo_hub(args),
@@ -886,7 +879,7 @@ def entrypoint(debug: str = "") -> None:
886
879
  k, v = parse_key_value_pair(a)
887
880
  if k == "cfg" and v is not None: # custom.yaml passed
888
881
  LOGGER.info(f"Overriding {DEFAULT_CFG_PATH} with {v}")
889
- overrides = {k: val for k, val in yaml_load(checks.check_yaml(v)).items() if k != "cfg"}
882
+ overrides = {k: val for k, val in YAML.load(checks.check_yaml(v)).items() if k != "cfg"}
890
883
  else:
891
884
  overrides[k] = v
892
885
  except (NameError, SyntaxError, ValueError, AssertionError) as e:
@@ -35,7 +35,7 @@ resume: False # (bool) resume training from last checkpoint
35
35
  amp: True # (bool) Automatic Mixed Precision (AMP) training, choices=[True, False], True runs AMP check
36
36
  fraction: 1.0 # (float) dataset fraction to train on (default is 1.0, all images in train set)
37
37
  profile: False # (bool) profile ONNX and TensorRT speeds during training for loggers
38
- freeze: None # (int | list, optional) freeze first n layers, or freeze list of layer indices during training
38
+ freeze: # (int | list, optional) freeze first n layers, or freeze list of layer indices during training
39
39
  multi_scale: False # (bool) Whether to use multiscale during training
40
40
  # Segmentation
41
41
  overlap_mask: True # (bool) merge object masks into a single image mask during training (segment train only)
@@ -84,7 +84,7 @@ int8: False # (bool) CoreML/TF INT8 quantization
84
84
  dynamic: False # (bool) ONNX/TF/TensorRT: dynamic axes
85
85
  simplify: True # (bool) ONNX: simplify model using `onnxslim`
86
86
  opset: # (int, optional) ONNX: opset version
87
- workspace: None # (float, optional) TensorRT: workspace size (GiB), `None` will let TensorRT auto-allocate memory
87
+ workspace: # (float, optional) TensorRT: workspace size (GiB), `None` will let TensorRT auto-allocate memory
88
88
  nms: False # (bool) CoreML: add NMS
89
89
 
90
90
  # Hyperparameters ------------------------------------------------------------------------------------------------------
ultralytics/data/base.py CHANGED
@@ -11,7 +11,6 @@ from typing import Optional
11
11
 
12
12
  import cv2
13
13
  import numpy as np
14
- import psutil
15
14
  from torch.utils.data import Dataset
16
15
 
17
16
  from ultralytics.data.utils import FORMATS_HELP_MSG, HELP_URL, IMG_FORMATS, check_file_speeds
@@ -336,7 +335,7 @@ class BaseDataset(Dataset):
336
335
  ratio = self.imgsz / max(im.shape[0], im.shape[1]) # max(h, w) # ratio
337
336
  b += im.nbytes * ratio**2
338
337
  mem_required = b * self.ni / n * (1 + safety_margin) # GB required to cache dataset into RAM
339
- mem = psutil.virtual_memory()
338
+ mem = __import__("psutil").virtual_memory()
340
339
  if mem_required > mem.available:
341
340
  self.cache = None
342
341
  LOGGER.warning(
@@ -4,14 +4,13 @@ import glob
4
4
  import math
5
5
  import os
6
6
  import time
7
+ import urllib
7
8
  from dataclasses import dataclass
8
9
  from pathlib import Path
9
10
  from threading import Thread
10
- from urllib.parse import urlparse
11
11
 
12
12
  import cv2
13
13
  import numpy as np
14
- import requests
15
14
  import torch
16
15
  from PIL import Image
17
16
 
@@ -111,7 +110,7 @@ class LoadStreams:
111
110
  for i, s in enumerate(sources): # index, source
112
111
  # Start thread to read frames from video stream
113
112
  st = f"{i + 1}/{n}: {s}... "
114
- if urlparse(s).hostname in {"www.youtube.com", "youtube.com", "youtu.be"}: # if source is YouTube video
113
+ if urllib.parse.urlparse(s).hostname in {"www.youtube.com", "youtube.com", "youtu.be"}: # YouTube video
115
114
  # YouTube format i.e. 'https://www.youtube.com/watch?v=Jsn8D3aC840' or 'https://youtu.be/Jsn8D3aC840'
116
115
  s = get_best_youtube_url(s)
117
116
  s = eval(s) if s.isnumeric() else s # i.e. s = '0' local webcam
@@ -589,7 +588,7 @@ def autocast_list(source):
589
588
  files = []
590
589
  for im in source:
591
590
  if isinstance(im, (str, Path)): # filename or uri
592
- files.append(Image.open(requests.get(im, stream=True).raw if str(im).startswith("http") else im))
591
+ files.append(Image.open(urllib.request.urlopen(im) if str(im).startswith("http") else im))
593
592
  elif isinstance(im, (Image.Image, np.ndarray)): # PIL or np Image
594
593
  files.append(im)
595
594
  else:
ultralytics/data/utils.py CHANGED
@@ -1,6 +1,5 @@
1
1
  # Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
2
2
 
3
- import hashlib
4
3
  import json
5
4
  import os
6
5
  import random
@@ -19,16 +18,16 @@ from ultralytics.nn.autobackend import check_class_names
19
18
  from ultralytics.utils import (
20
19
  DATASETS_DIR,
21
20
  LOGGER,
21
+ MACOS,
22
22
  NUM_THREADS,
23
23
  ROOT,
24
24
  SETTINGS_FILE,
25
25
  TQDM,
26
+ YAML,
26
27
  clean_url,
27
28
  colorstr,
28
29
  emojis,
29
30
  is_dir_writeable,
30
- yaml_load,
31
- yaml_save,
32
31
  )
33
32
  from ultralytics.utils.checks import check_file, check_font, is_ascii
34
33
  from ultralytics.utils.downloads import download, safe_download, unzip_file
@@ -37,7 +36,7 @@ from ultralytics.utils.ops import segments2boxes
37
36
  HELP_URL = "See https://docs.ultralytics.com/datasets for dataset formatting guidance."
38
37
  IMG_FORMATS = {"bmp", "dng", "jpeg", "jpg", "mpo", "png", "tif", "tiff", "webp", "pfm", "heic"} # image suffixes
39
38
  VID_FORMATS = {"asf", "avi", "gif", "m4v", "mkv", "mov", "mp4", "mpeg", "mpg", "ts", "wmv", "webm"} # video suffixes
40
- PIN_MEMORY = str(os.getenv("PIN_MEMORY", True)).lower() == "true" # global pin_memory for dataloaders
39
+ PIN_MEMORY = str(os.getenv("PIN_MEMORY", not MACOS)).lower() == "true" # global pin_memory for dataloaders
41
40
  FORMATS_HELP_MSG = f"Supported formats are:\nimages: {IMG_FORMATS}\nvideos: {VID_FORMATS}"
42
41
 
43
42
 
@@ -131,7 +130,7 @@ def get_hash(paths):
131
130
  size += os.stat(p).st_size
132
131
  except OSError:
133
132
  continue
134
- h = hashlib.sha256(str(size).encode()) # hash sizes
133
+ h = __import__("hashlib").sha256(str(size).encode()) # hash sizes
135
134
  h.update("".join(paths).encode()) # hash paths
136
135
  return h.hexdigest() # return hash
137
136
 
@@ -400,7 +399,7 @@ def check_det_dataset(dataset, autodownload=True):
400
399
  extract_dir, autodownload = file.parent, False
401
400
 
402
401
  # Read YAML
403
- data = yaml_load(file, append_filename=True) # dictionary
402
+ data = YAML.load(file, append_filename=True) # dictionary
404
403
 
405
404
  # Checks
406
405
  for k in "train", "val":
@@ -493,7 +492,7 @@ def check_cls_dataset(dataset, split=""):
493
492
  # Download (optional if dataset=https://file.zip is passed directly)
494
493
  if str(dataset).startswith(("http:/", "https:/")):
495
494
  dataset = safe_download(dataset, dir=DATASETS_DIR, unzip=True, delete=False)
496
- elif Path(dataset).suffix in {".zip", ".tar", ".gz"}:
495
+ elif str(dataset).endswith((".zip", ".tar", ".gz")):
497
496
  file = check_file(dataset)
498
497
  dataset = safe_download(file, dir=DATASETS_DIR, unzip=True, delete=False)
499
498
 
@@ -600,9 +599,9 @@ class HUBDatasetStats:
600
599
  _, data_dir, yaml_path = self._unzip(Path(path))
601
600
  try:
602
601
  # Load YAML with checks
603
- data = yaml_load(yaml_path)
602
+ data = YAML.load(yaml_path)
604
603
  data["path"] = "" # strip path since YAML should be in dataset root for all HUB datasets
605
- yaml_save(yaml_path, data)
604
+ YAML.save(yaml_path, data)
606
605
  data = check_det_dataset(yaml_path, autodownload) # dict
607
606
  data["path"] = data_dir # YAML path should be set to '' (relative) or parent (absolute)
608
607
  except Exception as e:
@@ -89,10 +89,10 @@ from ultralytics.utils import (
89
89
  RKNN_CHIPS,
90
90
  ROOT,
91
91
  WINDOWS,
92
+ YAML,
92
93
  callbacks,
93
94
  colorstr,
94
95
  get_default_args,
95
- yaml_save,
96
96
  )
97
97
  from ultralytics.utils.checks import (
98
98
  check_imgsz,
@@ -631,7 +631,7 @@ class Exporter:
631
631
  ov_model.set_rt_info("fit_to_window_letterbox", ["model_info", "resize_type"])
632
632
 
633
633
  ov.save_model(ov_model, file, compress_to_fp16=self.args.half)
634
- yaml_save(Path(file).parent / "metadata.yaml", self.metadata) # add metadata.yaml
634
+ YAML.save(Path(file).parent / "metadata.yaml", self.metadata) # add metadata.yaml
635
635
 
636
636
  if self.args.int8:
637
637
  fq = str(self.file).replace(self.file.suffix, f"_int8_openvino_model{os.sep}")
@@ -690,7 +690,7 @@ class Exporter:
690
690
  f = str(self.file).replace(self.file.suffix, f"_paddle_model{os.sep}")
691
691
 
692
692
  pytorch2paddle(module=self.model, save_dir=f, jit_type="trace", input_examples=[self.im]) # export
693
- yaml_save(Path(f) / "metadata.yaml", self.metadata) # add metadata.yaml
693
+ YAML.save(Path(f) / "metadata.yaml", self.metadata) # add metadata.yaml
694
694
  return f, None
695
695
 
696
696
  @try_export
@@ -783,7 +783,7 @@ class Exporter:
783
783
  for f_debug in ("debug.bin", "debug.param", "debug2.bin", "debug2.param", *pnnx_files):
784
784
  Path(f_debug).unlink(missing_ok=True)
785
785
 
786
- yaml_save(f / "metadata.yaml", self.metadata) # add metadata.yaml
786
+ YAML.save(f / "metadata.yaml", self.metadata) # add metadata.yaml
787
787
  return str(f), None
788
788
 
789
789
  @try_export
@@ -974,7 +974,7 @@ class Exporter:
974
974
  output_signaturedefs=True, # fix error with Attention block group convolution
975
975
  optimization_for_gpu_delegate=True,
976
976
  )
977
- yaml_save(f / "metadata.yaml", self.metadata) # add metadata.yaml
977
+ YAML.save(f / "metadata.yaml", self.metadata) # add metadata.yaml
978
978
 
979
979
  # Remove/rename TFLite models
980
980
  if self.args.int8:
@@ -1087,7 +1087,7 @@ class Exporter:
1087
1087
  LOGGER.warning(f"{prefix} your model may not work correctly with spaces in path '{f}'.")
1088
1088
 
1089
1089
  # Add metadata
1090
- yaml_save(Path(f) / "metadata.yaml", self.metadata) # add metadata.yaml
1090
+ YAML.save(Path(f) / "metadata.yaml", self.metadata) # add metadata.yaml
1091
1091
  return f, None
1092
1092
 
1093
1093
  @try_export
@@ -1114,7 +1114,7 @@ class Exporter:
1114
1114
  rknn.build(do_quantization=self.args.int8)
1115
1115
  f = f.replace(".onnx", f"-{self.args.name}-int8.rknn" if self.args.int8 else f"-{self.args.name}-fp16.rknn")
1116
1116
  rknn.export_rknn(f"{export_path / f}")
1117
- yaml_save(export_path / "metadata.yaml", self.metadata)
1117
+ YAML.save(export_path / "metadata.yaml", self.metadata)
1118
1118
  return export_path, None
1119
1119
 
1120
1120
  @try_export
@@ -10,7 +10,6 @@ from PIL import Image
10
10
 
11
11
  from ultralytics.cfg import TASK2DATA, get_cfg, get_save_dir
12
12
  from ultralytics.engine.results import Results
13
- from ultralytics.hub import HUB_WEB_ROOT, HUBTrainingSession
14
13
  from ultralytics.nn.tasks import attempt_load_one_weight, guess_model_task, yaml_model_load
15
14
  from ultralytics.utils import (
16
15
  ARGV,
@@ -19,9 +18,9 @@ from ultralytics.utils import (
19
18
  LOGGER,
20
19
  RANK,
21
20
  SETTINGS,
21
+ YAML,
22
22
  callbacks,
23
23
  checks,
24
- yaml_load,
25
24
  )
26
25
 
27
26
 
@@ -126,6 +125,8 @@ class Model(torch.nn.Module):
126
125
 
127
126
  # Check if Ultralytics HUB model from https://hub.ultralytics.com
128
127
  if self.is_hub_model(model):
128
+ from ultralytics.hub import HUBTrainingSession
129
+
129
130
  # Fetch model from HUB
130
131
  checks.check_requirements("hub-sdk>=0.0.12")
131
132
  session = HUBTrainingSession.create_session(model)
@@ -141,7 +142,7 @@ class Model(torch.nn.Module):
141
142
 
142
143
  # Load or create new YOLO model
143
144
  __import__("os").environ["CUBLAS_WORKSPACE_CONFIG"] = ":4096:8" # to avoid deterministic warnings
144
- if Path(model).suffix in {".yaml", ".yml"}:
145
+ if str(model).endswith((".yaml", ".yml")):
145
146
  self._new(model, task=task, verbose=verbose)
146
147
  else:
147
148
  self._load(model, task=task)
@@ -225,6 +226,8 @@ class Model(torch.nn.Module):
225
226
  >>> Model.is_hub_model("yolo11n.pt")
226
227
  False
227
228
  """
229
+ from ultralytics.hub import HUB_WEB_ROOT
230
+
228
231
  return model.startswith(f"{HUB_WEB_ROOT}/models/")
229
232
 
230
233
  def _new(self, cfg: str, task=None, model=None, verbose=False) -> None:
@@ -770,7 +773,7 @@ class Model(torch.nn.Module):
770
773
 
771
774
  checks.check_pip_update_available()
772
775
 
773
- overrides = yaml_load(checks.check_yaml(kwargs["cfg"])) if kwargs.get("cfg") else self.overrides
776
+ overrides = YAML.load(checks.check_yaml(kwargs["cfg"])) if kwargs.get("cfg") else self.overrides
774
777
  custom = {
775
778
  # NOTE: handle the case when 'cfg' includes 'data'.
776
779
  "data": overrides.get("data") or DEFAULT_CFG_DICT["data"] or TASK2DATA[self.task],
@@ -31,11 +31,11 @@ from ultralytics.utils import (
31
31
  LOGGER,
32
32
  RANK,
33
33
  TQDM,
34
+ YAML,
34
35
  callbacks,
35
36
  clean_url,
36
37
  colorstr,
37
38
  emojis,
38
- yaml_save,
39
39
  )
40
40
  from ultralytics.utils.autobatch import check_train_batch_size
41
41
  from ultralytics.utils.checks import check_amp, check_file, check_imgsz, check_model_file_from_stem, print_args
@@ -117,7 +117,7 @@ class BaseTrainer:
117
117
  if RANK in {-1, 0}:
118
118
  self.wdir.mkdir(parents=True, exist_ok=True) # make dir
119
119
  self.args.save_dir = str(self.save_dir)
120
- yaml_save(self.save_dir / "args.yaml", vars(self.args)) # save run args
120
+ YAML.save(self.save_dir / "args.yaml", vars(self.args)) # save run args
121
121
  self.last, self.best = self.wdir / "last.pt", self.wdir / "best.pt" # checkpoint paths
122
122
  self.save_period = self.args.save_period
123
123
 
@@ -23,7 +23,7 @@ import numpy as np
23
23
  import torch
24
24
 
25
25
  from ultralytics.cfg import get_cfg, get_save_dir
26
- from ultralytics.utils import DEFAULT_CFG, LOGGER, callbacks, colorstr, remove_colorstr, yaml_print, yaml_save
26
+ from ultralytics.utils import DEFAULT_CFG, LOGGER, YAML, callbacks, colorstr, remove_colorstr
27
27
  from ultralytics.utils.plotting import plot_tune_results
28
28
 
29
29
 
@@ -235,9 +235,9 @@ class Tuner:
235
235
  )
236
236
  LOGGER.info("\n" + header)
237
237
  data = {k: float(x[best_idx, i + 1]) for i, k in enumerate(self.space.keys())}
238
- yaml_save(
238
+ YAML.save(
239
239
  self.tune_dir / "best_hyperparameters.yaml",
240
240
  data=data,
241
241
  header=remove_colorstr(header.replace(self.prefix, "# ")) + "\n",
242
242
  )
243
- yaml_print(self.tune_dir / "best_hyperparameters.yaml")
243
+ YAML.print(self.tune_dir / "best_hyperparameters.yaml")
@@ -201,7 +201,7 @@ class HUBTrainingSession:
201
201
  HUBModelError: If the identifier format is not recognized.
202
202
  """
203
203
  api_key, model_id, filename = None, None, None
204
- if Path(identifier).suffix in {".pt", ".yaml"}:
204
+ if str(identifier).endswith((".pt", ".yaml")):
205
205
  filename = identifier
206
206
  elif identifier.startswith(f"{HUB_WEB_ROOT}/models/"):
207
207
  parsed_url = urlparse(identifier)
@@ -19,7 +19,6 @@ from pathlib import Path
19
19
  from ultralytics.engine.model import Model
20
20
  from ultralytics.utils.torch_utils import model_info
21
21
 
22
- from .build import build_sam
23
22
  from .predict import Predictor, SAM2Predictor
24
23
 
25
24
 
@@ -78,6 +77,8 @@ class SAM(Model):
78
77
  >>> sam = SAM("sam_b.pt")
79
78
  >>> sam._load("path/to/custom_weights.pt")
80
79
  """
80
+ from .build import build_sam # slow import
81
+
81
82
  self.model = build_sam(weights)
82
83
 
83
84
  def predict(self, source, stream=False, bboxes=None, points=None, labels=None, **kwargs):
@@ -15,7 +15,6 @@ from typing import Tuple
15
15
  import torch
16
16
  import torch.nn as nn
17
17
  import torch.nn.functional as F
18
- import torch.utils.checkpoint as checkpoint
19
18
 
20
19
  from ultralytics.nn.modules import LayerNorm2d
21
20
  from ultralytics.utils.instance import to_2tuple
@@ -308,7 +307,7 @@ class ConvLayer(nn.Module):
308
307
  def forward(self, x):
309
308
  """Processes input through convolutional layers, applying MBConv blocks and optional downsampling."""
310
309
  for blk in self.blocks:
311
- x = checkpoint.checkpoint(blk, x) if self.use_checkpoint else blk(x)
310
+ x = torch.utils.checkpoint(blk, x) if self.use_checkpoint else blk(x) # warn: checkpoint is slow import
312
311
  return x if self.downsample is None else self.downsample(x)
313
312
 
314
313
 
@@ -751,7 +750,7 @@ class BasicLayer(nn.Module):
751
750
  def forward(self, x):
752
751
  """Processes input through TinyViT blocks and optional downsampling."""
753
752
  for blk in self.blocks:
754
- x = checkpoint.checkpoint(blk, x) if self.use_checkpoint else blk(x)
753
+ x = torch.utils.checkpoint(blk, x) if self.use_checkpoint else blk(x) # warn: checkpoint is slow import
755
754
  return x if self.downsample is None else self.downsample(x)
756
755
 
757
756
  def extra_repr(self) -> str:
@@ -31,7 +31,6 @@ from .amg import (
31
31
  uncrop_boxes_xyxy,
32
32
  uncrop_masks,
33
33
  )
34
- from .build import build_sam
35
34
 
36
35
 
37
36
  class Predictor(BasePredictor):
@@ -439,6 +438,8 @@ class Predictor(BasePredictor):
439
438
 
440
439
  def get_model(self):
441
440
  """Retrieves or builds the Segment Anything Model (SAM) for image segmentation tasks."""
441
+ from .build import build_sam # slow import
442
+
442
443
  return build_sam(self.args.model)
443
444
 
444
445
  def postprocess(self, preds, img, orig_imgs):
@@ -658,6 +659,8 @@ class SAM2Predictor(Predictor):
658
659
 
659
660
  def get_model(self):
660
661
  """Retrieves and initializes the Segment Anything Model 2 (SAM2) for image segmentation tasks."""
662
+ from .build import build_sam # slow import
663
+
661
664
  return build_sam(self.args.model)
662
665
 
663
666
  def prompt_inference(
@@ -15,7 +15,7 @@ from ultralytics.nn.tasks import (
15
15
  YOLOEModel,
16
16
  YOLOESegModel,
17
17
  )
18
- from ultralytics.utils import ROOT, yaml_load
18
+ from ultralytics.utils import ROOT, YAML
19
19
 
20
20
 
21
21
  class YOLO(Model):
@@ -107,7 +107,7 @@ class YOLOWorld(Model):
107
107
 
108
108
  # Assign default COCO class names when there are no custom names
109
109
  if not hasattr(self.model, "names"):
110
- self.model.names = yaml_load(ROOT / "cfg/datasets/coco8.yaml").get("names")
110
+ self.model.names = YAML.load(ROOT / "cfg/datasets/coco8.yaml").get("names")
111
111
 
112
112
  @property
113
113
  def task_map(self):
@@ -156,7 +156,7 @@ class YOLOE(Model):
156
156
 
157
157
  # Assign default COCO class names when there are no custom names
158
158
  if not hasattr(self.model, "names"):
159
- self.model.names = yaml_load(ROOT / "cfg/datasets/coco8.yaml").get("names")
159
+ self.model.names = YAML.load(ROOT / "cfg/datasets/coco8.yaml").get("names")
160
160
 
161
161
  @property
162
162
  def task_map(self):
@@ -14,7 +14,7 @@ import torch
14
14
  import torch.nn as nn
15
15
  from PIL import Image
16
16
 
17
- from ultralytics.utils import ARM64, IS_JETSON, LINUX, LOGGER, PYTHON_VERSION, ROOT, yaml_load
17
+ from ultralytics.utils import ARM64, IS_JETSON, LINUX, LOGGER, PYTHON_VERSION, ROOT, YAML
18
18
  from ultralytics.utils.checks import check_requirements, check_suffix, check_version, check_yaml, is_rockchip
19
19
  from ultralytics.utils.downloads import attempt_download_asset, is_url
20
20
 
@@ -33,7 +33,7 @@ def check_class_names(names):
33
33
  f"{min(names.keys())}-{max(names.keys())} defined in your dataset YAML."
34
34
  )
35
35
  if isinstance(names[0], str) and names[0].startswith("n0"): # imagenet class codes, i.e. 'n01440764'
36
- names_map = yaml_load(ROOT / "cfg/datasets/ImageNet.yaml")["map"] # human-readable names
36
+ names_map = YAML.load(ROOT / "cfg/datasets/ImageNet.yaml")["map"] # human-readable names
37
37
  names = {k: names_map[v] for k, v in names.items()}
38
38
  return names
39
39
 
@@ -42,7 +42,7 @@ def default_class_names(data=None):
42
42
  """Applies default class names to an input YAML file or returns numerical class names."""
43
43
  if data:
44
44
  try:
45
- return yaml_load(check_yaml(data))["names"]
45
+ return YAML.load(check_yaml(data))["names"]
46
46
  except Exception:
47
47
  pass
48
48
  return {i: f"class{i}" for i in range(999)} # return default if above errors
@@ -536,7 +536,7 @@ class AutoBackend(nn.Module):
536
536
 
537
537
  # Load external metadata YAML
538
538
  if isinstance(metadata, (str, Path)) and Path(metadata).exists():
539
- metadata = yaml_load(metadata)
539
+ metadata = YAML.load(metadata)
540
540
  if metadata and isinstance(metadata, dict):
541
541
  for k, v in metadata.items():
542
542
  if k in {"stride", "batch", "channels"}:
ultralytics/nn/tasks.py CHANGED
@@ -69,7 +69,7 @@ from ultralytics.nn.modules import (
69
69
  YOLOESegment,
70
70
  v10Detect,
71
71
  )
72
- from ultralytics.utils import DEFAULT_CFG_DICT, DEFAULT_CFG_KEYS, LOGGER, colorstr, emojis, yaml_load
72
+ from ultralytics.utils import DEFAULT_CFG_DICT, DEFAULT_CFG_KEYS, LOGGER, YAML, colorstr, emojis
73
73
  from ultralytics.utils.checks import check_requirements, check_suffix, check_yaml
74
74
  from ultralytics.utils.loss import (
75
75
  E2EDetectLoss,
@@ -92,11 +92,6 @@ from ultralytics.utils.torch_utils import (
92
92
  time_sync,
93
93
  )
94
94
 
95
- try:
96
- import thop
97
- except ImportError:
98
- thop = None # conda support without 'ultralytics-thop' installed
99
-
100
95
 
101
96
  class BaseModel(torch.nn.Module):
102
97
  """The BaseModel class serves as a base class for all the models in the Ultralytics YOLO family."""
@@ -183,6 +178,11 @@ class BaseModel(torch.nn.Module):
183
178
  x (torch.Tensor): The input data to the layer.
184
179
  dt (list): A list to store the computation time of the layer.
185
180
  """
181
+ try:
182
+ import thop
183
+ except ImportError:
184
+ thop = None # conda support without 'ultralytics-thop' installed
185
+
186
186
  c = m == self.model[-1] and isinstance(x, list) # is final layer list, copy input as inplace fix
187
187
  flops = thop.profile(m, inputs=[x.copy() if c else x], verbose=False)[0] / 1e9 * 2 if thop else 0 # GFLOPs
188
188
  t = time_sync()
@@ -1523,7 +1523,7 @@ def yaml_model_load(path):
1523
1523
 
1524
1524
  unified_path = re.sub(r"(\d+)([nslmx])(.+)?$", r"\1\3", str(path)) # i.e. yolov8x.yaml -> yolov8.yaml
1525
1525
  yaml_file = check_yaml(unified_path, hard=False) or check_yaml(path)
1526
- d = yaml_load(yaml_file) # model dict
1526
+ d = YAML.load(yaml_file) # model dict
1527
1527
  d["scale"] = guess_model_scale(path)
1528
1528
  d["yaml_file"] = str(path)
1529
1529
  return d