ultralytics 8.0.237__py3-none-any.whl → 8.0.239__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.

Potentially problematic release.


This version of ultralytics might be problematic. Click here for more details.

Files changed (137) hide show
  1. ultralytics/__init__.py +2 -2
  2. ultralytics/cfg/__init__.py +241 -138
  3. ultralytics/cfg/datasets/DOTAv1.5.yaml +1 -1
  4. ultralytics/cfg/datasets/DOTAv1.yaml +1 -1
  5. ultralytics/cfg/datasets/dota8.yaml +34 -0
  6. ultralytics/data/__init__.py +9 -2
  7. ultralytics/data/annotator.py +4 -4
  8. ultralytics/data/augment.py +186 -169
  9. ultralytics/data/base.py +54 -48
  10. ultralytics/data/build.py +34 -23
  11. ultralytics/data/converter.py +242 -70
  12. ultralytics/data/dataset.py +117 -95
  13. ultralytics/data/explorer/__init__.py +5 -0
  14. ultralytics/data/explorer/explorer.py +170 -97
  15. ultralytics/data/explorer/gui/__init__.py +1 -0
  16. ultralytics/data/explorer/gui/dash.py +146 -76
  17. ultralytics/data/explorer/utils.py +87 -25
  18. ultralytics/data/loaders.py +75 -62
  19. ultralytics/data/split_dota.py +44 -36
  20. ultralytics/data/utils.py +160 -142
  21. ultralytics/engine/exporter.py +348 -292
  22. ultralytics/engine/model.py +102 -66
  23. ultralytics/engine/predictor.py +74 -55
  24. ultralytics/engine/results.py +63 -40
  25. ultralytics/engine/trainer.py +192 -144
  26. ultralytics/engine/tuner.py +66 -59
  27. ultralytics/engine/validator.py +31 -26
  28. ultralytics/hub/__init__.py +54 -31
  29. ultralytics/hub/auth.py +28 -25
  30. ultralytics/hub/session.py +282 -133
  31. ultralytics/hub/utils.py +64 -42
  32. ultralytics/models/__init__.py +1 -1
  33. ultralytics/models/fastsam/__init__.py +1 -1
  34. ultralytics/models/fastsam/model.py +6 -6
  35. ultralytics/models/fastsam/predict.py +3 -2
  36. ultralytics/models/fastsam/prompt.py +55 -48
  37. ultralytics/models/fastsam/val.py +1 -1
  38. ultralytics/models/nas/__init__.py +1 -1
  39. ultralytics/models/nas/model.py +9 -8
  40. ultralytics/models/nas/predict.py +8 -6
  41. ultralytics/models/nas/val.py +11 -9
  42. ultralytics/models/rtdetr/__init__.py +1 -1
  43. ultralytics/models/rtdetr/model.py +11 -9
  44. ultralytics/models/rtdetr/train.py +18 -16
  45. ultralytics/models/rtdetr/val.py +25 -19
  46. ultralytics/models/sam/__init__.py +1 -1
  47. ultralytics/models/sam/amg.py +13 -14
  48. ultralytics/models/sam/build.py +44 -42
  49. ultralytics/models/sam/model.py +6 -6
  50. ultralytics/models/sam/modules/decoders.py +6 -4
  51. ultralytics/models/sam/modules/encoders.py +37 -35
  52. ultralytics/models/sam/modules/sam.py +5 -4
  53. ultralytics/models/sam/modules/tiny_encoder.py +95 -73
  54. ultralytics/models/sam/modules/transformer.py +3 -2
  55. ultralytics/models/sam/predict.py +39 -27
  56. ultralytics/models/utils/loss.py +99 -95
  57. ultralytics/models/utils/ops.py +34 -31
  58. ultralytics/models/yolo/__init__.py +1 -1
  59. ultralytics/models/yolo/classify/__init__.py +1 -1
  60. ultralytics/models/yolo/classify/predict.py +8 -6
  61. ultralytics/models/yolo/classify/train.py +37 -31
  62. ultralytics/models/yolo/classify/val.py +26 -24
  63. ultralytics/models/yolo/detect/__init__.py +1 -1
  64. ultralytics/models/yolo/detect/predict.py +8 -6
  65. ultralytics/models/yolo/detect/train.py +47 -37
  66. ultralytics/models/yolo/detect/val.py +100 -82
  67. ultralytics/models/yolo/model.py +31 -25
  68. ultralytics/models/yolo/obb/__init__.py +1 -1
  69. ultralytics/models/yolo/obb/predict.py +13 -12
  70. ultralytics/models/yolo/obb/train.py +3 -3
  71. ultralytics/models/yolo/obb/val.py +80 -58
  72. ultralytics/models/yolo/pose/__init__.py +1 -1
  73. ultralytics/models/yolo/pose/predict.py +17 -12
  74. ultralytics/models/yolo/pose/train.py +28 -25
  75. ultralytics/models/yolo/pose/val.py +91 -64
  76. ultralytics/models/yolo/segment/__init__.py +1 -1
  77. ultralytics/models/yolo/segment/predict.py +10 -8
  78. ultralytics/models/yolo/segment/train.py +16 -15
  79. ultralytics/models/yolo/segment/val.py +90 -68
  80. ultralytics/nn/__init__.py +26 -6
  81. ultralytics/nn/autobackend.py +144 -112
  82. ultralytics/nn/modules/__init__.py +96 -13
  83. ultralytics/nn/modules/block.py +28 -7
  84. ultralytics/nn/modules/conv.py +41 -23
  85. ultralytics/nn/modules/head.py +67 -59
  86. ultralytics/nn/modules/transformer.py +49 -32
  87. ultralytics/nn/modules/utils.py +20 -15
  88. ultralytics/nn/tasks.py +215 -141
  89. ultralytics/solutions/ai_gym.py +59 -47
  90. ultralytics/solutions/distance_calculation.py +22 -15
  91. ultralytics/solutions/heatmap.py +76 -54
  92. ultralytics/solutions/object_counter.py +46 -39
  93. ultralytics/solutions/speed_estimation.py +13 -16
  94. ultralytics/trackers/__init__.py +1 -1
  95. ultralytics/trackers/basetrack.py +1 -0
  96. ultralytics/trackers/bot_sort.py +2 -1
  97. ultralytics/trackers/byte_tracker.py +10 -7
  98. ultralytics/trackers/track.py +7 -7
  99. ultralytics/trackers/utils/gmc.py +25 -25
  100. ultralytics/trackers/utils/kalman_filter.py +85 -42
  101. ultralytics/trackers/utils/matching.py +8 -7
  102. ultralytics/utils/__init__.py +173 -151
  103. ultralytics/utils/autobatch.py +10 -10
  104. ultralytics/utils/benchmarks.py +76 -86
  105. ultralytics/utils/callbacks/__init__.py +1 -1
  106. ultralytics/utils/callbacks/base.py +29 -29
  107. ultralytics/utils/callbacks/clearml.py +51 -43
  108. ultralytics/utils/callbacks/comet.py +81 -66
  109. ultralytics/utils/callbacks/dvc.py +33 -26
  110. ultralytics/utils/callbacks/hub.py +44 -26
  111. ultralytics/utils/callbacks/mlflow.py +31 -24
  112. ultralytics/utils/callbacks/neptune.py +35 -25
  113. ultralytics/utils/callbacks/raytune.py +9 -4
  114. ultralytics/utils/callbacks/tensorboard.py +16 -11
  115. ultralytics/utils/callbacks/wb.py +39 -33
  116. ultralytics/utils/checks.py +189 -141
  117. ultralytics/utils/dist.py +15 -12
  118. ultralytics/utils/downloads.py +112 -96
  119. ultralytics/utils/errors.py +1 -1
  120. ultralytics/utils/files.py +11 -11
  121. ultralytics/utils/instance.py +22 -22
  122. ultralytics/utils/loss.py +117 -67
  123. ultralytics/utils/metrics.py +224 -158
  124. ultralytics/utils/ops.py +39 -29
  125. ultralytics/utils/patches.py +3 -3
  126. ultralytics/utils/plotting.py +217 -120
  127. ultralytics/utils/tal.py +19 -13
  128. ultralytics/utils/torch_utils.py +138 -109
  129. ultralytics/utils/triton.py +12 -10
  130. ultralytics/utils/tuner.py +49 -47
  131. {ultralytics-8.0.237.dist-info → ultralytics-8.0.239.dist-info}/METADATA +5 -4
  132. ultralytics-8.0.239.dist-info/RECORD +188 -0
  133. ultralytics-8.0.237.dist-info/RECORD +0 -187
  134. {ultralytics-8.0.237.dist-info → ultralytics-8.0.239.dist-info}/LICENSE +0 -0
  135. {ultralytics-8.0.237.dist-info → ultralytics-8.0.239.dist-info}/WHEEL +0 -0
  136. {ultralytics-8.0.237.dist-info → ultralytics-8.0.239.dist-info}/entry_points.txt +0 -0
  137. {ultralytics-8.0.237.dist-info → ultralytics-8.0.239.dist-info}/top_level.txt +0 -0
