a
    yf>.                     @   s   d Z ddlZddlZddlZddlZddlZddlZddlm	Z	m
Z
 ddlmZmZmZmZmZmZmZ ddlmZ G dd dZdS )a?  
Module provides functionalities for hyperparameter tuning of the Ultralytics YOLO models for object detection, instance
segmentation, image classification, pose estimation, and multi-object tracking.

Hyperparameter tuning is the process of systematically searching for the optimal set of hyperparameters
that yield the best model performance. This is particularly crucial in deep learning models like YOLO,
where small changes in hyperparameters can lead to significant differences in model accuracy and efficiency.

Example:
    Tune hyperparameters for YOLOv8n on COCO8 at imgsz=640 and epochs=30 for 300 tuning iterations.
    ```python
    from ultralytics import YOLO

    model = YOLO("yolov8n.pt")
    model.tune(data="coco8.yaml", epochs=10, iterations=300, optimizer="AdamW", plots=False, save=False, val=False)
    ```
    N)get_cfgget_save_dir)DEFAULT_CFGLOGGER	callbackscolorstrremove_colorstr
yaml_print	yaml_save)plot_tune_resultsc                   @   s2   e Zd ZdZedfddZdd	d
ZdddZdS )TuneraE  
    Class responsible for hyperparameter tuning of YOLO models.

    The class evolves YOLO model hyperparameters over a given number of iterations
    by mutating them according to the search space and retraining the model to evaluate their performance.

    Attributes:
        space (dict): Hyperparameter search space containing bounds and scaling factors for mutation.
        tune_dir (Path): Directory where evolution logs and results will be saved.
        tune_csv (Path): Path to the CSV file where evolution logs are saved.

    Methods:
        _mutate(hyp: dict) -> dict:
            Mutates the given hyperparameters within the bounds specified in `self.space`.

        __call__():
            Executes the hyperparameter evolution across multiple iterations.

    Example:
        Tune hyperparameters for YOLOv8n on COCO8 at imgsz=640 and epochs=30 for 300 tuning iterations.
        ```python
        from ultralytics import YOLO

        model = YOLO("yolov8n.pt")
        model.tune(data="coco8.yaml", epochs=10, iterations=300, optimizer="AdamW", plots=False, save=False, val=False)
        ```

        Tune with custom search space.
        ```python
        from ultralytics import YOLO

        model = YOLO("yolov8n.pt")
        model.tune(space={key1: val1, key2: val2})  # custom search space dictionary
        ```
    Nc                 C   s   | ddp>ddddddd	d
dddddddddddddddd| _t|d| _t| jdd| _| jd | _|ptt | _t	d| _
t|  t| j
 d| j d| j
 d dS )z
        Initialize the Tuner with configurations.

        Args:
            args (dict, optional): Configuration for hyperparameter evolution.
        spaceN)gh㈵>皙?)g-C6?r   )gffffff?g\(\?333333?)        gMbP?)r   g      @)r   gffffff?)      ?g      4@)皙?g      @)g?g      @)r   r   )r   g?)r   g     F@)r   g      $@)r   r   )Zlr0ZlrfZmomentumZweight_decayZwarmup_epochsZwarmup_momentumboxclsZdflZhsv_hZhsv_sZhsv_vdegrees	translatescaleZshearZperspectiveZflipudZfliplrZbgrZmosaicZmixupZ
copy_paste)Z	overridesZtune)nameztune_results.csvzTuner: z*Initialized Tuner instance with 'tune_dir=z'
uT   💡 Learn about tuning at https://docs.ultralytics.com/guides/hyperparameter-tuning)popr   r   argsr   tune_dirtune_csvr   Zget_default_callbacksr   prefixZadd_integration_callbacksr   info)selfr   
_callbacks r!   T/var/www/html/django/DPS/env/lib/python3.9/site-packages/ultralytics/engine/tuner.py__init__F   sH    

