ultralytics 8.0.238__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 (134) hide show
  1. ultralytics/__init__.py +2 -2
  2. ultralytics/cfg/__init__.py +241 -138
  3. ultralytics/data/__init__.py +9 -2
  4. ultralytics/data/annotator.py +4 -4
  5. ultralytics/data/augment.py +186 -169
  6. ultralytics/data/base.py +54 -48
  7. ultralytics/data/build.py +34 -23
  8. ultralytics/data/converter.py +242 -70
  9. ultralytics/data/dataset.py +117 -95
  10. ultralytics/data/explorer/__init__.py +3 -1
  11. ultralytics/data/explorer/explorer.py +120 -100
  12. ultralytics/data/explorer/gui/__init__.py +1 -0
  13. ultralytics/data/explorer/gui/dash.py +123 -89
  14. ultralytics/data/explorer/utils.py +37 -39
  15. ultralytics/data/loaders.py +75 -62
  16. ultralytics/data/split_dota.py +44 -36
  17. ultralytics/data/utils.py +160 -142
  18. ultralytics/engine/exporter.py +348 -292
  19. ultralytics/engine/model.py +102 -66
  20. ultralytics/engine/predictor.py +74 -55
  21. ultralytics/engine/results.py +61 -41
  22. ultralytics/engine/trainer.py +192 -144
  23. ultralytics/engine/tuner.py +66 -59
  24. ultralytics/engine/validator.py +31 -26
  25. ultralytics/hub/__init__.py +54 -31
  26. ultralytics/hub/auth.py +28 -25
  27. ultralytics/hub/session.py +282 -133
  28. ultralytics/hub/utils.py +64 -42
  29. ultralytics/models/__init__.py +1 -1
  30. ultralytics/models/fastsam/__init__.py +1 -1
  31. ultralytics/models/fastsam/model.py +6 -6
  32. ultralytics/models/fastsam/predict.py +3 -2
  33. ultralytics/models/fastsam/prompt.py +55 -48
  34. ultralytics/models/fastsam/val.py +1 -1
  35. ultralytics/models/nas/__init__.py +1 -1
  36. ultralytics/models/nas/model.py +9 -8
  37. ultralytics/models/nas/predict.py +8 -6
  38. ultralytics/models/nas/val.py +11 -9
  39. ultralytics/models/rtdetr/__init__.py +1 -1
  40. ultralytics/models/rtdetr/model.py +11 -9
  41. ultralytics/models/rtdetr/train.py +18 -16
  42. ultralytics/models/rtdetr/val.py +25 -19
  43. ultralytics/models/sam/__init__.py +1 -1
  44. ultralytics/models/sam/amg.py +13 -14
  45. ultralytics/models/sam/build.py +44 -42
  46. ultralytics/models/sam/model.py +6 -6
  47. ultralytics/models/sam/modules/decoders.py +6 -4
  48. ultralytics/models/sam/modules/encoders.py +37 -35
  49. ultralytics/models/sam/modules/sam.py +5 -4
  50. ultralytics/models/sam/modules/tiny_encoder.py +95 -73
  51. ultralytics/models/sam/modules/transformer.py +3 -2
  52. ultralytics/models/sam/predict.py +39 -27
  53. ultralytics/models/utils/loss.py +99 -95
  54. ultralytics/models/utils/ops.py +34 -31
  55. ultralytics/models/yolo/__init__.py +1 -1
  56. ultralytics/models/yolo/classify/__init__.py +1 -1
  57. ultralytics/models/yolo/classify/predict.py +8 -6
  58. ultralytics/models/yolo/classify/train.py +37 -31
  59. ultralytics/models/yolo/classify/val.py +26 -24
  60. ultralytics/models/yolo/detect/__init__.py +1 -1
  61. ultralytics/models/yolo/detect/predict.py +8 -6
  62. ultralytics/models/yolo/detect/train.py +47 -37
  63. ultralytics/models/yolo/detect/val.py +100 -82
  64. ultralytics/models/yolo/model.py +31 -25
  65. ultralytics/models/yolo/obb/__init__.py +1 -1
  66. ultralytics/models/yolo/obb/predict.py +13 -11
  67. ultralytics/models/yolo/obb/train.py +3 -3
  68. ultralytics/models/yolo/obb/val.py +70 -59
  69. ultralytics/models/yolo/pose/__init__.py +1 -1
  70. ultralytics/models/yolo/pose/predict.py +17 -12
  71. ultralytics/models/yolo/pose/train.py +28 -25
  72. ultralytics/models/yolo/pose/val.py +91 -64
  73. ultralytics/models/yolo/segment/__init__.py +1 -1
  74. ultralytics/models/yolo/segment/predict.py +10 -8
  75. ultralytics/models/yolo/segment/train.py +16 -15
  76. ultralytics/models/yolo/segment/val.py +90 -68
  77. ultralytics/nn/__init__.py +26 -6
  78. ultralytics/nn/autobackend.py +144 -112
  79. ultralytics/nn/modules/__init__.py +96 -13
  80. ultralytics/nn/modules/block.py +28 -7
  81. ultralytics/nn/modules/conv.py +41 -23
  82. ultralytics/nn/modules/head.py +60 -52
  83. ultralytics/nn/modules/transformer.py +49 -32
  84. ultralytics/nn/modules/utils.py +20 -15
  85. ultralytics/nn/tasks.py +215 -141
  86. ultralytics/solutions/ai_gym.py +59 -47
  87. ultralytics/solutions/distance_calculation.py +17 -14
  88. ultralytics/solutions/heatmap.py +57 -55
  89. ultralytics/solutions/object_counter.py +46 -39
  90. ultralytics/solutions/speed_estimation.py +13 -16
  91. ultralytics/trackers/__init__.py +1 -1
  92. ultralytics/trackers/basetrack.py +1 -0
  93. ultralytics/trackers/bot_sort.py +2 -1
  94. ultralytics/trackers/byte_tracker.py +10 -7
  95. ultralytics/trackers/track.py +7 -7
  96. ultralytics/trackers/utils/gmc.py +25 -25
  97. ultralytics/trackers/utils/kalman_filter.py +85 -42
  98. ultralytics/trackers/utils/matching.py +8 -7
  99. ultralytics/utils/__init__.py +173 -152
  100. ultralytics/utils/autobatch.py +10 -10
  101. ultralytics/utils/benchmarks.py +76 -86
  102. ultralytics/utils/callbacks/__init__.py +1 -1
  103. ultralytics/utils/callbacks/base.py +29 -29
  104. ultralytics/utils/callbacks/clearml.py +51 -43
  105. ultralytics/utils/callbacks/comet.py +81 -66
  106. ultralytics/utils/callbacks/dvc.py +33 -26
  107. ultralytics/utils/callbacks/hub.py +44 -26
  108. ultralytics/utils/callbacks/mlflow.py +31 -24
  109. ultralytics/utils/callbacks/neptune.py +35 -25
  110. ultralytics/utils/callbacks/raytune.py +9 -4
  111. ultralytics/utils/callbacks/tensorboard.py +16 -11
  112. ultralytics/utils/callbacks/wb.py +39 -33
  113. ultralytics/utils/checks.py +189 -141
  114. ultralytics/utils/dist.py +15 -12
  115. ultralytics/utils/downloads.py +112 -96
  116. ultralytics/utils/errors.py +1 -1
  117. ultralytics/utils/files.py +11 -11
  118. ultralytics/utils/instance.py +22 -22
  119. ultralytics/utils/loss.py +117 -67
  120. ultralytics/utils/metrics.py +224 -158
  121. ultralytics/utils/ops.py +38 -28
  122. ultralytics/utils/patches.py +3 -3
  123. ultralytics/utils/plotting.py +217 -120
  124. ultralytics/utils/tal.py +19 -13
  125. ultralytics/utils/torch_utils.py +138 -109
  126. ultralytics/utils/triton.py +12 -10
  127. ultralytics/utils/tuner.py +49 -47
  128. {ultralytics-8.0.238.dist-info → ultralytics-8.0.239.dist-info}/METADATA +2 -1
  129. ultralytics-8.0.239.dist-info/RECORD +188 -0
  130. ultralytics-8.0.238.dist-info/RECORD +0 -188
  131. {ultralytics-8.0.238.dist-info → ultralytics-8.0.239.dist-info}/LICENSE +0 -0
  132. {ultralytics-8.0.238.dist-info → ultralytics-8.0.239.dist-info}/WHEEL +0 -0
  133. {ultralytics-8.0.238.dist-info → ultralytics-8.0.239.dist-info}/entry_points.txt +0 -0
  134. {ultralytics-8.0.238.dist-info → ultralytics-8.0.239.dist-info}/top_level.txt +0 -0