@@ -1,9 +1,29 @@
1
1
  # Ultralytics YOLO 🚀, AGPL-3.0 license
2
2
 
3
- from .tasks import (BaseModel, ClassificationModel, DetectionModel, SegmentationModel, attempt_load_one_weight,
4
- attempt_load_weights, guess_model_scale, guess_model_task, parse_model, torch_safe_load,
5
- yaml_model_load)
3
+ from .tasks import (
4
+ BaseModel,
5
+ ClassificationModel,
6
+ DetectionModel,
7
+ SegmentationModel,
8
+ attempt_load_one_weight,
9
+ attempt_load_weights,
10
+ guess_model_scale,
11
+ guess_model_task,
12
+ parse_model,
13
+ torch_safe_load,
14
+ yaml_model_load,
15
+ )
6
16
 
7
- __all__ = ('attempt_load_one_weight', 'attempt_load_weights', 'parse_model', 'yaml_model_load', 'guess_model_task',
8
- 'guess_model_scale', 'torch_safe_load', 'DetectionModel', 'SegmentationModel', 'ClassificationModel',
9
- 'BaseModel')
17
+ __all__ = (
18
+ "attempt_load_one_weight",
19
+ "attempt_load_weights",
20
+ "parse_model",
21
+ "yaml_model_load",
22
+ "guess_model_task",
23
+ "guess_model_scale",
24
+ "torch_safe_load",
25
+ "DetectionModel",
26
+ "SegmentationModel",
27
+ "ClassificationModel",
28
+ "BaseModel",
29
+ )
@@ -32,10 +32,12 @@ def check_class_names(names):
32
32
  names = {int(k): str(v) for k, v in names.items()}
33
33
  n = len(names)
34
34
  if max(names.keys()) >= n:
