ultralytics 8.3.89__py3-none-any.whl → 8.3.90__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 (155) hide show
  1. tests/conftest.py +2 -2
  2. tests/test_cli.py +13 -11
  3. tests/test_cuda.py +10 -1
  4. tests/test_integrations.py +1 -5
  5. tests/test_python.py +16 -16
  6. tests/test_solutions.py +9 -9
  7. ultralytics/__init__.py +1 -1
  8. ultralytics/cfg/__init__.py +3 -1
  9. ultralytics/cfg/models/11/yolo11-cls.yaml +5 -5
  10. ultralytics/cfg/models/11/yolo11-obb.yaml +5 -5
  11. ultralytics/cfg/models/11/yolo11-pose.yaml +5 -5
  12. ultralytics/cfg/models/11/yolo11-seg.yaml +5 -5
  13. ultralytics/cfg/models/11/yolo11.yaml +5 -5
  14. ultralytics/cfg/models/v8/yolov8-ghost-p2.yaml +5 -5
  15. ultralytics/cfg/models/v8/yolov8-ghost-p6.yaml +5 -5
  16. ultralytics/cfg/models/v8/yolov8-ghost.yaml +5 -5
  17. ultralytics/cfg/models/v8/yolov8-obb.yaml +5 -5
  18. ultralytics/cfg/models/v8/yolov8-p6.yaml +5 -5
  19. ultralytics/cfg/models/v8/yolov8-rtdetr.yaml +5 -5
  20. ultralytics/cfg/models/v8/yolov8-world.yaml +5 -5
  21. ultralytics/cfg/models/v8/yolov8-worldv2.yaml +5 -5
  22. ultralytics/cfg/models/v8/yolov8.yaml +5 -5
  23. ultralytics/cfg/models/v9/yolov9c-seg.yaml +1 -1
  24. ultralytics/cfg/models/v9/yolov9c.yaml +1 -1
  25. ultralytics/cfg/models/v9/yolov9e-seg.yaml +1 -1
  26. ultralytics/cfg/models/v9/yolov9e.yaml +1 -1
  27. ultralytics/cfg/models/v9/yolov9m.yaml +1 -1
  28. ultralytics/cfg/models/v9/yolov9s.yaml +1 -1
  29. ultralytics/cfg/models/v9/yolov9t.yaml +1 -1
  30. ultralytics/data/annotator.py +9 -14
  31. ultralytics/data/base.py +118 -30
  32. ultralytics/data/build.py +63 -24
  33. ultralytics/data/converter.py +5 -5
  34. ultralytics/data/dataset.py +207 -53
  35. ultralytics/data/loaders.py +1 -0
  36. ultralytics/data/split_dota.py +39 -12
  37. ultralytics/data/utils.py +13 -19
  38. ultralytics/engine/exporter.py +19 -17
  39. ultralytics/engine/model.py +67 -88
  40. ultralytics/engine/predictor.py +106 -21
  41. ultralytics/engine/trainer.py +32 -23
  42. ultralytics/engine/tuner.py +21 -18
  43. ultralytics/engine/validator.py +75 -41
  44. ultralytics/hub/__init__.py +12 -13
  45. ultralytics/hub/auth.py +9 -12
  46. ultralytics/hub/session.py +76 -21
  47. ultralytics/hub/utils.py +19 -17
  48. ultralytics/models/fastsam/model.py +20 -11
  49. ultralytics/models/fastsam/predict.py +36 -16
  50. ultralytics/models/fastsam/utils.py +5 -5
  51. ultralytics/models/fastsam/val.py +6 -6
  52. ultralytics/models/nas/model.py +22 -11
  53. ultralytics/models/nas/predict.py +9 -4
  54. ultralytics/models/nas/val.py +5 -5
  55. ultralytics/models/rtdetr/model.py +20 -11
  56. ultralytics/models/rtdetr/predict.py +18 -15
  57. ultralytics/models/rtdetr/train.py +20 -16
  58. ultralytics/models/rtdetr/val.py +42 -6
  59. ultralytics/models/sam/__init__.py +1 -1
  60. ultralytics/models/sam/amg.py +50 -4
  61. ultralytics/models/sam/model.py +8 -14
  62. ultralytics/models/sam/modules/decoders.py +18 -21
  63. ultralytics/models/sam/modules/encoders.py +25 -46
  64. ultralytics/models/sam/modules/memory_attention.py +19 -15
  65. ultralytics/models/sam/modules/sam.py +18 -25
  66. ultralytics/models/sam/modules/tiny_encoder.py +19 -29
  67. ultralytics/models/sam/modules/transformer.py +35 -57
  68. ultralytics/models/sam/modules/utils.py +15 -15
  69. ultralytics/models/sam/predict.py +0 -3
  70. ultralytics/models/utils/loss.py +87 -36
  71. ultralytics/models/utils/ops.py +26 -31
  72. ultralytics/models/yolo/classify/predict.py +24 -3
  73. ultralytics/models/yolo/classify/train.py +77 -10
  74. ultralytics/models/yolo/classify/val.py +40 -15
  75. ultralytics/models/yolo/detect/predict.py +23 -10
  76. ultralytics/models/yolo/detect/train.py +85 -15
  77. ultralytics/models/yolo/detect/val.py +145 -21
  78. ultralytics/models/yolo/model.py +1 -2
  79. ultralytics/models/yolo/obb/predict.py +12 -4
  80. ultralytics/models/yolo/obb/train.py +7 -0
  81. ultralytics/models/yolo/obb/val.py +25 -7
  82. ultralytics/models/yolo/pose/predict.py +22 -6
  83. ultralytics/models/yolo/pose/train.py +17 -1
  84. ultralytics/models/yolo/pose/val.py +46 -21
  85. ultralytics/models/yolo/segment/predict.py +22 -8
  86. ultralytics/models/yolo/segment/train.py +6 -0
  87. ultralytics/models/yolo/segment/val.py +100 -14
  88. ultralytics/models/yolo/world/train.py +38 -8
  89. ultralytics/models/yolo/world/train_world.py +39 -10
  90. ultralytics/nn/autobackend.py +28 -14
  91. ultralytics/nn/modules/__init__.py +3 -0
  92. ultralytics/nn/modules/activation.py +12 -3
  93. ultralytics/nn/modules/block.py +587 -84
  94. ultralytics/nn/modules/conv.py +418 -54
  95. ultralytics/nn/modules/head.py +3 -4
  96. ultralytics/nn/modules/transformer.py +320 -34
  97. ultralytics/nn/modules/utils.py +17 -3
  98. ultralytics/nn/tasks.py +221 -69
  99. ultralytics/solutions/ai_gym.py +2 -2
  100. ultralytics/solutions/analytics.py +4 -4
  101. ultralytics/solutions/heatmap.py +4 -4
  102. ultralytics/solutions/instance_segmentation.py +10 -4
  103. ultralytics/solutions/object_blurrer.py +2 -2
  104. ultralytics/solutions/object_counter.py +2 -2
  105. ultralytics/solutions/object_cropper.py +2 -2
  106. ultralytics/solutions/parking_management.py +9 -9
  107. ultralytics/solutions/queue_management.py +1 -1
  108. ultralytics/solutions/region_counter.py +2 -2
  109. ultralytics/solutions/security_alarm.py +7 -7
  110. ultralytics/solutions/solutions.py +7 -4
  111. ultralytics/solutions/speed_estimation.py +2 -2
  112. ultralytics/solutions/streamlit_inference.py +6 -6
  113. ultralytics/solutions/trackzone.py +9 -2
  114. ultralytics/solutions/vision_eye.py +4 -4
  115. ultralytics/trackers/basetrack.py +1 -1
  116. ultralytics/trackers/bot_sort.py +23 -22
  117. ultralytics/trackers/byte_tracker.py +4 -4
  118. ultralytics/trackers/track.py +2 -1
  119. ultralytics/trackers/utils/gmc.py +26 -27
  120. ultralytics/trackers/utils/kalman_filter.py +31 -29
  121. ultralytics/trackers/utils/matching.py +7 -7
  122. ultralytics/utils/__init__.py +32 -27
  123. ultralytics/utils/autobatch.py +5 -5
  124. ultralytics/utils/benchmarks.py +111 -18
  125. ultralytics/utils/callbacks/base.py +3 -3
  126. ultralytics/utils/callbacks/clearml.py +11 -11
  127. ultralytics/utils/callbacks/comet.py +35 -22
  128. ultralytics/utils/callbacks/dvc.py +11 -10
  129. ultralytics/utils/callbacks/hub.py +8 -8
  130. ultralytics/utils/callbacks/mlflow.py +1 -1
  131. ultralytics/utils/callbacks/neptune.py +12 -10
  132. ultralytics/utils/callbacks/raytune.py +1 -1
  133. ultralytics/utils/callbacks/tensorboard.py +6 -6
  134. ultralytics/utils/callbacks/wb.py +16 -16
  135. ultralytics/utils/checks.py +116 -35
  136. ultralytics/utils/dist.py +15 -2
  137. ultralytics/utils/downloads.py +13 -9
  138. ultralytics/utils/files.py +12 -13
  139. ultralytics/utils/instance.py +112 -45
  140. ultralytics/utils/loss.py +28 -33
  141. ultralytics/utils/metrics.py +246 -181
  142. ultralytics/utils/ops.py +61 -53
  143. ultralytics/utils/patches.py +8 -6
  144. ultralytics/utils/plotting.py +64 -45
  145. ultralytics/utils/tal.py +88 -57
  146. ultralytics/utils/torch_utils.py +181 -33
  147. ultralytics/utils/triton.py +13 -3
  148. ultralytics/utils/tuner.py +8 -16
  149. {ultralytics-8.3.89.dist-info → ultralytics-8.3.90.dist-info}/METADATA +1 -1
  150. ultralytics-8.3.90.dist-info/RECORD +250 -0
  151. ultralytics-8.3.89.dist-info/RECORD +0 -250
  152. {ultralytics-8.3.89.dist-info → ultralytics-8.3.90.dist-info}/LICENSE +0 -0
  153. {ultralytics-8.3.89.dist-info → ultralytics-8.3.90.dist-info}/WHEEL +0 -0
  154. {ultralytics-8.3.89.dist-info → ultralytics-8.3.90.dist-info}/entry_points.txt +0 -0
  155. {ultralytics-8.3.89.dist-info → ultralytics-8.3.90.dist-info}/top_level.txt +0 -0