@@ -20,10 +20,98 @@ def coco91_to_coco80_class():
20
20
  corresponding 91-index class ID.
21
21
  """
22
22
  return [
23
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, None, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, None, 24, 25, None,
24
- None, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, None, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
25
- 51, 52, 53, 54, 55, 56, 57, 58, 59, None, 60, None, None, 61, None, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
26
- None, 73, 74, 75, 76, 77, 78, 79, None]
23
+ 0,
24
+ 1,
25
+ 2,
26
+ 3,
27
+ 4,
28
+ 5,
29
+ 6,
30
+ 7,
31
+ 8,
32
+ 9,
33
+ 10,
34
+ None,
35
+ 11,
36
+ 12,
37
+ 13,
38
+ 14,
39
+ 15,
40
+ 16,
41
+ 17,
42
+ 18,
43
+ 19,
44
+ 20,
45
+ 21,
46
+ 22,
47
+ 23,
48
+ None,
49
+ 24,
50
+ 25,
51
+ None,
52
+ None,
53
+ 26,
54
+ 27,
55
+ 28,
56
+ 29,
57
+ 30,
58
+ 31,
59
+ 32,
60
+ 33,
61
+ 34,
62
+ 35,
63
+ 36,
64
+ 37,
65
+ 38,
66
+ 39,
67
+ None,
68
+ 40,
69
+ 41,
70
+ 42,
71
+ 43,
72
+ 44,
73
+ 45,
74
+ 46,
75
+ 47,
76
+ 48,
77
+ 49,
78
+ 50,
79
+ 51,
80
+ 52,
81
+ 53,
82
+ 54,
83
+ 55,
84
+ 56,
85
+ 57,
86
+ 58,
87
+ 59,
88
+ None,
89
+ 60,
90
+ None,
91
+ None,
92
+ 61,
93
+ None,
94
+ 62,
95
+ 63,
96
+ 64,
97
+ 65,
98
+ 66,
99
+ 67,
100
+ 68,
101
+ 69,
102
+ 70,
103
+ 71,
104
+ 72,
105
+ None,
106
+ 73,
107
+ 74,
108
+ 75,
109
+ 76,
110
+ 77,
111
+ 78,
112
+ 79,
113
+ None,
114
+ ]
27
115
 
28
116
 
29
117
  def coco80_to_coco91_class():
@@ -42,16 +130,96 @@ def coco80_to_coco91_class():
42
130
  ```
43
131
  """
