
    |h&                         d dl Z d dlZd dlmZ d dlmZmZmZmZ d dlZ	d dl
mZ d dlmZmZ d dlmZ d dlmZ d dlmZ d dlmZmZ d d	lmZ d d
lmZmZmZ d dlmZm Z   G d de      Z!y)    N)copy)AnyDictListOptional)build_dataloaderbuild_yolo_dataset)BaseTrainer)yolo)DetectionModel)LOGGERRANK)override_configs)plot_imagesplot_labelsplot_results)de_paralleltorch_distributed_zero_firstc            	            e Zd ZdZddededee   fdZddeded	edefd
Zde	de	fdZ
d Zddee   dee   defdZd Zddeee      defdZd Zde	eef   deddfdZd Zd Z fdZ xZS ) DetectionTrainera  
    A class extending the BaseTrainer class for training based on a detection model.

    This trainer specializes in object detection tasks, handling the specific requirements for training YOLO models
    for object detection including dataset building, data loading, preprocessing, and model configuration.

    Attributes:
        model (DetectionModel): The YOLO detection model being trained.
        data (Dict): Dictionary containing dataset information including class names and number of classes.
        loss_names (tuple): Names of the loss components used in training (box_loss, cls_loss, dfl_loss).

    Methods:
        build_dataset: Build YOLO dataset for training or validation.
        get_dataloader: Construct and return dataloader for the specified mode.
        preprocess_batch: Preprocess a batch of images by scaling and converting to float.
        set_model_attributes: Set model attributes based on dataset information.
        get_model: Return a YOLO detection model.
        get_validator: Return a validator for model evaluation.
        label_loss_items: Return a loss dictionary with labeled training loss items.
        progress_string: Return a formatted string of training progress.
        plot_training_samples: Plot training samples with their annotations.
        plot_metrics: Plot metrics from a CSV file.
        plot_training_labels: Create a labeled training plot of the YOLO model.
        auto_batch: Calculate optimal batch size based on model memory requirements.

    Examples:
        >>> from ultralytics.models.yolo.detect import DetectionTrainer
        >>> args = dict(model="yolo11n.pt", data="coco8.yaml", epochs=3)
        >>> trainer = DetectionTrainer(overrides=args)
        >>> trainer.train()
    Nimg_pathmodebatchc           	          t        t        | j                  r-t        | j                        j                  j                         nd      d      }t        | j                  ||| j                  ||dk(  |      S )a  
        Build YOLO Dataset for training or validation.

        Args:
            img_path (str): Path to the folder containing images.
            mode (str): 'train' mode or 'val' mode, users are able to customize different augmentations for each mode.
            batch (int, optional): Size of batches, this is for 'rect' mode.

        Returns:
            (Dataset): YOLO dataset object configured for the specified mode.
        r       val)r   rectstride)maxintmodelr   r   r	   argsdata)selfr   r   r   gss        c/var/www/html/test/engine/venv/lib/python3.12/site-packages/ultralytics/models/yolo/detect/train.pybuild_datasetzDetectionTrainer.build_dataset6   s]     TZZ[,33779QOQST!$))XudiidY]afYfoqrr    dataset_path
batch_sizerankc                 b   |dv sJ d| d       t        |      5  | j                  |||      }ddd       |dk(  }t        dd      r|rt        j                  d       d}|dk(  r| j
                  j                  n| j
                  j                  d	z  }t        |||||      S # 1 sw Y   wxY w)
a  
        Construct and return dataloader for the specified mode.

        Args:
            dataset_path (str): Path to the dataset.
            batch_size (int): Number of images per batch.
            rank (int): Process rank for distributed training.
            mode (str): 'train' for training dataloader, 'val' for validation dataloader.

        Returns:
            (DataLoader): PyTorch dataloader object.
        >   r   trainz#Mode must be 'train' or 'val', not .Nr-   r   FzJ'rect=True' is incompatible with DataLoader shuffle, setting shuffle=False   )r   r'   getattrr   warningr"   workersr   )r$   r)   r*   r+   r   datasetshuffler2   s           r&   get_dataloaderzDetectionTrainer.get_dataloaderE   s     ''V+NtfTU)VV')$/ 	I((tZHG	I'/7FE*wNNghG'+w$))##DII<M<MPQ<QWgtLL	I 	Is   B%%B.returnc                    |d   j                  | j                  d      j                         dz  |d<   | j                  j                  r|d   }t        j                  t        | j                  j                  dz        t        | j                  j                  dz  | j                  z               | j                  z  | j                  z  }|t        |j                  dd       z  }|d	k7  ro|j                  dd D cg c]4  }t        j                  ||z  | j                  z        | j                  z  6 }}t        j                  j!                  ||d
d      }||d<   |S c c}w )a   
        Preprocess a batch of images by scaling and converting to float.

        Args:
            batch (Dict): Dictionary containing batch data with 'img' tensor.

        Returns:
            (Dict): Preprocessed batch with normalized images.
        imgT)non_blocking   g      ?g      ?r/   N   bilinearF)sizer   align_corners)todevicefloatr"   multi_scalerandom	randranger    imgszr   r   shapemathceilnn
functionalinterpolate)r$   r   imgsszsfxnss          r&   preprocess_batchz!DetectionTrainer.preprocess_batch\   s?    U|t{{FLLNQTTe99  <D  TYY__s%:!;SSVAVY]YdYdAd=ef;;++ 
 c$**QR.))BQwKO::VWVX>FGDIIa"ft{{23dkkA  }}00BZ_d0eE%Ls   ?9E$c                     | j                   d   | j                  _        | j                   d   | j                  _        | j                  | j                  _        y)z2Set model attributes based on dataset information.ncnamesN)r#   r!   rS   rT   r"   r$   s    r&   set_model_attributesz%DetectionTrainer.set_model_attributesw   s;     		$