35
- raise KeyError(f'{n}-class dataset requires class indices 0-{n - 1}, but you have invalid class indices '
36
- f'{min(names.keys())}-{max(names.keys())} defined in your dataset YAML.')
37
- if isinstance(names[0], str) and names[0].startswith('n0'): # imagenet class codes, i.e. 'n01440764'
38
- names_map = yaml_load(ROOT / 'cfg/datasets/ImageNet.yaml')['map'] # human-readable names
35
+ raise KeyError(
36
+ f"{n}-class dataset requires class indices 0-{n - 1}, but you have invalid class indices "
37
+ f"{min(names.keys())}-{max(names.keys())} defined in your dataset YAML."
38
+ )
39
+ if isinstance(names[0], str) and names[0].startswith("n0"): # imagenet class codes, i.e. 'n01440764'
40
+ names_map = yaml_load(ROOT / "cfg/datasets/ImageNet.yaml")["map"] # human-readable names
39
41
  names = {k: names_map[v] for k, v in names.items()}
40
42
  return names
41
43
 
@@ -44,8 +46,8 @@ def default_class_names(data=None):
44
46
  """Applies default class names to an input YAML file or returns numerical class names."""
45
47
  if data:
46
48
  with contextlib.suppress(Exception):
47
- return yaml_load(check_yaml(data))['names']
48
- return {i: f'class{i}' for i in range(999)} # return default if above errors
49
+ return yaml_load(check_yaml(data))["names"]
50
+ return {i: f"class{i}" for i in range(999)} # return default if above errors
49
51
 
50
52
 
51
53
  class AutoBackend(nn.Module):
@@ -77,14 +79,16 @@ class AutoBackend(nn.Module):
77
79
  """
78
80
 
79
81
  @torch.no_grad()
80
- def __init__(self,
81
- weights='yolov8n.pt',
82
- device=torch.device('cpu'),
83
- dnn=False,
84
- data=None,
85
- fp16=False,
86
- fuse=True,
87
- verbose=True):
82
+ def __init__(
83
+ self,
84
+ weights="yolov8n.pt",
85
+ device=torch.device("cpu"),
86
+ dnn=False,
87
+ data=None,
88
+ fp16=False,
89
+ fuse=True,
90
+ verbose=True,
91
+ ):
88
92
  """
89
93
  Initialize the AutoBackend for inference.
90
94
 
@@ -100,17 +104,31 @@ class AutoBackend(nn.Module):
100
104
  super().__init__()
101
105
  w = str(weights[0] if isinstance(weights, list) else weights)
102
106
  nn_module = isinstance(weights, torch.nn.Module)
103
- pt, jit, onnx, xml, engine, coreml, saved_model, pb, tflite, edgetpu, tfjs, paddle, ncnn, triton = \
104
- self._model_type(w)
107
+ (
108
+ pt,
109
+ jit,
110
+ onnx,
111
+ xml,
112
+ engine,
113
+ coreml,
114
+ saved_model,
115
+ pb,
116
+ tflite,
117
+ edgetpu,
118
+ tfjs,
119
+ paddle,
120
+ ncnn,
121
+ triton,
122
+ ) = self._model_type(w)
105
123
  fp16 &= pt or jit or onnx or xml or engine or nn_module or triton # FP16
106
124
  nhwc = coreml or saved_model or pb or tflite or edgetpu # BHWC formats (vs torch BCWH)
107
125
  stride = 32 # default stride
108
126
  model, metadata = None, None
109
127
 
110
128
  # Set device
111
- cuda = torch.cuda.is_available() and device.type != 'cpu' # use CUDA
129
+ cuda = torch.cuda.is_available() and device.type != "cpu" # use CUDA
112
130
  if cuda and not any([nn_module, pt, jit, engine, onnx]): # GPU dataloader formats
113
- device = torch.device('cpu')
131
+ device = torch.device("cpu")
114
132
  cuda = False
115
133
 
116
134
  # Download if not local
@@ -121,77 +139,79 @@ class AutoBackend(nn.Module):
121
139
  if nn_module: # in-memory PyTorch model
122
140
  model = weights.to(device)
123
141
  model = model.fuse(verbose=verbose) if fuse else model
124
- if hasattr(model, 'kpt_shape'):
142
+ if hasattr(model, "kpt_shape"):
125
143
  kpt_shape = model.kpt_shape # pose-only
126
144
  stride = max(int(model.stride.max()), 32) # model stride
127
- names = model.module.names if hasattr(model, 'module') else model.names # get class names
145
+ names = model.module.names if hasattr(model, "module") else model.names # get class names
128
146
  model.half() if fp16 else model.float()
129
147
  self.model = model # explicitly assign for to(), cpu(), cuda(), half()
130
148
  pt = True
131
149
  elif pt: # PyTorch
132
150
  from ultralytics.nn.tasks import attempt_load_weights
133
- model = attempt_load_weights(weights if isinstance(weights, list) else w,
134
- device=device,
135
- inplace=True,
136
- fuse=fuse)
137
- if hasattr(model, 'kpt_shape'):
151
+
152
+ model = attempt_load_weights(
153
+ weights if isinstance(weights, list) else w, device=device, inplace=True, fuse=fuse
154
+ )
155
+ if hasattr(model, "kpt_shape"):
138
156
  kpt_shape = model.kpt_shape # pose-only
139
157
  stride = max(int(model.stride.max()), 32) # model stride
140
- names = model.module.names if hasattr(model, 'module') else model.names # get class names
158
+ names = model.module.names if hasattr(model, "module") else model.names # get class names
141
159
  model.half() if fp16 else model.float()
142
160
  self.model = model # explicitly assign for to(), cpu(), cuda(), half()
143
161
  elif jit: # TorchScript