44
132
  return [
45
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 28, 31, 32, 33, 34,
46
- 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
47
- 64, 65, 67, 70, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 84, 85, 86, 87, 88, 89, 90]
48
-
49
-
50
- def convert_coco(labels_dir='../coco/annotations/',
51
- save_dir='coco_converted/',
52
- use_segments=False,
53
- use_keypoints=False,
54
- cls91to80=True):
133
+ 1,
134
+ 2,
135
+ 3,
136
+ 4,
137
+ 5,
138
+ 6,
139
+ 7,
140
+ 8,
141
+ 9,
142
+ 10,
143
+ 11,
144
+ 13,
145
+ 14,
146
+ 15,
147
+ 16,
148
+ 17,
149
+ 18,
150
+ 19,
151
+ 20,
152
+ 21,
153
+ 22,
154
+ 23,
155
+ 24,
156
+ 25,
157
+ 27,
158
+ 28,
159
+ 31,
160
+ 32,
161
+ 33,
162
+ 34,
163
+ 35,
164
+ 36,
165
+ 37,
166
+ 38,
167
+ 39,
168
+ 40,
169
+ 41,
170
+ 42,
171
+ 43,
172
+ 44,
173
+ 46,
174
+ 47,
175
+ 48,
176
+ 49,
177
+ 50,
178
+ 51,
179
+ 52,
180
+ 53,
181
+ 54,
182
+ 55,
183
+ 56,
184
+ 57,
185
+ 58,
186
+ 59,
187
+ 60,
188
+ 61,
189
+ 62,
190
+ 63,
191
+ 64,
192
+ 65,
193
+ 67,
194
+ 70,
195
+ 72,
196
+ 73,
197
+ 74,
198
+ 75,
199
+ 76,
200
+ 77,
201
+ 78,
202
+ 79,
203
+ 80,
204
+ 81,
205
+ 82,
206
+ 84,
207
+ 85,
208
+ 86,
209
+ 87,
210
+ 88,
211
+ 89,
212
+ 90,
213
+ ]
214
+
215
+
216
+ def convert_coco(
217
+ labels_dir="../coco/annotations/",
218
+ save_dir="coco_converted/",
219
+ use_segments=False,
220
+ use_keypoints=False,
221
+ cls91to80=True,
222
+ ):
55
223
  """
56
224
  Converts COCO dataset annotations to a YOLO annotation format suitable for training YOLO models.
57
225
 
@@ -75,76 +243,78 @@ def convert_coco(labels_dir='../coco/annotations/',
75
243
 
76
244
  # Create dataset directory
77
245
  save_dir = increment_path(save_dir) # increment if save directory already exists
78
- for p in save_dir / 'labels', save_dir / 'images':
246
+ for p in save_dir / "labels", save_dir / "images":
79
247
  p.mkdir(parents=True, exist_ok=True) # make dir
80
248
 
81
249
  # Convert classes
82
250
  coco80 = coco91_to_coco80_class()
83
251
 
84
252
  # Import json
85
- for json_file in sorted(Path(labels_dir).resolve().glob('*.json')):
86
- fn = Path(save_dir) / 'labels' / json_file.stem.replace('instances_', '') # folder name
253
+ for json_file in sorted(Path(labels_dir).resolve().glob("*.json")):
254
+ fn = Path(save_dir) / "labels" / json_file.stem.replace("instances_", "") # folder name
87
255
  fn.mkdir(parents=True, exist_ok=True)
88
256
  with open(json_file) as f:
89
257
  data = json.load(f)
90
258
 
91
259
  # Create image dict
92
- images = {f'{x["id"]:d}': x for x in data['images']}
260
+ images = {f'{x["id"]:d}': x for x in data["images"]}
93
261
  # Create image-annotations dict
94
262
  imgToAnns = defaultdict(list)
95
- for ann in data['annotations']:
96
- imgToAnns[ann['image_id']].append(ann)
263
+ for ann in data["annotations"]:
264
+ imgToAnns[ann["image_id"]].append(ann)
97
265
 
98
266
  # Write labels file
99
- for img_id, anns in TQDM(imgToAnns.items(), desc=f'Annotations {json_file}'):
100
- img = images[f'{img_id:d}']
101
- h, w, f = img['height'], img['width'], img['file_name']
267
+ for img_id, anns in TQDM(imgToAnns.items(), desc=f"Annotations {json_file}"):
268
+ img = images[f"{img_id:d}"]
269
+ h, w, f = img["height"], img["width"], img["file_name"]
102
270
 
103
271
  bboxes = []
104
272
  segments = []
105
273
  keypoints = []
106
274
  for ann in anns:
107
- if ann['iscrowd']:
275
+ if ann["iscrowd"]:
108
276
  continue
109
277
  # The COCO box format is [top left x, top left y, width, height]
110
- box = np.array(ann['bbox'], dtype=np.float64)
278
+ box = np.array(ann["bbox"], dtype=np.float64)
111
279
  box[:2] += box[2:] / 2 # xy top-left corner to center
112
280
  box[[0, 2]] /= w # normalize x
113
281
  box[[1, 3]] /= h # normalize y
114
282
  if box[2] <= 0 or box[3] <= 0: # if w <= 0 and h <= 0
115
283
  continue
116
284
 
117
- cls = coco80[ann['category_id'] - 1] if cls91to80 else ann['category_id'] - 1 # class
285
+ cls = coco80[ann["category_id"] - 1] if cls91to80 else ann["category_id"] - 1 # class
118
286
  box = [cls] + box.tolist()
119
287
  if box not in bboxes:
120
288
  bboxes.append(box)
121
- if use_segments and ann.get('segmentation') is not None:
122
- if len(ann['segmentation']) == 0:
289
+ if use_segments and ann.get("segmentation") is not None:
290
+ if len(ann["segmentation"]) == 0:
123
291
  segments.append([])
124
292
  continue
125
- elif len(ann['segmentation']) > 1:
126
- s = merge_multi_segment(ann['segmentation'])
293
+ elif len(ann["segmentation"]) > 1:
294
+ s = merge_multi_segment(ann["segmentation"])
127
295
  s = (np.concatenate(s, axis=0) / np.array([w, h])).reshape(-1).tolist()
128
296
  else:
129
- s = [j for i in ann['segmentation'] for j in i] # all segments concatenated
297
+ s = [j for i in ann["segmentation"] for j in i] # all segments concatenated
130
298
  s = (np.array(s).reshape(-1, 2) / np.array([w, h])).reshape(-1).tolist()
131
299
  s = [cls] + s
132
300
  segments.append(s)
133
- if use_keypoints and ann.get('keypoints') is not None:
134
- keypoints.append(box + (np.array(ann['keypoints']).reshape(-1, 3) /
135
- np.array([w, h, 1])).reshape(-1).tolist())
301
+ if use_keypoints and ann.get("keypoints") is not None:
302
+ keypoints.append(
303
+ box + (np.array(ann["keypoints"]).reshape(-1, 3) / np.array([w, h, 1])).reshape(-1).tolist()
304
+ )
136
305
 
137
306
  # Write
138
- with open((fn / f).with_suffix('.txt'), 'a') as file:
307
+ with open((fn / f).with_suffix(".txt"), "a") as file:
139
308
  for i in range(len(bboxes)):
140
309
  if use_keypoints:
141
- line = *(keypoints[i]), # cls, box, keypoints
310
+ line = (*(keypoints[i]),) # cls, box, keypoints
142
311
  else:
143
- line = *(segments[i]
144
- if use_segments and len(segments[i]) > 0 else bboxes[i]), # cls, box or segments
145
- file.write(('%g ' * len(line)).rstrip() % line + '\n')
312
+ line = (
313
+ *(segments[i] if use_segments and len(segments[i]) > 0 else bboxes[i]),
314
+ ) # cls, box or segments
315
+ file.write(("%g " * len(line)).rstrip() % line + "\n")
146
316
 
147
- LOGGER.info(f'COCO data converted successfully.\nResults saved to {save_dir.resolve()}')
317
+ LOGGER.info(f"COCO data converted successfully.\nResults saved to {save_dir.resolve()}")
148
318
 
149
319
 
150
320
  def convert_dota_to_yolo_obb(dota_root_path: str):
@@ -184,31 +354,32 @@ def convert_dota_to_yolo_obb(dota_root_path: str):
184
354
 
185
355
  # Class names to indices mapping
186
356
  class_mapping = {
187
- 'plane': 0,
188
- 'ship': 1,
189
- 'storage-tank': 2,
190
- 'baseball-diamond': 3,
191
- 'tennis-court': 4,
192
- 'basketball-court': 5,
193
- 'ground-track-field': 6,
194
- 'harbor': 7,
195
- 'bridge': 8,
196
- 'large-vehicle': 9,
197
- 'small-vehicle': 10,
198
- 'helicopter': 11,
199
- 'roundabout': 12,
200
- 'soccer-ball-field': 13,
201
- 'swimming-pool': 14,
202
- 'container-crane': 15,
203
- 'airport': 16,
204
- 'helipad': 17}
357
+ "plane": 0,
358
+ "ship": 1,
359
+ "storage-tank": 2,
360
+ "baseball-diamond": 3,
361
+ "tennis-court": 4,
362
+ "basketball-court": 5,
363
+ "ground-track-field": 6,
364
+ "harbor": 7,
365
+ "bridge": 8,
366
+ "large-vehicle": 9,
367
+ "small-vehicle": 10,
368
+ "helicopter": 11,
369
+ "roundabout": 12,
370
+ "soccer-ball-field": 13,
371
+ "swimming-pool": 14,
372
+ "container-crane": 15,
373
+ "airport": 16,
374
+ "helipad": 17,
375
+ }
205
376
 
206
377
  def convert_label(image_name, image_width, image_height, orig_label_dir, save_dir):
207
378
  """Converts a single image's DOTA annotation to YOLO OBB format and saves it to a specified directory."""
208
- orig_label_path = orig_label_dir / f'{image_name}.txt'
209
- save_path = save_dir / f'{image_name}.txt'
379
+ orig_label_path = orig_label_dir / f"{image_name}.txt"
380
+ save_path = save_dir / f"{image_name}.txt"
210
381
 
211
- with orig_label_path.open('r') as f, save_path.open('w') as g:
382
+ with orig_label_path.open("r") as f, save_path.open("w") as g:
212
383
  lines = f.readlines()
213
384
  for line in lines:
214
385
  parts = line.strip().split()
@@ -218,20 +389,21 @@ def convert_dota_to_yolo_obb(dota_root_path: str):
218
389
  class_idx = class_mapping[class_name]
219
390
  coords = [float(p) for p in parts[:8]]
220
391
  normalized_coords = [
221
- coords[i] / image_width if i % 2 == 0 else coords[i] / image_height for i in range(8)]
222
- formatted_coords = ['{:.6g}'.format(coord) for coord in normalized_coords]
392
+ coords[i] / image_width if i % 2 == 0 else coords[i] / image_height for i in range(8)
393
+ ]
394
+ formatted_coords = ["{:.6g}".format(coord) for coord in normalized_coords]
223
395
  g.write(f"{class_idx} {' '.join(formatted_coords)}\n")
