defrun_ray_tune(model,space:dict=None,grace_period:int=10,gpu_per_trial:int=None,max_samples:int=10,**train_args,):""" Run hyperparameter tuning using Ray Tune. Args: model (YOLO): Model to run the tuner on. space (dict, optional): The hyperparameter search space. grace_period (int, optional): The grace period in epochs of the ASHA scheduler. gpu_per_trial (int, optional): The number of GPUs to allocate per trial. max_samples (int, optional): The maximum number of trials to run. **train_args (Any): Additional arguments to pass to the `train()` method. Returns: (dict): A dictionary containing the results of the hyperparameter search. Examples: >>> from ultralytics import YOLO >>> model = YOLO("yolo11n.pt") # Load a YOLO11n model Start tuning hyperparameters for YOLO11n training on the COCO8 dataset >>> result_grid = model.tune(data="coco8.yaml", use_ray=True) """LOGGER.info("💡 Learn about RayTune at https://docs.ultralytics.com/integrations/ray-tune")iftrain_argsisNone:train_args={}try:checks.check_requirements("ray[tune]")importrayfromrayimporttunefromray.airimportRunConfigfromray.air.integrations.wandbimportWandbLoggerCallbackfromray.tune.schedulersimportASHASchedulerexceptImportError:raiseModuleNotFoundError('Ray Tune required but not found. To install run: pip install "ray[tune]"')try:importwandbasserthasattr(wandb,"__version__")except(ImportError,AssertionError):wandb=Falsechecks.check_version(ray.__version__,">=2.0.0","ray")default_space={# 'optimizer': tune.choice(['SGD', 'Adam', 'AdamW', 'NAdam', 'RAdam', 'RMSProp']),"lr0":tune.uniform(1e-5,1e-1),"lrf":tune.uniform(0.01,1.0),# final OneCycleLR learning rate (lr0 * lrf)"momentum":tune.uniform(0.6,0.98),# SGD momentum/Adam beta1"weight_decay":tune.uniform(0.0,0.001),# optimizer weight decay"warmup_epochs":tune.uniform(0.0,5.0),# warmup epochs (fractions ok)"warmup_momentum":tune.uniform(0.0,0.95),# warmup initial momentum"box":tune.uniform(0.02,0.2),# box loss gain"cls":tune.uniform(0.2,4.0),# cls loss gain (scale with pixels)"hsv_h":tune.uniform(0.0,0.1),# image HSV-Hue augmentation (fraction)"hsv_s":tune.uniform(0.0,0.9),# image HSV-Saturation augmentation (fraction)"hsv_v":tune.uniform(0.0,0.9),# image HSV-Value augmentation (fraction)"degrees":tune.uniform(0.0,45.0),# image rotation (+/- deg)"translate":tune.uniform(0.0,0.9),# image translation (+/- fraction)"scale":tune.uniform(0.0,0.9),# image scale (+/- gain)"shear":tune.uniform(0.0,10.0),# image shear (+/- deg)"perspective":tune.uniform(0.0,0.001),# image perspective (+/- fraction), range 0-0.001"flipud":tune.uniform(0.0,1.0),# image flip up-down (probability)"fliplr":tune.uniform(0.0,1.0),# image flip left-right (probability)"bgr":tune.uniform(0.0,1.0),# image channel BGR (probability)"mosaic":tune.uniform(0.0,1.0),# image mixup (probability)"mixup":tune.uniform(0.0,1.0),# image mixup (probability)"copy_paste":tune.uniform(0.0,1.0),# segment copy-paste (probability)}# Put the model in ray storetask=model.taskmodel_in_store=ray.put(model)def_tune(config):"""Train the YOLO model with the specified hyperparameters."""model_to_train=ray.get(model_in_store)# get the model from ray store for tuningmodel_to_train.reset_callbacks()config.update(train_args)results=model_to_train.train(**config)returnresults.results_dict# Get search spaceifnotspace:space=default_spaceLOGGER.warning("WARNING ⚠️ search space not provided, using default search space.")# Get datasetdata=train_args.get("data",TASK2DATA[task])space["data"]=dataif"data"notintrain_args:LOGGER.warning(f'WARNING ⚠️ data not provided, using default "data={data}".')# Define the trainable function with allocated resourcestrainable_with_resources=tune.with_resources(_tune,{"cpu":NUM_THREADS,"gpu":gpu_per_trialor0})# Define the ASHA scheduler for hyperparameter searchasha_scheduler=ASHAScheduler(time_attr="epoch",metric=TASK2METRIC[task],mode="max",max_t=train_args.get("epochs")orDEFAULT_CFG_DICT["epochs"]or100,grace_period=grace_period,reduction_factor=3,)# Define the callbacks for the hyperparameter searchtuner_callbacks=[WandbLoggerCallback(project="YOLOv8-tune")]ifwandbelse[]# Create the Ray Tune hyperparameter search tunertune_dir=get_save_dir(get_cfg(DEFAULT_CFG,train_args),name=train_args.pop("name","tune")).resolve()# must be absolute dirtune_dir.mkdir(parents=True,exist_ok=True)tuner=tune.Tuner(trainable_with_resources,param_space=space,tune_config=tune.TuneConfig(scheduler=asha_scheduler,num_samples=max_samples),run_config=RunConfig(callbacks=tuner_callbacks,storage_path=tune_dir),)# Run the hyperparameter searchtuner.fit()# Get the results of the hyperparameter searchresults=tuner.get_results()# Shut down Ray to clean up workersray.shutdown()returnresults