144
- LOGGER.info(f'Loading {w} for TorchScript inference...')
145
- extra_files = {'config.txt': ''} # model metadata
162
+ LOGGER.info(f"Loading {w} for TorchScript inference...")
163
+ extra_files = {"config.txt": ""} # model metadata
146
164
  model = torch.jit.load(w, _extra_files=extra_files, map_location=device)
147
165
  model.half() if fp16 else model.float()
148
- if extra_files['config.txt']: # load metadata dict
149
- metadata = json.loads(extra_files['config.txt'], object_hook=lambda x: dict(x.items()))
166
+ if extra_files["config.txt"]: # load metadata dict
167
+ metadata = json.loads(extra_files["config.txt"], object_hook=lambda x: dict(x.items()))
150
168
  elif dnn: # ONNX OpenCV DNN
151
- LOGGER.info(f'Loading {w} for ONNX OpenCV DNN inference...')
152
- check_requirements('opencv-python>=4.5.4')
169
+ LOGGER.info(f"Loading {w} for ONNX OpenCV DNN inference...")
170
+ check_requirements("opencv-python>=4.5.4")
153
171
  net = cv2.dnn.readNetFromONNX(w)
154
172
  elif onnx: # ONNX Runtime
155
- LOGGER.info(f'Loading {w} for ONNX Runtime inference...')
156
- check_requirements(('onnx', 'onnxruntime-gpu' if cuda else 'onnxruntime'))
173
+ LOGGER.info(f"Loading {w} for ONNX Runtime inference...")
174
+ check_requirements(("onnx", "onnxruntime-gpu" if cuda else "onnxruntime"))
157
175
  import onnxruntime
158
- providers = ['CUDAExecutionProvider', 'CPUExecutionProvider'] if cuda else ['CPUExecutionProvider']
176
+
177
+ providers = ["CUDAExecutionProvider", "CPUExecutionProvider"] if cuda else ["CPUExecutionProvider"]
159
178
  session = onnxruntime.InferenceSession(w, providers=providers)
160
179
  output_names = [x.name for x in session.get_outputs()]
161
180
  metadata = session.get_modelmeta().custom_metadata_map # metadata
162
181
  elif xml: # OpenVINO
163
- LOGGER.info(f'Loading {w} for OpenVINO inference...')
164
- check_requirements('openvino>=2023.0') # requires openvino-dev: https://pypi.org/project/openvino-dev/
182
+ LOGGER.info(f"Loading {w} for OpenVINO inference...")
183
+ check_requirements("openvino>=2023.0") # requires openvino-dev: https://pypi.org/project/openvino-dev/
165
184
  from openvino.runtime import Core, Layout, get_batch # noqa
185
+
166
186
  core = Core()
167
187
  w = Path(w)
168
188
  if not w.is_file(): # if not *.xml
169
- w = next(w.glob('*.xml')) # get *.xml file from *_openvino_model dir
170
- ov_model = core.read_model(model=str(w), weights=w.with_suffix('.bin'))
189
+ w = next(w.glob("*.xml")) # get *.xml file from *_openvino_model dir
190
+ ov_model = core.read_model(model=str(w), weights=w.with_suffix(".bin"))
171
191
  if ov_model.get_parameters()[0].get_layout().empty:
172
- ov_model.get_parameters()[0].set_layout(Layout('NCHW'))
192
+ ov_model.get_parameters()[0].set_layout(Layout("NCHW"))
173
193
  batch_dim = get_batch(ov_model)
174
194
  if batch_dim.is_static:
175
195
  batch_size = batch_dim.get_length()
176
- ov_compiled_model = core.compile_model(ov_model, device_name='AUTO') # AUTO selects best available device
177
- metadata = w.parent / 'metadata.yaml'
196
+ ov_compiled_model = core.compile_model(ov_model, device_name="AUTO") # AUTO selects best available device
197
+ metadata = w.parent / "metadata.yaml"
178
198
  elif engine: # TensorRT
179
- LOGGER.info(f'Loading {w} for TensorRT inference...')
199
+ LOGGER.info(f"Loading {w} for TensorRT inference...")
180
200
  try:
181
201
  import tensorrt as trt # noqa https://developer.nvidia.com/nvidia-tensorrt-download
182
202
  except ImportError:
183
203
  if LINUX:
184
- check_requirements('nvidia-tensorrt', cmds='-U --index-url https://pypi.ngc.nvidia.com')
204
+ check_requirements("nvidia-tensorrt", cmds="-U --index-url https://pypi.ngc.nvidia.com")
185
205
  import tensorrt as trt # noqa
186
- check_version(trt.__version__, '7.0.0', hard=True) # require tensorrt>=7.0.0
187
- if device.type == 'cpu':
188
- device = torch.device('cuda:0')
189
- Binding = namedtuple('Binding', ('name', 'dtype', 'shape', 'data', 'ptr'))
206
+ check_version(trt.__version__, "7.0.0", hard=True) # require tensorrt>=7.0.0
207
+ if device.type == "cpu":
208
+ device = torch.device("cuda:0")
209
+ Binding = namedtuple("Binding", ("name", "dtype", "shape", "data", "ptr"))
190
210
  logger = trt.Logger(trt.Logger.INFO)
191
211
  # Read file
192
- with open(w, 'rb') as f, trt.Runtime(logger) as runtime:
193
- meta_len = int.from_bytes(f.read(4), byteorder='little') # read metadata length
194
- metadata = json.loads(f.read(meta_len).decode('utf-8')) # read metadata
212
+ with open(w, "rb") as f, trt.Runtime(logger) as runtime:
213
+ meta_len = int.from_bytes(f.read(4), byteorder="little") # read metadata length
214
+ metadata = json.loads(f.read(meta_len).decode("utf-8")) # read metadata
195
215
  model = runtime.deserialize_cuda_engine(f.read()) # read engine
196
216
  context = model.create_execution_context()
197
217
  bindings = OrderedDict()
@@ -213,116 +233,124 @@ class AutoBackend(nn.Module):
213
233
  im = torch.from_numpy(np.empty(shape, dtype=dtype)).to(device)
214
234
  bindings[name] = Binding(name, dtype, shape, im, int(im.data_ptr()))
215
235
  binding_addrs = OrderedDict((n, d.ptr) for n, d in bindings.items())
216
- batch_size = bindings['images'].shape[0] # if dynamic, this is instead max batch size
236
+ batch_size = bindings["images"].shape[0] # if dynamic, this is instead max batch size
217
237
  elif coreml: # CoreML
218
- LOGGER.info(f'Loading {w} for CoreML inference...')
238
+ LOGGER.info(f"Loading {w} for CoreML inference...")
219
239
  import coremltools as ct
240
+
220
241
  model = ct.models.MLModel(w)
221
242
  metadata = dict(model.user_defined_metadata)
222
243
  elif saved_model: # TF SavedModel
223
- LOGGER.info(f'Loading {w} for TensorFlow SavedModel inference...')
244
+ LOGGER.info(f"Loading {w} for TensorFlow SavedModel inference...")
224
245
  import tensorflow as tf
246
+
225
247
  keras = False # assume TF1 saved_model
226
248
  model = tf.keras.models.load_model(w) if keras else tf.saved_model.load(w)
227
- metadata = Path(w) / 'metadata.yaml'
249
+ metadata = Path(w) / "metadata.yaml"
228
250
  elif pb: # GraphDef https://www.tensorflow.org/guide/migrate#a_graphpb_or_graphpbtxt
229
- LOGGER.info(f'Loading {w} for TensorFlow GraphDef inference...')
251
+ LOGGER.info(f"Loading {w} for TensorFlow GraphDef inference...")
230
252
  import tensorflow as tf
231
253
 
232
254
  from ultralytics.engine.exporter import gd_outputs
233
255
 
234
256
  def wrap_frozen_graph(gd, inputs, outputs):
235
257
  """Wrap frozen graphs for deployment."""
236
- x = tf.compat.v1.wrap_function(lambda: tf.compat.v1.import_graph_def(gd, name=''), []) # wrapped
258
+ x = tf.compat.v1.wrap_function(lambda: tf.compat.v1.import_graph_def(gd, name=""), []) # wrapped
237
259
  ge = x.graph.as_graph_element
238
260
  return x.prune(tf.nest.map_structure(ge, inputs), tf.nest.map_structure(ge, outputs))
239
261
 
240
262
  gd = tf.Graph().as_graph_def() # TF GraphDef
241
- with open(w, 'rb') as f:
263
+ with open(w, "rb") as f:
242
264
  gd.ParseFromString(f.read())
243
- frozen_func = wrap_frozen_graph(gd, inputs='x:0', outputs=gd_outputs(gd))
265
+ frozen_func = wrap_frozen_graph(gd, inputs="x:0", outputs=gd_outputs(gd))
244
266
  elif tflite or edgetpu: # https://www.tensorflow.org/lite/guide/python#install_tensorflow_lite_for_python
245
267
  try: # https://coral.ai/docs/edgetpu/tflite-python/#update-existing-tf-lite-code-for-the-edge-tpu
246
268
  from tflite_runtime.interpreter import Interpreter, load_delegate
247
269
  except ImportError:
248
270
  import tensorflow as tf
271
+
249
272
  Interpreter, load_delegate = tf.lite.Interpreter, tf.lite.experimental.load_delegate
250
273
  if edgetpu: # TF Edge TPU https://coral.ai/software/#edgetpu-runtime
251
- LOGGER.info(f'Loading {w} for TensorFlow Lite Edge TPU inference...')
252
- delegate = {
253
- 'Linux': 'libedgetpu.so.1',
254
- 'Darwin': 'libedgetpu.1.dylib',
255
- 'Windows': 'edgetpu.dll'}[platform.system()]
274
+ LOGGER.info(f"Loading {w} for TensorFlow Lite Edge TPU inference...")
275
+ delegate = {"Linux": "libedgetpu.so.1", "Darwin": "libedgetpu.1.dylib", "Windows": "edgetpu.dll"}[
276
+ platform.system()
277
+ ]
256
278
  interpreter = Interpreter(model_path=w, experimental_delegates=[load_delegate(delegate)])
257
279
  else: # TFLite
258
- LOGGER.info(f'Loading {w} for TensorFlow Lite inference...')
280
+ LOGGER.info(f"Loading {w} for TensorFlow Lite inference...")
259
281
  interpreter = Interpreter(model_path=w) # load TFLite model
260
282
  interpreter.allocate_tensors() # allocate
261
283
  input_details = interpreter.get_input_details() # inputs
262
284
  output_details = interpreter.get_output_details() # outputs
263
285
  # Load metadata
264
286
  with contextlib.suppress(zipfile.BadZipFile):
265
- with zipfile.ZipFile(w, 'r') as model:
287
+ with zipfile.ZipFile(w, "r") as model:
266
288
  meta_file = model.namelist()[0]
267
- metadata = ast.literal_eval(model.read(meta_file).decode('utf-8'))
289
+ metadata = ast.literal_eval(model.read(meta_file).decode("utf-8"))
268
290
  elif tfjs: # TF.js
269
- raise NotImplementedError('YOLOv8 TF.js inference is not currently supported.')
291
+ raise NotImplementedError("YOLOv8 TF.js inference is not currently supported.")
270
292
  elif paddle: # PaddlePaddle
271
- LOGGER.info(f'Loading {w} for PaddlePaddle inference...')
272
- check_requirements('paddlepaddle-gpu' if cuda else 'paddlepaddle')
293
+ LOGGER.info(f"Loading {w} for PaddlePaddle inference...")
294
+ check_requirements("paddlepaddle-gpu" if cuda else "paddlepaddle")
273
295
  import paddle.inference as pdi # noqa
296
+
274
297
  w = Path(w)
275
298
  if not w.is_file(): # if not *.pdmodel
276
- w = next(w.rglob('*.pdmodel')) # get *.pdmodel file from *_paddle_model dir
277
- config = pdi.Config(str(w), str(w.with_suffix('.pdiparams')))
299
+ w = next(w.rglob("*.pdmodel")) # get *.pdmodel file from *_paddle_model dir
300
+ config = pdi.Config(str(w), str(w.with_suffix(".pdiparams")))
278
301
  if cuda:
279
302
  config.enable_use_gpu(memory_pool_init_size_mb=2048, device_id=0)
280
303
  predictor = pdi.create_predictor(config)
281
304
  input_handle = predictor.get_input_handle(predictor.get_input_names()[0])
282
305
  output_names = predictor.get_output_names()
283
- metadata = w.parents[1] / 'metadata.yaml'
306
+ metadata = w.parents[1] / "metadata.yaml"
284
307
  elif ncnn: # ncnn
285
- LOGGER.info(f'Loading {w} for ncnn inference...')
286
- check_requirements('git+https://github.com/Tencent/ncnn.git' if ARM64 else 'ncnn') # requires ncnn
308
+ LOGGER.info(f"Loading {w} for ncnn inference...")
309
+ check_requirements("git+https://github.com/Tencent/ncnn.git" if ARM64 else "ncnn") # requires ncnn
287
310
  import ncnn as pyncnn
311
+
288
312
  net = pyncnn.Net()
289
313
  net.opt.use_vulkan_compute = cuda
290
314
  w = Path(w)
291
315
  if not w.is_file(): # if not *.param
292
- w = next(w.glob('*.param')) # get *.param file from *_ncnn_model dir
316
+ w = next(w.glob("*.param")) # get *.param file from *_ncnn_model dir
293
317
  net.load_param(str(w))
294
- net.load_model(str(w.with_suffix('.bin')))
295
- metadata = w.parent / 'metadata.yaml'
318
+ net.load_model(str(w.with_suffix(".bin")))
319
+ metadata = w.parent / "metadata.yaml"
296
320
  elif triton: # NVIDIA Triton Inference Server
297
- check_requirements('tritonclient[all]')
321
+ check_requirements("tritonclient[all]")
298
322
  from ultralytics.utils.triton import TritonRemoteModel
323
+
299
324
  model = TritonRemoteModel(w)
300
325
  else:
301
326
  from ultralytics.engine.exporter import export_formats
302
- raise TypeError(f"model='{w}' is not a supported model format. "
303
- 'See https://docs.ultralytics.com/modes/predict for help.'
304
- f'\n\n{export_formats()}')
327
+
328
+ raise TypeError(
329
+ f"model='{w}' is not a supported model format. "
330
+ "See https://docs.ultralytics.com/modes/predict for help."
331
+ f"\n\n{export_formats()}"
332
+ )
305
333
 
306
334
  # Load external metadata YAML
307
335
  if isinstance(metadata, (str, Path)) and Path(metadata).exists():
308
336
  metadata = yaml_load(metadata)
309
337
  if metadata:
310
338
  for k, v in metadata.items():
311
- if k in ('stride', 'batch'):
339
+ if k in ("stride", "batch"):
312
340
  metadata[k] = int(v)
313
- elif k in ('imgsz', 'names', 'kpt_shape') and isinstance(v, str):
341
+ elif k in ("imgsz", "names", "kpt_shape") and isinstance(v, str):
314
342
  metadata[k] = eval(v)
315
- stride = metadata['stride']
316
- task = metadata['task']
317
- batch = metadata['batch']
318
- imgsz = metadata['imgsz']
319
- names = metadata['names']
320
- kpt_shape = metadata.get('kpt_shape')
343
+ stride = metadata["stride"]
344
+ task = metadata["task"]
345
+ batch = metadata["batch"]
346
+ imgsz = metadata["imgsz"]
347
+ names = metadata["names"]
348
+ kpt_shape = metadata.get("kpt_shape")
321
349
  elif not (pt or triton or nn_module):
322
350
  LOGGER.warning(f"WARNING ⚠️ Metadata not found for 'model={weights}'")
323
351
 
324
352
  # Check names
325
- if 'names' not in locals(): # names missing
353
+ if "names" not in locals(): # names missing
326
354
  names = default_class_names(data)
327
355
  names = check_class_names(names)
328
356
 
@@ -367,26 +395,28 @@ class AutoBackend(nn.Module):
367
395
  im = im.cpu().numpy() # FP32
368
396
  y = list(self.ov_compiled_model(im).values())
369
397
  elif self.engine: # TensorRT
370
- if self.dynamic and im.shape != self.bindings['images'].shape:
371
- i = self.model.get_binding_index('images')
398
+ if self.dynamic and im.shape != self.bindings["images"].shape:
399
+ i = self.model.get_binding_index("images")
372
400
  self.context.set_binding_shape(i, im.shape) # reshape if dynamic
