ultralytics-opencv-headless 8.3.242__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 (298) hide show
  1. tests/__init__.py +23 -0
  2. tests/conftest.py +59 -0
  3. tests/test_cli.py +131 -0
  4. tests/test_cuda.py +216 -0
  5. tests/test_engine.py +157 -0
  6. tests/test_exports.py +309 -0
  7. tests/test_integrations.py +151 -0
  8. tests/test_python.py +777 -0
  9. tests/test_solutions.py +371 -0
  10. ultralytics/__init__.py +48 -0
  11. ultralytics/assets/bus.jpg +0 -0
  12. ultralytics/assets/zidane.jpg +0 -0
  13. ultralytics/cfg/__init__.py +1026 -0
  14. ultralytics/cfg/datasets/Argoverse.yaml +78 -0
  15. ultralytics/cfg/datasets/DOTAv1.5.yaml +37 -0
  16. ultralytics/cfg/datasets/DOTAv1.yaml +36 -0
  17. ultralytics/cfg/datasets/GlobalWheat2020.yaml +68 -0
  18. ultralytics/cfg/datasets/HomeObjects-3K.yaml +32 -0
  19. ultralytics/cfg/datasets/ImageNet.yaml +2025 -0
  20. ultralytics/cfg/datasets/Objects365.yaml +447 -0
  21. ultralytics/cfg/datasets/SKU-110K.yaml +58 -0
  22. ultralytics/cfg/datasets/VOC.yaml +102 -0
  23. ultralytics/cfg/datasets/VisDrone.yaml +87 -0
  24. ultralytics/cfg/datasets/african-wildlife.yaml +25 -0
  25. ultralytics/cfg/datasets/brain-tumor.yaml +22 -0
  26. ultralytics/cfg/datasets/carparts-seg.yaml +44 -0
  27. ultralytics/cfg/datasets/coco-pose.yaml +64 -0
  28. ultralytics/cfg/datasets/coco.yaml +118 -0
  29. ultralytics/cfg/datasets/coco128-seg.yaml +101 -0
  30. ultralytics/cfg/datasets/coco128.yaml +101 -0
  31. ultralytics/cfg/datasets/coco8-grayscale.yaml +103 -0
  32. ultralytics/cfg/datasets/coco8-multispectral.yaml +104 -0
  33. ultralytics/cfg/datasets/coco8-pose.yaml +47 -0
  34. ultralytics/cfg/datasets/coco8-seg.yaml +101 -0
  35. ultralytics/cfg/datasets/coco8.yaml +101 -0
  36. ultralytics/cfg/datasets/construction-ppe.yaml +32 -0
  37. ultralytics/cfg/datasets/crack-seg.yaml +22 -0
  38. ultralytics/cfg/datasets/dog-pose.yaml +52 -0
  39. ultralytics/cfg/datasets/dota8-multispectral.yaml +38 -0
  40. ultralytics/cfg/datasets/dota8.yaml +35 -0
  41. ultralytics/cfg/datasets/hand-keypoints.yaml +50 -0
  42. ultralytics/cfg/datasets/kitti.yaml +27 -0
  43. ultralytics/cfg/datasets/lvis.yaml +1240 -0
  44. ultralytics/cfg/datasets/medical-pills.yaml +21 -0
  45. ultralytics/cfg/datasets/open-images-v7.yaml +663 -0
  46. ultralytics/cfg/datasets/package-seg.yaml +22 -0
  47. ultralytics/cfg/datasets/signature.yaml +21 -0
  48. ultralytics/cfg/datasets/tiger-pose.yaml +41 -0
  49. ultralytics/cfg/datasets/xView.yaml +155 -0
  50. ultralytics/cfg/default.yaml +130 -0
  51. ultralytics/cfg/models/11/yolo11-cls-resnet18.yaml +17 -0
  52. ultralytics/cfg/models/11/yolo11-cls.yaml +33 -0
  53. ultralytics/cfg/models/11/yolo11-obb.yaml +50 -0
  54. ultralytics/cfg/models/11/yolo11-pose.yaml +51 -0
  55. ultralytics/cfg/models/11/yolo11-seg.yaml +50 -0
  56. ultralytics/cfg/models/11/yolo11.yaml +50 -0
  57. ultralytics/cfg/models/11/yoloe-11-seg.yaml +48 -0
  58. ultralytics/cfg/models/11/yoloe-11.yaml +48 -0
  59. ultralytics/cfg/models/12/yolo12-cls.yaml +32 -0
  60. ultralytics/cfg/models/12/yolo12-obb.yaml +48 -0
  61. ultralytics/cfg/models/12/yolo12-pose.yaml +49 -0
  62. ultralytics/cfg/models/12/yolo12-seg.yaml +48 -0
  63. ultralytics/cfg/models/12/yolo12.yaml +48 -0
  64. ultralytics/cfg/models/rt-detr/rtdetr-l.yaml +53 -0
  65. ultralytics/cfg/models/rt-detr/rtdetr-resnet101.yaml +45 -0
  66. ultralytics/cfg/models/rt-detr/rtdetr-resnet50.yaml +45 -0
  67. ultralytics/cfg/models/rt-detr/rtdetr-x.yaml +57 -0
  68. ultralytics/cfg/models/v10/yolov10b.yaml +45 -0
  69. ultralytics/cfg/models/v10/yolov10l.yaml +45 -0
  70. ultralytics/cfg/models/v10/yolov10m.yaml +45 -0
  71. ultralytics/cfg/models/v10/yolov10n.yaml +45 -0
  72. ultralytics/cfg/models/v10/yolov10s.yaml +45 -0
  73. ultralytics/cfg/models/v10/yolov10x.yaml +45 -0
  74. ultralytics/cfg/models/v3/yolov3-spp.yaml +49 -0
  75. ultralytics/cfg/models/v3/yolov3-tiny.yaml +40 -0
  76. ultralytics/cfg/models/v3/yolov3.yaml +49 -0
  77. ultralytics/cfg/models/v5/yolov5-p6.yaml +62 -0
  78. ultralytics/cfg/models/v5/yolov5.yaml +51 -0
  79. ultralytics/cfg/models/v6/yolov6.yaml +56 -0
  80. ultralytics/cfg/models/v8/yoloe-v8-seg.yaml +48 -0
  81. ultralytics/cfg/models/v8/yoloe-v8.yaml +48 -0
  82. ultralytics/cfg/models/v8/yolov8-cls-resnet101.yaml +28 -0
  83. ultralytics/cfg/models/v8/yolov8-cls-resnet50.yaml +28 -0
  84. ultralytics/cfg/models/v8/yolov8-cls.yaml +32 -0
  85. ultralytics/cfg/models/v8/yolov8-ghost-p2.yaml +58 -0
  86. ultralytics/cfg/models/v8/yolov8-ghost-p6.yaml +60 -0
  87. ultralytics/cfg/models/v8/yolov8-ghost.yaml +50 -0
  88. ultralytics/cfg/models/v8/yolov8-obb.yaml +49 -0
  89. ultralytics/cfg/models/v8/yolov8-p2.yaml +57 -0
  90. ultralytics/cfg/models/v8/yolov8-p6.yaml +59 -0
  91. ultralytics/cfg/models/v8/yolov8-pose-p6.yaml +60 -0
  92. ultralytics/cfg/models/v8/yolov8-pose.yaml +50 -0
  93. ultralytics/cfg/models/v8/yolov8-rtdetr.yaml +49 -0
  94. ultralytics/cfg/models/v8/yolov8-seg-p6.yaml +59 -0
  95. ultralytics/cfg/models/v8/yolov8-seg.yaml +49 -0
  96. ultralytics/cfg/models/v8/yolov8-world.yaml +51 -0
  97. ultralytics/cfg/models/v8/yolov8-worldv2.yaml +49 -0
  98. ultralytics/cfg/models/v8/yolov8.yaml +49 -0
  99. ultralytics/cfg/models/v9/yolov9c-seg.yaml +41 -0
  100. ultralytics/cfg/models/v9/yolov9c.yaml +41 -0
  101. ultralytics/cfg/models/v9/yolov9e-seg.yaml +64 -0
  102. ultralytics/cfg/models/v9/yolov9e.yaml +64 -0
  103. ultralytics/cfg/models/v9/yolov9m.yaml +41 -0
  104. ultralytics/cfg/models/v9/yolov9s.yaml +41 -0
  105. ultralytics/cfg/models/v9/yolov9t.yaml +41 -0
  106. ultralytics/cfg/trackers/botsort.yaml +21 -0
  107. ultralytics/cfg/trackers/bytetrack.yaml +12 -0
  108. ultralytics/data/__init__.py +26 -0
  109. ultralytics/data/annotator.py +66 -0
  110. ultralytics/data/augment.py +2801 -0
  111. ultralytics/data/base.py +435 -0
  112. ultralytics/data/build.py +437 -0
  113. ultralytics/data/converter.py +855 -0
  114. ultralytics/data/dataset.py +834 -0
  115. ultralytics/data/loaders.py +704 -0
  116. ultralytics/data/scripts/download_weights.sh +18 -0
  117. ultralytics/data/scripts/get_coco.sh +61 -0
  118. ultralytics/data/scripts/get_coco128.sh +18 -0
  119. ultralytics/data/scripts/get_imagenet.sh +52 -0
  120. ultralytics/data/split.py +138 -0
  121. ultralytics/data/split_dota.py +344 -0
  122. ultralytics/data/utils.py +798 -0
  123. ultralytics/engine/__init__.py +1 -0
  124. ultralytics/engine/exporter.py +1574 -0
  125. ultralytics/engine/model.py +1124 -0
  126. ultralytics/engine/predictor.py +508 -0
  127. ultralytics/engine/results.py +1522 -0
  128. ultralytics/engine/trainer.py +974 -0
  129. ultralytics/engine/tuner.py +448 -0
  130. ultralytics/engine/validator.py +384 -0
  131. ultralytics/hub/__init__.py +166 -0
  132. ultralytics/hub/auth.py +151 -0
  133. ultralytics/hub/google/__init__.py +174 -0
  134. ultralytics/hub/session.py +422 -0
  135. ultralytics/hub/utils.py +162 -0
  136. ultralytics/models/__init__.py +9 -0
  137. ultralytics/models/fastsam/__init__.py +7 -0
  138. ultralytics/models/fastsam/model.py +79 -0
  139. ultralytics/models/fastsam/predict.py +169 -0
  140. ultralytics/models/fastsam/utils.py +23 -0
  141. ultralytics/models/fastsam/val.py +38 -0
  142. ultralytics/models/nas/__init__.py +7 -0
  143. ultralytics/models/nas/model.py +98 -0
  144. ultralytics/models/nas/predict.py +56 -0
  145. ultralytics/models/nas/val.py +38 -0
  146. ultralytics/models/rtdetr/__init__.py +7 -0
  147. ultralytics/models/rtdetr/model.py +63 -0
  148. ultralytics/models/rtdetr/predict.py +88 -0
  149. ultralytics/models/rtdetr/train.py +89 -0
  150. ultralytics/models/rtdetr/val.py +216 -0
  151. ultralytics/models/sam/__init__.py +25 -0
  152. ultralytics/models/sam/amg.py +275 -0
  153. ultralytics/models/sam/build.py +365 -0
  154. ultralytics/models/sam/build_sam3.py +377 -0
  155. ultralytics/models/sam/model.py +169 -0
  156. ultralytics/models/sam/modules/__init__.py +1 -0
  157. ultralytics/models/sam/modules/blocks.py +1067 -0
  158. ultralytics/models/sam/modules/decoders.py +495 -0
  159. ultralytics/models/sam/modules/encoders.py +794 -0
  160. ultralytics/models/sam/modules/memory_attention.py +298 -0
  161. ultralytics/models/sam/modules/sam.py +1160 -0
  162. ultralytics/models/sam/modules/tiny_encoder.py +979 -0
  163. ultralytics/models/sam/modules/transformer.py +344 -0
  164. ultralytics/models/sam/modules/utils.py +512 -0
  165. ultralytics/models/sam/predict.py +3940 -0
  166. ultralytics/models/sam/sam3/__init__.py +3 -0
  167. ultralytics/models/sam/sam3/decoder.py +546 -0
  168. ultralytics/models/sam/sam3/encoder.py +529 -0
  169. ultralytics/models/sam/sam3/geometry_encoders.py +415 -0
  170. ultralytics/models/sam/sam3/maskformer_segmentation.py +286 -0
  171. ultralytics/models/sam/sam3/model_misc.py +199 -0
  172. ultralytics/models/sam/sam3/necks.py +129 -0
  173. ultralytics/models/sam/sam3/sam3_image.py +339 -0
  174. ultralytics/models/sam/sam3/text_encoder_ve.py +307 -0
  175. ultralytics/models/sam/sam3/vitdet.py +547 -0
  176. ultralytics/models/sam/sam3/vl_combiner.py +160 -0
  177. ultralytics/models/utils/__init__.py +1 -0
  178. ultralytics/models/utils/loss.py +466 -0
  179. ultralytics/models/utils/ops.py +315 -0
  180. ultralytics/models/yolo/__init__.py +7 -0
  181. ultralytics/models/yolo/classify/__init__.py +7 -0
  182. ultralytics/models/yolo/classify/predict.py +90 -0
  183. ultralytics/models/yolo/classify/train.py +202 -0
  184. ultralytics/models/yolo/classify/val.py +216 -0
  185. ultralytics/models/yolo/detect/__init__.py +7 -0
  186. ultralytics/models/yolo/detect/predict.py +122 -0
  187. ultralytics/models/yolo/detect/train.py +227 -0
  188. ultralytics/models/yolo/detect/val.py +507 -0
  189. ultralytics/models/yolo/model.py +430 -0
  190. ultralytics/models/yolo/obb/__init__.py +7 -0
  191. ultralytics/models/yolo/obb/predict.py +56 -0
  192. ultralytics/models/yolo/obb/train.py +79 -0
  193. ultralytics/models/yolo/obb/val.py +302 -0
  194. ultralytics/models/yolo/pose/__init__.py +7 -0
  195. ultralytics/models/yolo/pose/predict.py +65 -0
  196. ultralytics/models/yolo/pose/train.py +110 -0
  197. ultralytics/models/yolo/pose/val.py +248 -0
  198. ultralytics/models/yolo/segment/__init__.py +7 -0
  199. ultralytics/models/yolo/segment/predict.py +109 -0
  200. ultralytics/models/yolo/segment/train.py +69 -0
  201. ultralytics/models/yolo/segment/val.py +307 -0
  202. ultralytics/models/yolo/world/__init__.py +5 -0
  203. ultralytics/models/yolo/world/train.py +173 -0
  204. ultralytics/models/yolo/world/train_world.py +178 -0
  205. ultralytics/models/yolo/yoloe/__init__.py +22 -0
  206. ultralytics/models/yolo/yoloe/predict.py +162 -0
  207. ultralytics/models/yolo/yoloe/train.py +287 -0
  208. ultralytics/models/yolo/yoloe/train_seg.py +122 -0
  209. ultralytics/models/yolo/yoloe/val.py +206 -0
  210. ultralytics/nn/__init__.py +27 -0
  211. ultralytics/nn/autobackend.py +958 -0
  212. ultralytics/nn/modules/__init__.py +182 -0
  213. ultralytics/nn/modules/activation.py +54 -0
  214. ultralytics/nn/modules/block.py +1947 -0
  215. ultralytics/nn/modules/conv.py +669 -0
  216. ultralytics/nn/modules/head.py +1183 -0
  217. ultralytics/nn/modules/transformer.py +793 -0
  218. ultralytics/nn/modules/utils.py +159 -0
  219. ultralytics/nn/tasks.py +1768 -0
  220. ultralytics/nn/text_model.py +356 -0
  221. ultralytics/py.typed +1 -0
  222. ultralytics/solutions/__init__.py +41 -0
  223. ultralytics/solutions/ai_gym.py +108 -0
  224. ultralytics/solutions/analytics.py +264 -0
  225. ultralytics/solutions/config.py +107 -0
  226. ultralytics/solutions/distance_calculation.py +123 -0
  227. ultralytics/solutions/heatmap.py +125 -0
  228. ultralytics/solutions/instance_segmentation.py +86 -0
  229. ultralytics/solutions/object_blurrer.py +89 -0
  230. ultralytics/solutions/object_counter.py +190 -0
  231. ultralytics/solutions/object_cropper.py +87 -0
  232. ultralytics/solutions/parking_management.py +280 -0
  233. ultralytics/solutions/queue_management.py +93 -0
  234. ultralytics/solutions/region_counter.py +133 -0
  235. ultralytics/solutions/security_alarm.py +151 -0
  236. ultralytics/solutions/similarity_search.py +219 -0
  237. ultralytics/solutions/solutions.py +828 -0
  238. ultralytics/solutions/speed_estimation.py +114 -0
  239. ultralytics/solutions/streamlit_inference.py +260 -0
  240. ultralytics/solutions/templates/similarity-search.html +156 -0
  241. ultralytics/solutions/trackzone.py +88 -0
  242. ultralytics/solutions/vision_eye.py +67 -0
  243. ultralytics/trackers/__init__.py +7 -0
  244. ultralytics/trackers/basetrack.py +115 -0
  245. ultralytics/trackers/bot_sort.py +257 -0
  246. ultralytics/trackers/byte_tracker.py +469 -0
  247. ultralytics/trackers/track.py +116 -0
  248. ultralytics/trackers/utils/__init__.py +1 -0
  249. ultralytics/trackers/utils/gmc.py +339 -0
  250. ultralytics/trackers/utils/kalman_filter.py +482 -0
  251. ultralytics/trackers/utils/matching.py +154 -0
  252. ultralytics/utils/__init__.py +1450 -0
  253. ultralytics/utils/autobatch.py +118 -0
  254. ultralytics/utils/autodevice.py +205 -0
  255. ultralytics/utils/benchmarks.py +728 -0
  256. ultralytics/utils/callbacks/__init__.py +5 -0
  257. ultralytics/utils/callbacks/base.py +233 -0
  258. ultralytics/utils/callbacks/clearml.py +146 -0
  259. ultralytics/utils/callbacks/comet.py +625 -0
  260. ultralytics/utils/callbacks/dvc.py +197 -0
  261. ultralytics/utils/callbacks/hub.py +110 -0
  262. ultralytics/utils/callbacks/mlflow.py +134 -0
  263. ultralytics/utils/callbacks/neptune.py +126 -0
  264. ultralytics/utils/callbacks/platform.py +73 -0
  265. ultralytics/utils/callbacks/raytune.py +42 -0
  266. ultralytics/utils/callbacks/tensorboard.py +123 -0
  267. ultralytics/utils/callbacks/wb.py +188 -0
  268. ultralytics/utils/checks.py +998 -0
  269. ultralytics/utils/cpu.py +85 -0
  270. ultralytics/utils/dist.py +123 -0
  271. ultralytics/utils/downloads.py +529 -0
  272. ultralytics/utils/errors.py +35 -0
  273. ultralytics/utils/events.py +113 -0
  274. ultralytics/utils/export/__init__.py +7 -0
  275. ultralytics/utils/export/engine.py +237 -0
  276. ultralytics/utils/export/imx.py +315 -0
  277. ultralytics/utils/export/tensorflow.py +231 -0
  278. ultralytics/utils/files.py +219 -0
  279. ultralytics/utils/git.py +137 -0
  280. ultralytics/utils/instance.py +484 -0
  281. ultralytics/utils/logger.py +444 -0
  282. ultralytics/utils/loss.py +849 -0
  283. ultralytics/utils/metrics.py +1560 -0
  284. ultralytics/utils/nms.py +337 -0
  285. ultralytics/utils/ops.py +664 -0
  286. ultralytics/utils/patches.py +201 -0
  287. ultralytics/utils/plotting.py +1045 -0
  288. ultralytics/utils/tal.py +403 -0
  289. ultralytics/utils/torch_utils.py +984 -0
  290. ultralytics/utils/tqdm.py +440 -0
  291. ultralytics/utils/triton.py +112 -0
  292. ultralytics/utils/tuner.py +160 -0
  293. ultralytics_opencv_headless-8.3.242.dist-info/METADATA +374 -0
  294. ultralytics_opencv_headless-8.3.242.dist-info/RECORD +298 -0
  295. ultralytics_opencv_headless-8.3.242.dist-info/WHEEL +5 -0
  296. ultralytics_opencv_headless-8.3.242.dist-info/entry_points.txt +3 -0
  297. ultralytics_opencv_headless-8.3.242.dist-info/licenses/LICENSE +661 -0
  298. ultralytics_opencv_headless-8.3.242.dist-info/top_level.txt +1 -0