@@ -3,7 +3,7 @@
3
3
  # YOLOv9e object detection model with P3/8 - P5/32 outputs
4
4
  # Model docs: https://docs.ultralytics.com/models/yolov9
5
5
  # Task docs: https://docs.ultralytics.com/tasks/detect
6
- # 1225 layers, 58206592 parameters, 193.0 GFLOPs
6
+ # 721 layers, 58206592 parameters, 193.0 GFLOPs
7
7
 
8
8
  # Parameters
9
9
  nc: 80 # number of classes
@@ -3,7 +3,7 @@
3
3
  # YOLOv9m object detection model with P3/8 - P5/32 outputs
4
4
  # Model docs: https://docs.ultralytics.com/models/yolov9
5
5
  # Task docs: https://docs.ultralytics.com/tasks/detect
6
- # 603 layers, 20216160 parameters, 77.9 GFLOPs
6
+ # 348 layers, 20216160 parameters, 77.9 GFLOPs
7
7
 
8
8
  # Parameters
9
9
  nc: 80 # number of classes
@@ -3,7 +3,7 @@
3
3
  # YOLOv9s object detection model with P3/8 - P5/32 outputs
4
4
  # Model docs: https://docs.ultralytics.com/models/yolov9
5
5
  # Task docs: https://docs.ultralytics.com/tasks/detect