zTuner.__init__single   皙?r   c                    s   j  rtj j dddddddf }t|t}t|  d| dddf dddf   d }|dkstdkrtjt	||d	d  n&|d
krԈ|
|d d|  tj}|tt  tdd  j D }t j}	t|	tdkr`|||	|k  ||	 |  | d ddqfddt j D }
n fdd j D }
 j D ]H\}t|
| d |
|< t|
| d |
|< t|
| d|
|< q|
S )a  
        Mutates the hyperparameters based on bounds and scaling factors specified in `self.space`.

        Args:
            parent (str): Parent selection method: 'single' or 'weighted'.
            n (int): Number of parents to consider.
            mutation (float): Probability of a parameter mutation in any given iteration.
            sigma (float): Standard deviation for Gaussian random number generator.

        Returns:
            (dict): A dictionary containing mutated hyperparameters.
           ,   Zndmin	delimiterZskiprowsNr   gư>r$   )weightsZweightedc                 S   s(   g | ] \}}t |d kr |d ndqS )   r'   r   )len.0kvr!   r!   r"   
<listcomp>       z!Tuner._mutate.<locals>.<listcomp>r   g      @c                    s*   i | ]"\}}|t |d    |  qS r)   floatr0   ir1   )r2   xr!   r"   
<dictcomp>   r4   z!Tuner._mutate.<locals>.<dictcomp>c                    s   i | ]}|t  j|qS r!   )getattrr   r0   r1   )r   r!   r"   r;      r4   r%   )r   existsnploadtxtminr.   ZargsortrandomchoicesrangeZreshapesumseedinttimearrayr   itemsZonesallZrandnZclip	enumeratekeysmaxround)r   parentnZmutationsigmafitnesswrgngZhypr1   r!   )r   r2   r:   r"   _mutater   s0    (

8 zTuner._mutate
   Tc                    sT  t   }d\}}| jd jddd t|D ] }|  t| j d|d  d| d  i }i t| j	}	t
t|	}
|
d }zdd	d
gdd |	 D }tj|ddj}||d  rdnd }t|d }|dksJ dW n@ ty. } z&td|d  d|  W Y d}~n
d}~0 0 |dd}t|dgfdd| j D  }| j rpdnddgt| j  d }t| jd.}||dtt| d  W d   n1 s0    Y  t j!| jdddddddf }|"   |k}|rP|
}d d! | D }|#d"D ]}t$%|| jd  q4n|rdt$j&|dd# t'| j | j |d  d| d$t   | d%d&| j d't(d(| j d| j d)|   d* d  d| j d+| d| j d,| d| j d-}td|   fd.d!t)| j D }t*| jd/ |t+|,| jd0d d1 t-| jd/  q,dS )2a  
        Executes the hyperparameter evolution process when the Tuner instance is called.

        This method iterates through the number of iterations, performing the following steps in each iteration:
        1. Load the existing hyperparameters or initialize new ones.
        2. Mutate the hyperparameters using the `mutate` method.
        3. Train a YOLO model with the mutated hyperparameters.
        4. Log the fitness score and mutated hyperparameters to a CSV file.

        Args:
           model (Model): A pre-initialized YOLO model to be used for training.
           iterations (int): The number of generations to run the evolution for.
           cleanup (bool): Whether to delete iteration weights to reduce storage space used during tuning.

        Note:
           The method utilizes the `self.tune_csv` Path object to read and log hyperparameters and fitness scores.
           Ensure this path is set correctly in the Tuner instance.
        )NNr,   T)parentsexist_okzStarting iteration r)   /z with hyperparameters: Zyolotrainc                 s   s    | ]\}}| d | V  qdS )=Nr!   r/   r!   r!   r"   	<genexpr>   r4   z!Tuner.__call__.<locals>.<genexpr>)checkzbest.ptzlast.ptZtrain_metricsr   ztraining faileduD   WARNING ❌️ training failure for hyperparameter tuning iteration 
NrS   r   r%   c                    s   g | ]} | qS r!   r!   r=   )mutated_hypr!   r"   r3      r4   z"Tuner.__call__.<locals>.<listcomp> r(   ar'   r*   c                 S   s   i | ]\}}|t |d qS )r%   )rO   r/   r!   r!   r"   r;      r4   z"Tuner.__call__.<locals>.<dictcomp>z*.pt)ignore_errorsu    iterations complete ✅ (z.2fzs)
zResults saved to boldzBest fitness=z observed at iteration zBest fitness metrics are zBest fitness model is z0Best fitness hyperparameters are printed below.
c                    s&   i | ]\}}|t  |d  f qS r5   r6   r8   )best_idxr:   r!   r"   r;      r4   zbest_hyperparameters.yamlz# )dataheader).rH   r   mkdirrD   rX   r   r   r   varsr   r   r   rJ   
subprocessrun
returncoder>   torchload	ExceptionwarninggetrO   r   rM   r   joinlistopenwritemapstrr?   r@   Zargmaxglobshutilcopy2rmtreer   r   rL   r
   r   replacer	   )r   modelZ
iterationscleanupt0Zbest_save_dirZbest_metricsr9   ZmetricsZ
train_argssave_dirZweights_dircmdZreturn_codeZ	ckpt_fileerS   Zlog_rowheadersfZbest_is_currentZckptri   rh   r!   )rg   rb   r:   r"   __call__   s    &0$.>
&
zTuner.__call__)r$   r%   r&   r   )NrY   T)__name__
__module____qualname____doc__r   r#   rX   r   r!   r!   r!   r"   r   !   s   $,
.r   )r   rB   r{   rl   rH   numpyr?   ro   Zultralytics.cfgr   r   Zultralytics.utilsr   r   r   r   r   r	   r
   Zultralytics.utils.plottingr   r   r!   r!   r!   r"   <module>   s   $