99W-

))

r(   cfgweightsverbosec                     t        || j                  d   | j                  d   |xr	 t        dk(        }|r|j                  |       |S )aF  
        Return a YOLO detection model.

        Args:
            cfg (str, optional): Path to model configuration file.
            weights (str, optional): Path to model weights.
            verbose (bool): Whether to display model information.

        Returns:
            (DetectionModel): YOLO detection model.
        rS   channels)rS   chrY   )r   r#   r   load)r$   rW   rX   rY   r!   s        r&   	get_modelzDetectionTrainer.get_model   sF     styy499Z;PZaZpfjnpfpqJJwr(   c                     d| _         t        j                  j                  | j                  | j
                  t        | j                        | j                        S )z6Return a DetectionValidator for YOLO model validation.)box_losscls_lossdfl_loss)save_dirr"   
_callbacks)	
loss_namesr   detectDetectionValidatortest_loaderrd   r   r"   	callbacksrU   s    r&   get_validatorzDetectionTrainer.get_validator   sG    <{{--t}}4		?W[WeWe . 
 	
r(   
loss_itemsprefixc                     | j                   D cg c]	  }| d|  }}|7|D cg c]  }t        t        |      d       }}t        t	        ||            S |S c c}w c c}w )ah  
        Return a loss dict with labeled training loss items tensor.

        Args:
            loss_items (List[float], optional): List of loss values.
            prefix (str): Prefix for keys in the returned dictionary.

        Returns:
            (Dict | List): Dictionary of labeled loss items if loss_items is provided, otherwise list of keys.
        /   )rf   roundrA   dictzip)r$   rl   rm   rO   keyss        r&   label_loss_itemsz!DetectionTrainer.label_loss_items   sh     *.9A6(!A399!6@A%a!,AJAD*-..K :As
   AAc                 j    dddt        | j                        z   z  z   ddg| j                  ddz  S )z`Return a formatted string of training progress with epoch, GPU memory, loss, instances and size.
z%11s   EpochGPU_mem	InstancesSize)lenrf   rU   s    r&   progress_stringz DetectionTrainer.progress_string   sT    vS%9!9::?
 __?
 	?

 ?
 
 	
r(   nic                 ^    t        ||d   | j                  d| dz  | j                         y)z
        Plot training samples with their annotations.

        Args:
            batch (Dict[str, Any]): Dictionary containing batch data.
            ni (int): Number of iterations.
        im_filetrain_batchz.jpg)labelspathsfnameon_plotN)r   rd   r   )r$   r   r   s      r&   plot_training_samplesz&DetectionTrainer.plot_training_samples   s3     		"--Kt4"88LL		
r(   c                 F    t        | j                  | j                         y)zPlot metrics from a CSV file.)filer   N)r   csvr   rU   s    r&   plot_metricszDetectionTrainer.plot_metrics   s    $((DLL9r(   c                    t        j                  | j                  j                  j                  D cg c]  }|d   	 c}d      }t        j                  | j                  j                  j                  D cg c]  }|d   	 c}d      }t        ||j                         | j                  d   | j                  | j                         yc c}w c c}w )z1Create a labeled training plot of the YOLO model.bboxesr   clsrT   )rT   rd   r   N)
npconcatenatetrain_loaderr3   r   r   squeezer#   rd   r   )r$   lbboxesr   s       r&   plot_training_labelsz%DetectionTrainer.plot_training_labels   s    t7H7H7P7P7W7WX8XZ[\nn$2C2C2K2K2R2RSBbiSUVWE3;;=		'0BT]]dhdpdpq  YSs   C7Cc                 
   t        | j                  ddi      5 | _        | j                  | j                  d   dd      }ddd       t	        d j
                  D              d	z  }~t        |   |      S # 1 sw Y   8xY w)
z
        Get optimal batch size by calculating memory occupation of model.

        Returns:
            (int): Optimal batch size.
        cacheF)	overridesr-      )r   r   Nc              3   8   K   | ]  }t        |d            yw)r   N)r}   ).0labels     r&   	<genexpr>z.DetectionTrainer.auto_batch.<locals>.<genexpr>   s     N#eEl+Ns   rx   )r   r"   r'   r#   r   r   super
auto_batch)r$   train_datasetmax_num_obj	__class__s      r&   r   zDetectionTrainer.auto_batch   s     diiGU3CD 	[	 ..tyy/AWY.ZM	[N9M9MNNQRRw!+..		[ 	[s   'A99B)r-   N)r   r   r-   )NNT)Nr-   )__name__
__module____qualname____doc__strr   r    r'   r5   r   rQ   rV   boolr_   rk   r   rA   ru   r~   r   r   r   r   r   __classcell__)r   s   @r&   r   r      s    @sc s sxPS} sM3 MC MC M[^ M.d t 6$Xc] HSM [_ "
8DK+@ QT $

4S> 
s 
t 
:r/ /r(   r   )"rG   rC   r   typingr   r   r   r   numpyr   torch.nnrI   ultralytics.datar   r	   ultralytics.engine.trainerr
   ultralytics.modelsr   ultralytics.nn.tasksr   ultralytics.utilsr   r   ultralytics.utils.patchesr   ultralytics.utils.plottingr   r   r   ultralytics.utils.torch_utilsr   r   r    r(   r&   <module>r      sE       , ,   A 2 # / * 6 M M SE/{ E/r(   