224
396
 
225
- for phase in ['train', 'val']:
226
- image_dir = dota_root_path / 'images' / phase
227
- orig_label_dir = dota_root_path / 'labels' / f'{phase}_original'
228
- save_dir = dota_root_path / 'labels' / phase
397
+ for phase in ["train", "val"]:
398
+ image_dir = dota_root_path / "images" / phase
399
+ orig_label_dir = dota_root_path / "labels" / f"{phase}_original"
400
+ save_dir = dota_root_path / "labels" / phase
229
401
 
230
402
  save_dir.mkdir(parents=True, exist_ok=True)
231
403
 
232
404
  image_paths = list(image_dir.iterdir())
233
- for image_path in TQDM(image_paths, desc=f'Processing {phase} images'):
234
- if image_path.suffix != '.png':
405
+ for image_path in TQDM(image_paths, desc=f"Processing {phase} images"):
406
+ if image_path.suffix != ".png":
235
407
  continue
236
408
  image_name_without_ext = image_path.stem
237
409
  img = cv2.imread(str(image_path))
@@ -293,7 +465,7 @@ def merge_multi_segment(segments):
293
465
  s.append(segments[i])
294
466
  else:
295
467
  idx = [0, idx[1] - idx[0]]
296
- s.append(segments[i][idx[0]:idx[1] + 1])
468
+ s.append(segments[i][idx[0] : idx[1] + 1])
297
469
 
298
470
  else:
299
471
  for i in range(len(idx_list) - 1, -1, -1):