@@ -0,0 +1,448 @@
1
+ # Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
2
+ """
3
+ Module provides functionalities for hyperparameter tuning of the Ultralytics YOLO models for object detection, instance
4
+ segmentation, image classification, pose estimation, and multi-object tracking.
5
+
6
+ Hyperparameter tuning is the process of systematically searching for the optimal set of hyperparameters
7
+ that yield the best model performance. This is particularly crucial in deep learning models like YOLO,
8
+ where small changes in hyperparameters can lead to significant differences in model accuracy and efficiency.
9
+
10
+ Examples:
11
+ Tune hyperparameters for YOLO11n on COCO8 at imgsz=640 and epochs=10 for 300 tuning iterations.
12
+ >>> from ultralytics import YOLO
13
+ >>> model = YOLO("yolo11n.pt")
14
+ >>> model.tune(data="coco8.yaml", epochs=10, iterations=300, optimizer="AdamW", plots=False, save=False, val=False)
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ import gc
20
+ import random
21
+ import shutil
22
+ import subprocess
23
+ import time
24
+ from datetime import datetime
25
+
26
+ import numpy as np
27
+ import torch
28
+
29
+ from ultralytics.cfg import get_cfg, get_save_dir
30
+ from ultralytics.utils import DEFAULT_CFG, LOGGER, YAML, callbacks, colorstr, remove_colorstr
31
+ from ultralytics.utils.checks import check_requirements
32
+ from ultralytics.utils.patches import torch_load
33
+ from ultralytics.utils.plotting import plot_tune_results
34
+
35
+
36
+ class Tuner:
37
+ """A class for hyperparameter tuning of YOLO models.
38
+
39
+ The class evolves YOLO model hyperparameters over a given number of iterations by mutating them according to the
40
+ search space and retraining the model to evaluate their performance. Supports both local CSV storage and distributed
41
+ MongoDB Atlas coordination for multi-machine hyperparameter optimization.
42
+
43
+ Attributes:
44
+ space (dict[str, tuple]): Hyperparameter search space containing bounds and scaling factors for mutation.
45
+ tune_dir (Path): Directory where evolution logs and results will be saved.
46
+ tune_csv (Path): Path to the CSV file where evolution logs are saved.
47
+ args (dict): Configuration arguments for the tuning process.
48
+ callbacks (list): Callback functions to be executed during tuning.
49
+ prefix (str): Prefix string for logging messages.
50
+ mongodb (MongoClient): Optional MongoDB client for distributed tuning.
51
+ collection (Collection): MongoDB collection for storing tuning results.
52
+
53
+ Methods:
54
+ _mutate: Mutate hyperparameters based on bounds and scaling factors.
55
+ __call__: Execute the hyperparameter evolution across multiple iterations.
56
+
57
+ Examples:
58
+ Tune hyperparameters for YOLO11n on COCO8 at imgsz=640 and epochs=10 for 300 tuning iterations.
59
+ >>> from ultralytics import YOLO
60
+ >>> model = YOLO("yolo11n.pt")
61
+ >>> model.tune(
62
+ >>> data="coco8.yaml",
63
+ >>> epochs=10,
64
+ >>> iterations=300,
65
+ >>> plots=False,
66
+ >>> save=False,
67
+ >>> val=False
68
+ >>> )
69
+
70
+ Tune with distributed MongoDB Atlas coordination across multiple machines:
71
+ >>> model.tune(
72
+ >>> data="coco8.yaml",
73
+ >>> epochs=10,
74
+ >>> iterations=300,
75
+ >>> mongodb_uri="mongodb+srv://user:pass@cluster.mongodb.net/",
76
+ >>> mongodb_db="ultralytics",
77
+ >>> mongodb_collection="tune_results"
78
+ >>> )
79
+
80
+ Tune with custom search space:
81
+ >>> model.tune(space={"lr0": (1e-5, 1e-1), "momentum": (0.6, 0.98)})
82
+ """
83
+
84
+ def __init__(self, args=DEFAULT_CFG, _callbacks: list | None = None):
85
+ """Initialize the Tuner with configurations.
86
+
87
+ Args:
88
+ args (dict): Configuration for hyperparameter evolution.
89
+ _callbacks (list | None, optional): Callback functions to be executed during tuning.
90
+ """
91
+ self.space = args.pop("space", None) or { # key: (min, max, gain(optional))
92
+ # 'optimizer': tune.choice(['SGD', 'Adam', 'AdamW', 'NAdam', 'RAdam', 'RMSProp']),
93
+ "lr0": (1e-5, 1e-1), # initial learning rate (i.e. SGD=1E-2, Adam=1E-3)
94
+ "lrf": (0.0001, 0.1), # final OneCycleLR learning rate (lr0 * lrf)
95
+ "momentum": (0.7, 0.98, 0.3), # SGD momentum/Adam beta1
96
+ "weight_decay": (0.0, 0.001), # optimizer weight decay 5e-4
97
+ "warmup_epochs": (0.0, 5.0), # warmup epochs (fractions ok)
98
+ "warmup_momentum": (0.0, 0.95), # warmup initial momentum
99
+ "box": (1.0, 20.0), # box loss gain
100
+ "cls": (0.1, 4.0), # cls loss gain (scale with pixels)
101
+ "dfl": (0.4, 6.0), # dfl loss gain
102
+ "hsv_h": (0.0, 0.1), # image HSV-Hue augmentation (fraction)
103
+ "hsv_s": (0.0, 0.9), # image HSV-Saturation augmentation (fraction)
104
+ "hsv_v": (0.0, 0.9), # image HSV-Value augmentation (fraction)
105
+ "degrees": (0.0, 45.0), # image rotation (+/- deg)
106
+ "translate": (0.0, 0.9), # image translation (+/- fraction)
107
+ "scale": (0.0, 0.95), # image scale (+/- gain)
108
+ "shear": (0.0, 10.0), # image shear (+/- deg)
109
+ "perspective": (0.0, 0.001), # image perspective (+/- fraction), range 0-0.001
110
+ "flipud": (0.0, 1.0), # image flip up-down (probability)
111
+ "fliplr": (0.0, 1.0), # image flip left-right (probability)
112
+ "bgr": (0.0, 1.0), # image channel bgr (probability)
113
+ "mosaic": (0.0, 1.0), # image mosaic (probability)
114
+ "mixup": (0.0, 1.0), # image mixup (probability)
115
+ "cutmix": (0.0, 1.0), # image cutmix (probability)
116
+ "copy_paste": (0.0, 1.0), # segment copy-paste (probability)
117
+ "close_mosaic": (0.0, 10.0), # close dataloader mosaic (epochs)
118
+ }
119
+ mongodb_uri = args.pop("mongodb_uri", None)
120
+ mongodb_db = args.pop("mongodb_db", "ultralytics")
121
+ mongodb_collection = args.pop("mongodb_collection", "tuner_results")
122
+
123
+ self.args = get_cfg(overrides=args)
124
+ self.args.exist_ok = self.args.resume # resume w/ same tune_dir
125
+ self.tune_dir = get_save_dir(self.args, name=self.args.name or "tune")
126
+ self.args.name, self.args.exist_ok, self.args.resume = (None, False, False) # reset to not affect training
127
+ self.tune_csv = self.tune_dir / "tune_results.csv"
128
+ self.callbacks = _callbacks or callbacks.get_default_callbacks()
129
+ self.prefix = colorstr("Tuner: ")
130
+ callbacks.add_integration_callbacks(self)
131
+
132
+ # MongoDB Atlas support (optional)
133
+ self.mongodb = None
134
+ if mongodb_uri:
135
+ self._init_mongodb(mongodb_uri, mongodb_db, mongodb_collection)
136
+
137
+ LOGGER.info(
138
+ f"{self.prefix}Initialized Tuner instance with 'tune_dir={self.tune_dir}'\n"
139
+ f"{self.prefix}💡 Learn about tuning at https://docs.ultralytics.com/guides/hyperparameter-tuning"
140
+ )
141
+
142
+ def _connect(self, uri: str = "mongodb+srv://username:password@cluster.mongodb.net/", max_retries: int = 3):
143
+ """Create MongoDB client with exponential backoff retry on connection failures.
144
+
145
+ Args:
146
+ uri (str): MongoDB connection string with credentials and cluster information.
147
+ max_retries (int): Maximum number of connection attempts before giving up.
148
+
149
+ Returns:
150
+ (MongoClient): Connected MongoDB client instance.
151
+ """
152
+ check_requirements("pymongo")
153
+
154
+ from pymongo import MongoClient
155
+ from pymongo.errors import ConnectionFailure, ServerSelectionTimeoutError
156
+
157
+ for attempt in range(max_retries):
158
+ try:
159
+ client = MongoClient(
160
+ uri,
161
+ serverSelectionTimeoutMS=30000,
162
+ connectTimeoutMS=20000,
163
+ socketTimeoutMS=40000,
164
+ retryWrites=True,
165
+ retryReads=True,
166
+ maxPoolSize=30,
167
+ minPoolSize=3,
168
+ maxIdleTimeMS=60000,
169
+ )
170
+ client.admin.command("ping") # Test connection
171
+ LOGGER.info(f"{self.prefix}Connected to MongoDB Atlas (attempt {attempt + 1})")
172
+ return client
173
+ except (ConnectionFailure, ServerSelectionTimeoutError):
174
+ if attempt == max_retries - 1:
175
+ raise
176
+ wait_time = 2**attempt
177
+ LOGGER.warning(
178
+ f"{self.prefix}MongoDB connection failed (attempt {attempt + 1}), retrying in {wait_time}s..."
179
+ )
180
+ time.sleep(wait_time)
181
+
182
+ def _init_mongodb(self, mongodb_uri="", mongodb_db="", mongodb_collection=""):
183
+ """Initialize MongoDB connection for distributed tuning.
184
+
185
+ Connects to MongoDB Atlas for distributed hyperparameter optimization across multiple machines. Each worker
186
+ saves results to a shared collection and reads the latest best hyperparameters from all workers for evolution.
187
+
188
+ Args:
189
+ mongodb_uri (str): MongoDB connection string, e.g. 'mongodb+srv://username:password@cluster.mongodb.net/'.
190
+ mongodb_db (str, optional): Database name.
191
+ mongodb_collection (str, optional): Collection name.
192
+
193
+ Notes:
194
+ - Creates a fitness index for fast queries of top results
195
+ - Falls back to CSV-only mode if connection fails
196
+ - Uses connection pooling and retry logic for production reliability
197
+ """
198
+ self.mongodb = self._connect(mongodb_uri)
199
+ self.collection = self.mongodb[mongodb_db][mongodb_collection]
200
+ self.collection.create_index([("fitness", -1)], background=True)
201
+ LOGGER.info(f"{self.prefix}Using MongoDB Atlas for distributed tuning")
202
+
203
+ def _get_mongodb_results(self, n: int = 5) -> list:
204
+ """Get top N results from MongoDB sorted by fitness.
205
+
206
+ Args:
207
+ n (int): Number of top results to retrieve.
208
+
209
+ Returns:
210
+ (list[dict]): List of result documents with fitness scores and hyperparameters.
211
+ """
212
+ try:
213
+ return list(self.collection.find().sort("fitness", -1).limit(n))
214
+ except Exception:
215
+ return []
216
+
217
+ def _save_to_mongodb(self, fitness: float, hyperparameters: dict[str, float], metrics: dict, iteration: int):
218
+ """Save results to MongoDB with proper type conversion.
219
+
220
+ Args:
221
+ fitness (float): Fitness score achieved with these hyperparameters.
222
+ hyperparameters (dict[str, float]): Dictionary of hyperparameter values.
223
+ metrics (dict): Complete training metrics dictionary (mAP, precision, recall, losses, etc.).
224
+ iteration (int): Current iteration number.
225
+ """
226
+ try:
227
+ self.collection.insert_one(
228
+ {
229
+ "fitness": fitness,
230
+ "hyperparameters": {k: (v.item() if hasattr(v, "item") else v) for k, v in hyperparameters.items()},
231
+ "metrics": metrics,
232
+ "timestamp": datetime.now(),
233
+ "iteration": iteration,
234
+ }
235
+ )
236
+ except Exception as e:
237
+ LOGGER.warning(f"{self.prefix}MongoDB save failed: {e}")
238
+
239
+ def _sync_mongodb_to_csv(self):
240
+ """Sync MongoDB results to CSV for plotting compatibility.
241
+
242
+ Downloads all results from MongoDB and writes them to the local CSV file in chronological order. This enables
243
+ the existing plotting functions to work seamlessly with distributed MongoDB data.
244
+ """
245
+ try:
246
+ # Get all results from MongoDB
247
+ all_results = list(self.collection.find().sort("iteration", 1))
248
+ if not all_results:
249
+ return
250
+
251
+ # Write to CSV
252
+ headers = ",".join(["fitness", *list(self.space.keys())]) + "\n"
253
+ with open(self.tune_csv, "w", encoding="utf-8") as f:
254
+ f.write(headers)
255
+ for result in all_results:
256
+ fitness = result["fitness"]
257
+ hyp_values = [result["hyperparameters"][k] for k in self.space.keys()]
258
+ log_row = [round(fitness, 5), *hyp_values]
259
+ f.write(",".join(map(str, log_row)) + "\n")
260
+
261
+ except Exception as e:
262
+ LOGGER.warning(f"{self.prefix}MongoDB to CSV sync failed: {e}")
263
+
264
+ @staticmethod
265
+ def _crossover(x: np.ndarray, alpha: float = 0.2, k: int = 9) -> np.ndarray:
266
+ """BLX-α crossover from up to top-k parents (x[:,0]=fitness, rest=genes)."""
267
+ k = min(k, len(x))
268
+ # fitness weights (shifted to >0); fallback to uniform if degenerate
269
+ weights = x[:, 0] - x[:, 0].min() + 1e-6
270
+ if not np.isfinite(weights).all() or weights.sum() == 0:
271
+ weights = np.ones_like(weights)
272
+ idxs = random.choices(range(len(x)), weights=weights, k=k)
273
+ parents_mat = np.stack([x[i][1:] for i in idxs], 0) # (k, ng) strip fitness
274
+ lo, hi = parents_mat.min(0), parents_mat.max(0)
275
+ span = hi - lo
276
+ return np.random.uniform(lo - alpha * span, hi + alpha * span)
277
+
278
+ def _mutate(
279
+ self,
280
+ n: int = 9,
281
+ mutation: float = 0.5,
282
+ sigma: float = 0.2,
283
+ ) -> dict[str, float]:
284
+ """Mutate hyperparameters based on bounds and scaling factors specified in `self.space`.
285
+
286
+ Args:
287
+ n (int): Number of top parents to consider.
288
+ mutation (float): Probability of a parameter mutation in any given iteration.
289
+ sigma (float): Standard deviation for Gaussian random number generator.
290
+
291
+ Returns:
292
+ (dict[str, float]): A dictionary containing mutated hyperparameters.
293
+ """
294
+ x = None
295
+
296
+ # Try MongoDB first if available
297
+ if self.mongodb:
298
+ if results := self._get_mongodb_results(n):
299
+ # MongoDB already sorted by fitness DESC, so results[0] is best
300
+ x = np.array([[r["fitness"]] + [r["hyperparameters"][k] for k in self.space.keys()] for r in results])
301
+ elif self.collection.name in self.collection.database.list_collection_names(): # Tuner started elsewhere
302
+ x = np.array([[0.0] + [getattr(self.args, k) for k in self.space.keys()]])
303
+
304
+ # Fall back to CSV if MongoDB unavailable or empty
305
+ if x is None and self.tune_csv.exists():
306
+ csv_data = np.loadtxt(self.tune_csv, ndmin=2, delimiter=",", skiprows=1)
307
+ if len(csv_data) > 0:
308
+ fitness = csv_data[:, 0] # first column
309
+ order = np.argsort(-fitness)
310
+ x = csv_data[order][:n] # top-n sorted by fitness DESC
311
+
312
+ # Mutate if we have data, otherwise use defaults
313
+ if x is not None:
314
+ np.random.seed(int(time.time()))
315
+ ng = len(self.space)
316
+
317
+ # Crossover
318
+ genes = self._crossover(x)
319
+
320
+ # Mutation
321
+ gains = np.array([v[2] if len(v) == 3 else 1.0 for v in self.space.values()]) # gains 0-1
322
+ factors = np.ones(ng)
323
+ while np.all(factors == 1): # mutate until a change occurs (prevent duplicates)
324
+ mask = np.random.random(ng) < mutation
325
+ step = np.random.randn(ng) * (sigma * gains)
326
+ factors = np.where(mask, np.exp(step), 1.0).clip(0.25, 4.0)
327
+ hyp = {k: float(genes[i] * factors[i]) for i, k in enumerate(self.space.keys())}
328
+ else:
329
+ hyp = {k: getattr(self.args, k) for k in self.space.keys()}
330
+
331
+ # Constrain to limits
332
+ for k, bounds in self.space.items():
333
+ hyp[k] = round(min(max(hyp[k], bounds[0]), bounds[1]), 5)
334
+
335
+ # Update types
336
+ if "close_mosaic" in hyp:
337
+ hyp["close_mosaic"] = round(hyp["close_mosaic"])
338
+
339
+ return hyp
340
+
341
+ def __call__(self, model=None, iterations: int = 10, cleanup: bool = True):
342
+ """Execute the hyperparameter evolution process when the Tuner instance is called.
343
+
344
+ This method iterates through the specified number of iterations, performing the following steps:
345
+ 1. Sync MongoDB results to CSV (if using distributed mode)
346
+ 2. Mutate hyperparameters using the best previous results or defaults
347
+ 3. Train a YOLO model with the mutated hyperparameters
348
+ 4. Log fitness scores and hyperparameters to MongoDB and/or CSV
349
+ 5. Track the best performing configuration across all iterations
350
+
351
+ Args:
352
+ model (Model | None, optional): A pre-initialized YOLO model to be used for training.
353
+ iterations (int): The number of generations to run the evolution for.
354
+ cleanup (bool): Whether to delete iteration weights to reduce storage space during tuning.
355
+ """
356
+ t0 = time.time()
357
+ best_save_dir, best_metrics = None, None
358
+ (self.tune_dir / "weights").mkdir(parents=True, exist_ok=True)
359
+
360
+ # Sync MongoDB to CSV at startup for proper resume logic
361
+ if self.mongodb:
362
+ self._sync_mongodb_to_csv()
363
+
364
+ start = 0
365
+ if self.tune_csv.exists():
366
+ x = np.loadtxt(self.tune_csv, ndmin=2, delimiter=",", skiprows=1)
367
+ start = x.shape[0]
368
+ LOGGER.info(f"{self.prefix}Resuming tuning run {self.tune_dir} from iteration {start + 1}...")
369
+ for i in range(start, iterations):
370
+ # Linearly decay sigma from 0.2 → 0.1 over first 300 iterations
371
+ frac = min(i / 300.0, 1.0)
372
+ sigma_i = 0.2 - 0.1 * frac
373
+
374
+ # Mutate hyperparameters
375
+ mutated_hyp = self._mutate(sigma=sigma_i)
376
+ LOGGER.info(f"{self.prefix}Starting iteration {i + 1}/{iterations} with hyperparameters: {mutated_hyp}")
377
+
378
+ metrics = {}
379
+ train_args = {**vars(self.args), **mutated_hyp}
380
+ save_dir = get_save_dir(get_cfg(train_args))
381
+ weights_dir = save_dir / "weights"
382
+ try:
383
+ # Train YOLO model with mutated hyperparameters (run in subprocess to avoid dataloader hang)
384
+ launch = [__import__("sys").executable, "-m", "ultralytics.cfg.__init__"] # workaround yolo not found
385
+ cmd = [*launch, "train", *(f"{k}={v}" for k, v in train_args.items())]
386
+ return_code = subprocess.run(cmd, check=True).returncode
387
+ ckpt_file = weights_dir / ("best.pt" if (weights_dir / "best.pt").exists() else "last.pt")
388
+ metrics = torch_load(ckpt_file)["train_metrics"]
389
+ assert return_code == 0, "training failed"
390
+
391
+ # Cleanup
392
+ time.sleep(1)
393
+ gc.collect()
394
+ torch.cuda.empty_cache()
395
+
396
+ except Exception as e:
397
+ LOGGER.error(f"training failure for hyperparameter tuning iteration {i + 1}\n{e}")
398
+
399
+ # Save results - MongoDB takes precedence
400
+ fitness = metrics.get("fitness", 0.0)
401
+ if self.mongodb:
402
+ self._save_to_mongodb(fitness, mutated_hyp, metrics, i + 1)
403
+ self._sync_mongodb_to_csv()
404
+ total_mongo_iterations = self.collection.count_documents({})
405
+ if total_mongo_iterations >= iterations:
406
+ LOGGER.info(
407
+ f"{self.prefix}Target iterations ({iterations}) reached in MongoDB ({total_mongo_iterations}). Stopping."
408
+ )
409
+ break
410
+ else:
411
+ # Save to CSV only if no MongoDB
412
+ log_row = [round(fitness, 5)] + [mutated_hyp[k] for k in self.space.keys()]
413
+ headers = "" if self.tune_csv.exists() else (",".join(["fitness", *list(self.space.keys())]) + "\n")
414
+ with open(self.tune_csv, "a", encoding="utf-8") as f:
415
+ f.write(headers + ",".join(map(str, log_row)) + "\n")
416
+
417
+ # Get best results
418
+ x = np.loadtxt(self.tune_csv, ndmin=2, delimiter=",", skiprows=1)
419
+ fitness = x[:, 0] # first column
420
+ best_idx = fitness.argmax()
421
+ best_is_current = best_idx == i
422
+ if best_is_current:
423
+ best_save_dir = str(save_dir)
424
+ best_metrics = {k: round(v, 5) for k, v in metrics.items()}
425
+ for ckpt in weights_dir.glob("*.pt"):
426
+ shutil.copy2(ckpt, self.tune_dir / "weights")
427
+ elif cleanup and best_save_dir:
428
+ shutil.rmtree(best_save_dir, ignore_errors=True) # remove iteration dirs to reduce storage space
429
+
430
+ # Plot tune results
431
+ plot_tune_results(str(self.tune_csv))
432
+
433
+ # Save and print tune results
434
+ header = (
435
+ f"{self.prefix}{i + 1}/{iterations} iterations complete ✅ ({time.time() - t0:.2f}s)\n"
436
+ f"{self.prefix}Results saved to {colorstr('bold', self.tune_dir)}\n"
437
+ f"{self.prefix}Best fitness={fitness[best_idx]} observed at iteration {best_idx + 1}\n"
438
+ f"{self.prefix}Best fitness metrics are {best_metrics}\n"
439
+ f"{self.prefix}Best fitness model is {best_save_dir}"
440
+ )
441
+ LOGGER.info("\n" + header)
442
+ data = {k: float(x[best_idx, i + 1]) for i, k in enumerate(self.space.keys())}
443
+ YAML.save(
444
+ self.tune_dir / "best_hyperparameters.yaml",
445
+ data=data,
446
+ header=remove_colorstr(header.replace(self.prefix, "# ")) + "\n",
447
+ )
448
+ YAML.print(self.tune_dir / "best_hyperparameters.yaml")