6
- # 917 layers, 7318368 parameters, 27.6 GFLOPs
6
+ # 544 layers, 7318368 parameters, 27.6 GFLOPs
7
7
 
8
8
  # Parameters
9
9
  nc: 80 # number of classes
@@ -3,7 +3,7 @@
3
3
  # YOLOv9t object detection model with P3/8 - P5/32 outputs
4
4
  # Model docs: https://docs.ultralytics.com/models/yolov9
5
5
  # Task docs: https://docs.ultralytics.com/tasks/detect
6
- # 917 layers, 2128720 parameters, 8.5 GFLOPs
6
+ # 544 layers, 2128720 parameters, 8.5 GFLOPs
7
7
 
8
8
  # Parameters
9
9
  nc: 80 # number of classes
@@ -18,31 +18,26 @@ def auto_annotate(
18
18
  output_dir=None,
19
19
  ):
20
20
  """
21
- Automatically annotates images using a YOLO object detection model and a SAM segmentation model.
21
+ Automatically annotate images using a YOLO object detection model and a SAM segmentation model.
22
22
 
23
23
  This function processes images in a specified directory, detects objects using a YOLO model, and then generates
24
24
  segmentation masks using a SAM model. The resulting annotations are saved as text files.
25
25
 
26
26
  Args:
27
- data (str): Path to a folder containing images to be annotated.
27
+ data (str | Path): Path to a folder containing images to be annotated.
28
28
  det_model (str): Path or name of the pre-trained YOLO detection model.
29
29
  sam_model (str): Path or name of the pre-trained SAM segmentation model.
30
30
  device (str): Device to run the models on (e.g., 'cpu', 'cuda', '0').
31
- conf (float): Confidence threshold for detection model; default is 0.25.
32
- iou (float): IoU threshold for filtering overlapping boxes in detection results; default is 0.45.
33
- imgsz (int): Input image resize dimension; default is 640.
34
- max_det (int): Limits detections per image to control outputs in dense scenes.
35
- classes (list): Filters predictions to specified class IDs, returning only relevant detections.
36
- output_dir (str | None): Directory to save the annotated results. If None, a default directory is created.
31
+ conf (float): Confidence threshold for detection model.
32
+ iou (float): IoU threshold for filtering overlapping boxes in detection results.
33
+ imgsz (int): Input image resize dimension.
34
+ max_det (int): Maximum number of detections per image.
35
+ classes (List[int] | None): Filter predictions to specified class IDs, returning only relevant detections.
36
+ output_dir (str | Path | None): Directory to save the annotated results. If None, a default directory is created.
37
37
 
38
38
  Examples:
39
39
  >>> from ultralytics.data.annotator import auto_annotate
40
40
  >>> auto_annotate(data="ultralytics/assets", det_model="yolo11n.pt", sam_model="mobile_sam.pt")
41
-
42
- Notes:
43
- - The function creates a new directory for output if not specified.
44
- - Annotation results are saved as text files with the same names as the input images.
45
- - Each line in the output text file represents a detected object with its class ID and segmentation points.
46
41
  """