373
- self.bindings['images'] = self.bindings['images']._replace(shape=im.shape)
401
+ self.bindings["images"] = self.bindings["images"]._replace(shape=im.shape)
374
402
  for name in self.output_names:
375
403
  i = self.model.get_binding_index(name)
376
404
  self.bindings[name].data.resize_(tuple(self.context.get_binding_shape(i)))
377
- s = self.bindings['images'].shape
405
+ s = self.bindings["images"].shape
378
406
  assert im.shape == s, f"input size {im.shape} {'>' if self.dynamic else 'not equal to'} max model size {s}"
379
- self.binding_addrs['images'] = int(im.data_ptr())
407
+ self.binding_addrs["images"] = int(im.data_ptr())
380
408
  self.context.execute_v2(list(self.binding_addrs.values()))
381
409
  y = [self.bindings[x].data for x in sorted(self.output_names)]
382
410
  elif self.coreml: # CoreML
383
411
  im = im[0].cpu().numpy()
384
- im_pil = Image.fromarray((im * 255).astype('uint8'))
412
+ im_pil = Image.fromarray((im * 255).astype("uint8"))
385
413
  # im = im.resize((192, 320), Image.BILINEAR)
386
- y = self.model.predict({'image': im_pil}) # coordinates are xywh normalized
387
- if 'confidence' in y:
388
- raise TypeError('Ultralytics only supports inference of non-pipelined CoreML models exported with '
389
- f"'nms=False', but 'model={w}' has an NMS pipeline created by an 'nms=True' export.")
414
+ y = self.model.predict({"image": im_pil}) # coordinates are xywh normalized
415
+ if "confidence" in y:
416
+ raise TypeError(
417
+ "Ultralytics only supports inference of non-pipelined CoreML models exported with "
418
+ f"'nms=False', but 'model={w}' has an NMS pipeline created by an 'nms=True' export."
419
+ )
390
420
  # TODO: CoreML NMS inference handling
391
421
  # from ultralytics.utils.ops import xywh2xyxy
392
422
  # box = xywh2xyxy(y['coordinates'] * [[w, h, w, h]]) # xyxy pixels
@@ -425,20 +455,20 @@ class AutoBackend(nn.Module):
425
455
  if len(y) == 2 and len(self.names) == 999: # segments and names not defined
426
456
  ip, ib = (0, 1) if len(y[0].shape) == 4 else (1, 0) # index of protos, boxes
427
457
  nc = y[ib].shape[1] - y[ip].shape[3] - 4 # y = (1, 160, 160, 32), (1, 116, 8400)
428
- self.names = {i: f'class{i}' for i in range(nc)}
458
+ self.names = {i: f"class{i}" for i in range(nc)}
429
459
  else: # Lite or Edge TPU
430
460
  details = self.input_details[0]
431
- integer = details['dtype'] in (np.int8, np.int16) # is TFLite quantized int8 or int16 model
461
+ integer = details["dtype"] in (np.int8, np.int16) # is TFLite quantized int8 or int16 model
432
462
  if integer:
433
- scale, zero_point = details['quantization']
434
- im = (im / scale + zero_point).astype(details['dtype']) # de-scale
435
- self.interpreter.set_tensor(details['index'], im)
463
+ scale, zero_point = details["quantization"]
464
+ im = (im / scale + zero_point).astype(details["dtype"]) # de-scale
465
+ self.interpreter.set_tensor(details["index"], im)
436
466
  self.interpreter.invoke()
437
467
  y = []
438
468
  for output in self.output_details:
439
- x = self.interpreter.get_tensor(output['index'])
469
+ x = self.interpreter.get_tensor(output["index"])
440
470
  if integer:
441
- scale, zero_point = output['quantization']
471
+ scale, zero_point = output["quantization"]
442
472
  x = (x.astype(np.float32) - zero_point) * scale # re-scale
443
473
  if x.ndim > 2: # if task is not classification
444
474
  # Denormalize xywh by image size. See https://github.com/ultralytics/ultralytics/pull/1695
@@ -483,13 +513,13 @@ class AutoBackend(nn.Module):
483
513
  (None): This method runs the forward pass and don't return any value
484
514
  """
485
515
  warmup_types = self.pt, self.jit, self.onnx, self.engine, self.saved_model, self.pb, self.triton, self.nn_module
486
- if any(warmup_types) and (self.device.type != 'cpu' or self.triton):
516
+ if any(warmup_types) and (self.device.type != "cpu" or self.triton):
487
517
  im = torch.empty(*imgsz, dtype=torch.half if self.fp16 else torch.float, device=self.device) # input
488
518
  for _ in range(2 if self.jit else 1):
489
519
  self.forward(im) # warmup
490
520
 
491
521
  @staticmethod
492
- def _model_type(p='path/to/model.pt'):
522
+ def _model_type(p="path/to/model.pt"):
493
523
  """
494
524
  This function takes a path to a model file and returns the model type.
495
525
 
@@ -499,18 +529,20 @@ class AutoBackend(nn.Module):
499
529
  # Return model type from model path, i.e. path='path/to/model.onnx' -> type=onnx
500
530
  # types = [pt, jit, onnx, xml, engine, coreml, saved_model, pb, tflite, edgetpu, tfjs, paddle]
501
531
  from ultralytics.engine.exporter import export_formats
532
+
502
533
  sf = list(export_formats().Suffix) # export suffixes
503
534
  if not is_url(p, check=False) and not isinstance(p, str):
504
535
  check_suffix(p, sf) # checks
505
536
  name = Path(p).name
506
537
  types = [s in name for s in sf]
507
- types[5] |= name.endswith('.mlmodel') # retain support for older Apple CoreML *.mlmodel formats
538
+ types[5] |= name.endswith(".mlmodel") # retain support for older Apple CoreML *.mlmodel formats
508
539
  types[8] &= not types[9] # tflite &= not edgetpu
509
540
  if any(types):
510
541
  triton = False
511
542
  else:
512
543
  from urllib.parse import urlsplit
544
+
513
545
  url = urlsplit(p)
514
- triton = url.netloc and url.path and url.scheme in {'http', 'grpc'}
546
+ triton = url.netloc and url.path and url.scheme in {"http", "grpc"}
515
547
 
516
548
  return types + [triton]
@@ -17,18 +17,101 @@ Example:
17
17
  ```
18
18
  """
19
19
 
20
- from .block import (C1, C2, C3, C3TR, DFL, SPP, SPPF, Bottleneck, BottleneckCSP, C2f, C3Ghost, C3x, GhostBottleneck,
21
- HGBlock, HGStem, Proto, RepC3, ResNetLayer)
22
- from .conv import (CBAM, ChannelAttention, Concat, Conv, Conv2, ConvTranspose, DWConv, DWConvTranspose2d, Focus,
23
- GhostConv, LightConv, RepConv, SpatialAttention)
20
+ from .block import (
21
+ C1,
22
+ C2,
23
+ C3,
24
+ C3TR,
25
+ DFL,
26
+ SPP,
27
+ SPPF,
28
+ Bottleneck,
29
+ BottleneckCSP,
30
+ C2f,
31
+ C3Ghost,
32
+ C3x,
33
+ GhostBottleneck,
34
+ HGBlock,
35
+ HGStem,
36
+ Proto,
37
+ RepC3,
38
+ ResNetLayer,
39
+ )
40
+ from .conv import (
41
+ CBAM,
42
+ ChannelAttention,
43
+ Concat,
44
+ Conv,
45
+ Conv2,
46
+ ConvTranspose,
47
+ DWConv,
48
+ DWConvTranspose2d,
49
+ Focus,
50
+ GhostConv,
51
+ LightConv,
52
+ RepConv,
53
+ SpatialAttention,
54
+ )
24
55
  from .head import OBB, Classify, Detect, Pose, RTDETRDecoder, Segment
25
- from .transformer import (AIFI, MLP, DeformableTransformerDecoder, DeformableTransformerDecoderLayer, LayerNorm2d,
26
- MLPBlock, MSDeformAttn, TransformerBlock, TransformerEncoderLayer, TransformerLayer)
56
+ from .transformer import (
57
+ AIFI,
58
+ MLP,
59
+ DeformableTransformerDecoder,
60
+ DeformableTransformerDecoderLayer,
61
+ LayerNorm2d,
62
+ MLPBlock,
63
+ MSDeformAttn,
64
+ TransformerBlock,
65
+ TransformerEncoderLayer,
66
+ TransformerLayer,
67
+ )
27
68
 
28
- __all__ = ('Conv', 'Conv2', 'LightConv', 'RepConv', 'DWConv', 'DWConvTranspose2d', 'ConvTranspose', 'Focus',
29
- 'GhostConv', 'ChannelAttention', 'SpatialAttention', 'CBAM', 'Concat', 'TransformerLayer',
30
- 'TransformerBlock', 'MLPBlock', 'LayerNorm2d', 'DFL', 'HGBlock', 'HGStem', 'SPP', 'SPPF', 'C1', 'C2', 'C3',
31
- 'C2f', 'C3x', 'C3TR', 'C3Ghost', 'GhostBottleneck', 'Bottleneck', 'BottleneckCSP', 'Proto', 'Detect',
32
- 'Segment', 'Pose', 'Classify', 'TransformerEncoderLayer', 'RepC3', 'RTDETRDecoder', 'AIFI',
33
- 'DeformableTransformerDecoder', 'DeformableTransformerDecoderLayer', 'MSDeformAttn', 'MLP', 'ResNetLayer',
34
- 'OBB')
69
+ __all__ = (
70
+ "Conv",
71
+ "Conv2",
72
+ "LightConv",
73
+ "RepConv",
74
+ "DWConv",
75
+ "DWConvTranspose2d",
76
+ "ConvTranspose",
77
+ "Focus",
78
+ "GhostConv",
79
+ "ChannelAttention",
80
+ "SpatialAttention",
81
+ "CBAM",
82
+ "Concat",
83
+ "TransformerLayer",
84
+ "TransformerBlock",
85
+ "MLPBlock",
86
+ "LayerNorm2d",
87
+ "DFL",
88
+ "HGBlock",
89
+ "HGStem",
90
+ "SPP",
91
+ "SPPF",
92
+ "C1",
93
+ "C2",
94
+ "C3",
95
+ "C2f",
96
+ "C3x",
97
+ "C3TR",
98
+ "C3Ghost",
99
+ "GhostBottleneck",
100
+ "Bottleneck",
101
+ "BottleneckCSP",
102
+ "Proto",
103
+ "Detect",
104
+ "Segment",
105
+ "Pose",
106
+ "Classify",
107
+ "TransformerEncoderLayer",
108
+ "RepC3",
109
+ "RTDETRDecoder",
110
+ "AIFI",
111
+ "DeformableTransformerDecoder",
112
+ "DeformableTransformerDecoderLayer",
113
+ "MSDeformAttn",
114
+ "MLP",
115
+ "ResNetLayer",
116
+ "OBB",
117
+ )