47
42
  det_model = YOLO(det_model)
48
43
  sam_model = SAM(sam_model)
@@ -61,7 +56,7 @@ def auto_annotate(
61
56
  if class_ids:
62
57
  boxes = result.boxes.xyxy # Boxes object for bbox outputs
63
58
  sam_results = sam_model(result.orig_img, bboxes=boxes, verbose=False, save=False, device=device)
64
- segments = sam_results[0].masks.xyn # noqa
59
+ segments = sam_results[0].masks.xyn
65
60
 
66
61
  with open(f"{Path(output_dir) / Path(result.path).stem}.txt", "w", encoding="utf-8") as f:
67
62
  for i, s in enumerate(segments):
ultralytics/data/base.py CHANGED
@@ -22,28 +22,45 @@ class BaseDataset(Dataset):
22
22
  """
23
23
  Base dataset class for loading and processing image data.
24
24
 
25
- Args:
26
- img_path (str): Path to the folder containing images.
27
- imgsz (int, optional): Image size. Defaults to 640.
28
- cache (bool, optional): Cache images to RAM or disk during training. Defaults to False.
29
- augment (bool, optional): If True, data augmentation is applied. Defaults to True.
30
- hyp (dict, optional): Hyperparameters to apply data augmentation. Defaults to None.
31
- prefix (str, optional): Prefix to print in log messages. Defaults to ''.
32
- rect (bool, optional): If True, rectangular training is used. Defaults to False.
33
- batch_size (int, optional): Size of batches. Defaults to None.
34
- stride (int, optional): Stride. Defaults to 32.
35
- pad (float, optional): Padding. Defaults to 0.0.
36
- single_cls (bool, optional): If True, single class training is used. Defaults to False.
37
- classes (list): List of included classes. Default is None.
38
- fraction (float): Fraction of dataset to utilize. Default is 1.0 (use all data).
25
+ This class provides core functionality for loading images, caching, and preparing data for training and inference
26
+ in object detection tasks.
39
27
 
40
28
  Attributes:
41
- im_files (list): List of image file paths.
42
- labels (list): List of label data dictionaries.
29
+ img_path (str): Path to the folder containing images.
30
+ imgsz (int): Target image size for resizing.
31
+ augment (bool): Whether to apply data augmentation.
32
+ single_cls (bool): Whether to treat all objects as a single class.
33
+ prefix (str): Prefix to print in log messages.
34
+ fraction (float): Fraction of dataset to utilize.
35
+ im_files (List[str]): List of image file paths.
36
+ labels (List[Dict]): List of label data dictionaries.
43
37
  ni (int): Number of images in the dataset.
44
- ims (list): List of loaded images.
45
- npy_files (list): List of numpy file paths.
38
+ rect (bool): Whether to use rectangular training.
39
+ batch_size (int): Size of batches.
40
+ stride (int): Stride used in the model.
41
+ pad (float): Padding value.
42
+ buffer (List): Buffer for mosaic images.
43
+ max_buffer_length (int): Maximum buffer size.
44
+ ims (List): List of loaded images.
45
+ im_hw0 (List): List of original image dimensions (h, w).
46
+ im_hw (List): List of resized image dimensions (h, w).
47
+ npy_files (List[Path]): List of numpy file paths.
48
+ cache (str): Cache images to RAM or disk during training.
46
49
  transforms (callable): Image transformation function.
50
+
51
+ Methods:
52
+ get_img_files: Read image files from the specified path.
53
+ update_labels: Update labels to include only specified classes.
54
+ load_image: Load an image from the dataset.
55
+ cache_images: Cache images to memory or disk.
56
+ cache_images_to_disk: Save an image as an *.npy file for faster loading.
57
+ check_cache_disk: Check image caching requirements vs available disk space.
58
+ check_cache_ram: Check image caching requirements vs available memory.
59
+ set_rectangle: Set the shape of bounding boxes as rectangles.
60
+ get_image_and_label: Get and return label information from the dataset.
61
+ update_labels_info: Custom label format method to be implemented by subclasses.
62
+ build_transforms: Build transformation pipeline to be implemented by subclasses.
63
+ get_labels: Get labels method to be implemented by subclasses.
47
64
  """
48
65
 
49
66
  def __init__(
@@ -62,7 +79,24 @@ class BaseDataset(Dataset):
62
79
  classes=None,
63
80
  fraction=1.0,
64
81
  ):
65
- """Initialize BaseDataset with given configuration and options."""
82
+ """
83
+ Initialize BaseDataset with given configuration and options.
84
+
85
+ Args:
86
+ img_path (str): Path to the folder containing images.
87
+ imgsz (int, optional): Image size for resizing.
88
+ cache (bool | str, optional): Cache images to RAM or disk during training.
89
+ augment (bool, optional): If True, data augmentation is applied.
90
+ hyp (dict, optional): Hyperparameters to apply data augmentation.
91
+ prefix (str, optional): Prefix to print in log messages.
92
+ rect (bool, optional): If True, rectangular training is used.
93
+ batch_size (int, optional): Size of batches.
94
+ stride (int, optional): Stride used in the model.
95
+ pad (float, optional): Padding value.
96
+ single_cls (bool, optional): If True, single class training is used.
97
+ classes (List, optional): List of included classes.
98
+ fraction (float, optional): Fraction of dataset to utilize.
99
+ """
66
100
  super().__init__()
67
101
  self.img_path = img_path
68
102
  self.imgsz = imgsz
@@ -104,7 +138,18 @@ class BaseDataset(Dataset):
104
138
  self.transforms = self.build_transforms(hyp=hyp)
105
139
 
106
140
  def get_img_files(self, img_path):
107
- """Read image files."""
141
+ """
142
+ Read image files from the specified path.
143
+
144
+ Args:
145
+ img_path (str | List[str]): Path or list of paths to image directories or files.
146
+
147
+ Returns:
148
+ (List[str]): List of image file paths.
149
+
150
+ Raises:
151
+ FileNotFoundError: If no images are found or the path doesn't exist.
152
+ """
108
153
  try:
109
154
  f = [] # image files
110
155
  for p in img_path if isinstance(img_path, list) else [img_path]:
@@ -130,7 +175,12 @@ class BaseDataset(Dataset):
130
175
  return im_files
131
176
 
132
177
  def update_labels(self, include_class: Optional[list]):
133
- """Update labels to include only these classes (optional)."""
178
+ """
179
+ Update labels to include only specified classes.
180
+
181
+ Args:
182
+ include_class (List, optional): List of classes to include. If None, all classes are included.
183
+ """
134
184
  include_class_array = np.array(include_class).reshape(1, -1)
135
185
  for i in range(len(self.labels)):
136
186
  if include_class is not None:
@@ -149,7 +199,21 @@ class BaseDataset(Dataset):
149
199
  self.labels[i]["cls"][:, 0] = 0
150
200
 
151
201
  def load_image(self, i, rect_mode=True):
152
- """Loads 1 image from dataset index 'i', returns (im, resized hw)."""
202
+ """
203
+ Load an image from dataset index 'i'.
204
+
205
+ Args:
206
+ i (int): Index of the image to load.
207
+ rect_mode (bool, optional): Whether to use rectangular resizing.
208
+
209
+ Returns:
210
+ (np.ndarray): Loaded image.
211
+ (tuple): Original image dimensions (h, w).
212
+ (tuple): Resized image dimensions (h, w).
213
+
214
+ Raises:
215
+ FileNotFoundError: If the image file is not found.
216
+ """
153
217
  im, f, fn = self.ims[i], self.im_files[i], self.npy_files[i]
154
218
  if im is None: # not cached in RAM
155
219
  if fn.exists(): # load npy
@@ -187,7 +251,7 @@ class BaseDataset(Dataset):
187
251
  return self.ims[i], self.im_hw0[i], self.im_hw[i]
188
252
 
189
253
  def cache_images(self):
190
- """Cache images to memory or disk."""
254
+ """Cache images to memory or disk for faster training."""
191
255
  b, gb = 0, 1 << 30 # bytes of cached images, bytes per gigabytes
192
256
  fcn, storage = (self.cache_images_to_disk, "Disk") if self.cache == "disk" else (self.load_image, "RAM")
193
257
  with ThreadPool(NUM_THREADS) as pool:
@@ -203,13 +267,21 @@ class BaseDataset(Dataset):
203
267
  pbar.close()
204
268
 
205
269
  def cache_images_to_disk(self, i):
206
- """Saves an image as an *.npy file for faster loading."""
270
+ """Save an image as an *.npy file for faster loading."""
207
271
  f = self.npy_files[i]
208
272
  if not f.exists():
209
273
  np.save(f.as_posix(), cv2.imread(self.im_files[i]), allow_pickle=False)
210
274
 
211
275
  def check_cache_disk(self, safety_margin=0.5):
212
- """Check image caching requirements vs available disk space."""
276
+ """
277
+ Check if there's enough disk space for caching images.
278
+
279
+ Args:
280
+ safety_margin (float, optional): Safety margin factor for disk space calculation.
281
+
282
+ Returns:
283
+ (bool): True if there's enough disk space, False otherwise.
284
+ """
213
285
  import shutil
214
286
 
215
287
  b, gb = 0, 1 << 30 # bytes of cached images, bytes per gigabytes
@@ -237,7 +309,15 @@ class BaseDataset(Dataset):
237
309
  return True
238
310
 
239
311
  def check_cache_ram(self, safety_margin=0.5):
240
- """Check image caching requirements vs available memory."""
312
+ """
313
+ Check if there's enough RAM for caching images.
314
+
315
+ Args:
316
+ safety_margin (float, optional): Safety margin factor for RAM calculation.
317
+
318
+ Returns:
319
+ (bool): True if there's enough RAM, False otherwise.
320
+ """
241
321
  b, gb = 0, 1 << 30 # bytes of cached images, bytes per gigabytes
242
322
  n = min(self.ni, 30) # extrapolate from 30 random images
243
323
  for _ in range(n):
@@ -259,7 +339,7 @@ class BaseDataset(Dataset):
259
339
  return True
260
340
 
261
341
  def set_rectangle(self):
262
- """Sets the shape of bounding boxes for YOLO detections as rectangles."""
342
+ """Set the shape of bounding boxes for YOLO detections as rectangles."""
263
343
  bi = np.floor(np.arange(self.ni) / self.batch_size).astype(int) # batch index
264
344
  nb = bi[-1] + 1 # number of batches
265
345
 
@@ -284,11 +364,19 @@ class BaseDataset(Dataset):
284
364
  self.batch = bi # batch index of image
285
365
 
286
366
  def __getitem__(self, index):
287
- """Returns transformed label information for given index."""
367
+ """Return transformed label information for given index."""
288
368
  return self.transforms(self.get_image_and_label(index))
289
369
 
290
370
  def get_image_and_label(self, index):
291
- """Get and return label information from the dataset."""
371
+ """
372
+ Get and return label information from the dataset.
373
+
374
+ Args:
375
+ index (int): Index of the image to retrieve.
376
+
377
+ Returns:
378
+ (dict): Label dictionary with image and metadata.
379
+ """
292
380
  label = deepcopy(self.labels[index]) # requires deepcopy() https://github.com/ultralytics/ultralytics/pull/1948
293
381
  label.pop("shape", None) # shape is for rect, remove it
294
382
  label["img"], label["ori_shape"], label["resized_shape"] = self.load_image(index)
@@ -301,7 +389,7 @@ class BaseDataset(Dataset):
301
389
  return self.update_labels_info(label)
302
390
 
303
391
  def __len__(self):
304
- """Returns the length of the labels list for the dataset."""
392
+ """Return the length of the labels list for the dataset."""
305
393
  return len(self.labels)
306
394
 
307
395
  def update_labels_info(self, label):
ultralytics/data/build.py CHANGED
@@ -29,26 +29,37 @@ class InfiniteDataLoader(dataloader.DataLoader):
29
29
  """
30
30
  Dataloader that reuses workers.
31
31
 
32
- Uses same syntax as vanilla DataLoader.
32
+ This dataloader extends the PyTorch DataLoader to provide infinite recycling of workers, which improves efficiency
33
+ for training loops that need to iterate through the dataset multiple times.
34
+
35
+ Attributes:
36
+ batch_sampler (_RepeatSampler): A sampler that repeats indefinitely.
37
+ iterator (Iterator): The iterator from the parent DataLoader.
38
+
39
+ Methods:
40
+ __len__: Returns the length of the batch sampler's sampler.
41
+ __iter__: Creates a sampler that repeats indefinitely.
42
+ __del__: Ensures workers are properly terminated.
43
+ reset: Resets the iterator, useful when modifying dataset settings during training.
33
44
  """
34
45
 
35
46
  def __init__(self, *args, **kwargs):
36
- """Dataloader that infinitely recycles workers, inherits from DataLoader."""
47
+ """Initialize the InfiniteDataLoader with the same arguments as DataLoader."""
37
48
  super().__init__(*args, **kwargs)
38
49
  object.__setattr__(self, "batch_sampler", _RepeatSampler(self.batch_sampler))
39
50
  self.iterator = super().__iter__()
40
51
 
41
52
  def __len__(self):
42
- """Returns the length of the batch sampler's sampler."""
53
+ """Return the length of the batch sampler's sampler."""
43
54
  return len(self.batch_sampler.sampler)
44
55
 
45
56
  def __iter__(self):
46
- """Creates a sampler that repeats indefinitely."""
57
+ """Create an iterator that yields indefinitely from the underlying iterator."""
47
58
  for _ in range(len(self)):
48
59
  yield next(self.iterator)
49
60
 
50
61
  def __del__(self):
51
- """Ensure that workers are terminated."""
62
+ """Ensure that workers are properly terminated when the dataloader is deleted."""
52
63
  try:
53
64
  if not hasattr(self.iterator, "_workers"):
54
65
  return
@@ -60,11 +71,7 @@ class InfiniteDataLoader(dataloader.DataLoader):
60
71
  pass
61
72
 
62
73
  def reset(self):
63
- """
64
- Reset iterator.
65
-
66
- This is useful when we want to modify settings of dataset while training.
67
- """
74
+ """Reset the iterator to allow modifications to the dataset during training."""
68
75
  self.iterator = self._get_iterator()
69
76
 
70
77
 
@@ -72,29 +79,32 @@ class _RepeatSampler:
72
79
  """
73
80
  Sampler that repeats forever.
74
81
 
75
- Args:
82
+ This sampler wraps another sampler and yields its contents indefinitely, allowing for infinite iteration
83
+ over a dataset.
84
+
85
+ Attributes:
76
86
  sampler (Dataset.sampler): The sampler to repeat.
77
87
  """
78
88
 
79
89
  def __init__(self, sampler):
80
- """Initializes an object that repeats a given sampler indefinitely."""
90
+ """Initialize the _RepeatSampler with a sampler to repeat indefinitely."""
81
91
  self.sampler = sampler
82
92
 
83
93
  def __iter__(self):
84
- """Iterates over the 'sampler' and yields its contents."""
94
+ """Iterate over the sampler indefinitely, yielding its contents."""
85
95
  while True:
86
96
  yield from iter(self.sampler)
87
97
 
88
98
 
89
99
  def seed_worker(worker_id): # noqa
90
- """Set dataloader worker seed https://pytorch.org/docs/stable/notes/randomness.html#dataloader."""
100
+ """Set dataloader worker seed for reproducibility across worker processes."""
91
101
  worker_seed = torch.initial_seed() % 2**32
92
102
  np.random.seed(worker_seed)
93
103
  random.seed(worker_seed)
94
104
 
95
105
 
96
106
  def build_yolo_dataset(cfg, img_path, batch, data, mode="train", rect=False, stride=32, multi_modal=False):
97
- """Build YOLO Dataset."""
107
+ """Build and return a YOLO dataset based on configuration parameters."""
98
108
  dataset = YOLOMultiModalDataset if multi_modal else YOLODataset
99
109
  return dataset(
100
110
  img_path=img_path,
@@ -116,7 +126,7 @@ def build_yolo_dataset(cfg, img_path, batch, data, mode="train", rect=False, str
116
126
 
117
127
 
118
128
  def build_grounding(cfg, img_path, json_file, batch, mode="train", rect=False, stride=32):
119
- """Build YOLO Dataset."""
129
+ """Build and return a GroundingDataset based on configuration parameters."""
120
130
  return GroundingDataset(
121
131
  img_path=img_path,
122
132
  json_file=json_file,
@@ -137,7 +147,19 @@ def build_grounding(cfg, img_path, json_file, batch, mode="train", rect=False, s
137
147
 
138
148
 
139
149
  def build_dataloader(dataset, batch, workers, shuffle=True, rank=-1):
140
- """Return an InfiniteDataLoader or DataLoader for training or validation set."""
150
+ """
151
+ Create and return an InfiniteDataLoader or DataLoader for training or validation.
152
+
153
+ Args:
154
+ dataset (Dataset): Dataset to load data from.
155
+ batch (int): Batch size for the dataloader.
156
+ workers (int): Number of worker threads for loading data.
157
+ shuffle (bool): Whether to shuffle the dataset.
158
+ rank (int): Process rank in distributed training. -1 for single-GPU training.
159
+
160
+ Returns:
161
+ (InfiniteDataLoader): A dataloader that can be used for training or validation.
162
+ """
141
163
  batch = min(batch, len(dataset))
142
164
  nd = torch.cuda.device_count() # number of CUDA devices
143
165
  nw = min(os.cpu_count() // max(nd, 1), workers) # number of workers
@@ -158,7 +180,24 @@ def build_dataloader(dataset, batch, workers, shuffle=True, rank=-1):
158
180
 
159
181
 
160
182
  def check_source(source):
161
- """Check source type and return corresponding flag values."""
183
+ """
184
+ Check the type of input source and return corresponding flag values.
185
+
186
+ Args:
187
+ source (str | int | Path | List | Tuple | np.ndarray | PIL.Image | torch.Tensor): The input source to check.
188
+
189
+ Returns:
190
+ (tuple): A tuple containing:
191
+ - source: The processed source.
192
+ - webcam (bool): Whether the source is a webcam.
193
+ - screenshot (bool): Whether the source is a screenshot.
194
+ - from_img (bool): Whether the source is an image or list of images.
195
+ - in_memory (bool): Whether the source is an in-memory object.
196
+ - tensor (bool): Whether the source is a torch.Tensor.
197
+
198
+ Raises:
199
+ TypeError: If the source type is unsupported.
200
+ """
162
201
  webcam, screenshot, from_img, in_memory, tensor = False, False, False, False, False
163
202
  if isinstance(source, (str, int, Path)): # int for local usb camera
164
203
  source = str(source)
@@ -185,16 +224,16 @@ def check_source(source):
185
224
 
186
225
  def load_inference_source(source=None, batch=1, vid_stride=1, buffer=False):
187
226
  """
188
- Loads an inference source for object detection and applies necessary transformations.
227
+ Load an inference source for object detection and apply necessary transformations.
189
228
 
190
229
  Args:
191
- source (str, Path, Tensor, PIL.Image, np.ndarray): The input source for inference.
192
- batch (int, optional): Batch size for dataloaders. Default is 1.
193
- vid_stride (int, optional): The frame interval for video sources. Default is 1.
194
- buffer (bool, optional): Determined whether stream frames will be buffered. Default is False.
230
+ source (str | Path | torch.Tensor | PIL.Image | np.ndarray, optional): The input source for inference.
231
+ batch (int, optional): Batch size for dataloaders.
232
+ vid_stride (int, optional): The frame interval for video sources.
233
+ buffer (bool, optional): Whether stream frames will be buffered.
195
234
 
196
235
  Returns:
197
- dataset (Dataset): A dataset object for the specified input source.
236
+ (Dataset): A dataset object for the specified input source with attached source_type attribute.
198
237
  """
199
238
  source, stream, screenshot, from_img, in_memory, tensor = check_source(source)
200
239
  source_type = source.source_type if in_memory else SourceTypes(stream, screenshot, from_img, tensor)
@@ -21,7 +21,7 @@ def coco91_to_coco80_class():
21
21
  Converts 91-index COCO class IDs to 80-index COCO class IDs.
22
22
 
23
23
  Returns:
24
- (list): A list of 91 class IDs where the index represents the 80-index class ID and the value is the
24
+ (List): A list of 91 class IDs where the index represents the 80-index class ID and the value is the
25
25
  corresponding 91-index class ID.
26
26
  """
27
27
  return [
@@ -228,7 +228,7 @@ def convert_coco(
228
228
  lvis=False,
229
229
  ):
230
230
  """
231
- Converts COCO dataset annotations to a YOLO annotation format suitable for training YOLO models.
231
+ Converts COCO dataset annotations to a YOLO annotation format suitable for training YOLO models.
232
232
 
233
233
  Args:
234
234
  labels_dir (str, optional): Path to directory containing COCO dataset annotation files.
@@ -589,9 +589,9 @@ def yolo_bbox2segment(im_dir, save_dir=None, sam_model="sam_b.pt", device=None):
589
589
  Args:
590
590
  im_dir (str | Path): Path to image directory to convert.
591
591
  save_dir (str | Path): Path to save the generated labels, labels will be saved
592
- into `labels-segment` in the same directory level of `im_dir` if save_dir is None. Default: None.
593
- sam_model (str): Segmentation model to use for intermediate segmentation data; optional.
594
- device (int | str): The specific device to run SAM models. Default: None.
592
+ into `labels-segment` in the same directory level of `im_dir` if save_dir is None.
593
+ sam_model (str): Segmentation model to use for intermediate segmentation data.
594
+ device (int | str): The specific device to run SAM models.
595
595
 
596
596
  Notes:
597
597
  The input directory structure assumed for dataset: