
    .h:)                        d dl mZ d dlZd dlZd dlmZ d dlmZ d dl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mZ d d
lmZ d dlmZmZ d dlmZm Z   G d de      Z!y)    )annotationsN)copy)Any)build_dataloaderbuild_yolo_dataset)BaseTrainer)yolo)DetectionModel)DEFAULT_CFGLOGGERRANK)override_configs)plot_imagesplot_labels)torch_distributed_zero_firstunwrap_modelc                       e Zd ZdZeddfd fdZdddZdddZddZd Z	dddZ
d	 Zddd
Zd Zd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_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()
    Nc                (    t         |   |||       y)a  
        Initialize a DetectionTrainer object for training YOLO object detection model training.

        Args:
            cfg (dict, optional): Default configuration dictionary containing training parameters.
            overrides (dict, optional): Dictionary of parameter overrides for the default configuration.
            _callbacks (list, optional): List of callback functions to be executed during training.
        N)super__init__)selfcfg	overrides
_callbacks	__class__s       b/var/www/html/ai-service/venv/lib/python3.12/site-packages/ultralytics/models/yolo/detect/train.pyr   zDetectionTrainer.__init__8   s     	i4    c           	         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)moderectstride)maxintmodelr   r$   r   argsdata)r   img_pathr"   batchgss        r   build_datasetzDetectionTrainer.build_datasetC   s]     djj\$**-4488:aPRTU!$))XudiidY]afYfoqrrr   c           	        |dv sJ d| d       t        |      5  | j                  |||      }ddd       |dk(  }t        dd      r|rt        j                  d       d}t        |||dk(  r| j                  j                  n| j                  j                  d	z  ||| j                  j                  xr |dk(  
      S # 1 sw Y   x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+   workersshufflerank	drop_last)	r   r-   getattrr   warningr   r(   r2   compile)r   dataset_path
batch_sizer4   r"   datasetr3   s          r   get_dataloaderzDetectionTrainer.get_dataloaderR   s     ''V+NtfTU)VV')$/ 	I((tZHG	I'/7FE*wNNghG)-DII%%dii>O>ORS>Sii'';DGO
 	
	I 	Is   C  C	c                p   |j                         D ]W  \  }}t        |t        j                        s!|j	                  | j
                  | j
                  j                  dk(        ||<   Y |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.
        cuda)non_blockingimg   g      ?g      ?r1   N   bilinearF)sizer"   align_corners)items
isinstancetorchTensortodevicetypefloatr(   multi_scalerandom	randranger&   imgszr$   r%   shapemathceilnn
functionalinterpolate)	r   r+   kvimgsszsfxnss	            r   preprocess_batchz!DetectionTrainer.preprocess_batcho   s    KKM 	VDAq!U\\*44$++:J:Jf:T4Ua	V U|))+c1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   9F3c                    | j                   d   | j                  _        | j                   d   | j                  _        | j                  | j                  _        y)z2Set model attributes based on dataset information.ncnamesN)r)   r'   ra   rb   r(   r   s    r   set_model_attributesz%DetectionTrainer.set_model_attributes   s;     		$

99W-

))

r   c                    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.
        ra   channels)ra   chverbose)r
   r)   r   load)r   r   weightsri   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(   r   )	
loss_namesr	   detectDetectionValidatortest_loaderrq   r   r(   	callbacksrc   s    r   get_validatorzDetectionTrainer.get_validator   sG    <{{--t}}4		?W[WeWe . 
 	
r   c                    | 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.
        /   )rr   roundrM   dictzip)r   
loss_itemsprefixr]   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)lenrr   rc   s    r   progress_stringz DetectionTrainer.progress_string   sT    vS%9!9::?
 __?
 	?

 ?
 
 	
r   c                ^    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   rq   r   )r   r+   nis      r   plot_training_samplesz&DetectionTrainer.plot_training_samples   s3     		"--Kt4"88LL		
r   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   clsrb   )rb   rq   r   N)
npconcatenatetrain_loaderr;   r   r   squeezer)   rq   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)r   r/      )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   r   )r   r(   r-   r)   r%   r   r   
auto_batch)r   train_datasetmax_num_objr   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   zdict[str, Any] | None)r/   N)r*   strr"   r   r+   z
int | None)r   r   r/   )r9   r   r:   r&   r4   r&   r"   r   )r+   r|   returnr|   )NNT)r   
str | Nonerk   r   ri   bool)Nr/   )r~   zlist[float] | Noner   r   )r+   zdict[str, Any]r   r&   r   None)__name__
__module____qualname____doc__r   r   r-   r<   r_   rd   rl   rw   r   r   r   r   r   __classcell__)r   s   @r   r   r      sU    > '4\` 	5s
:<$"
$

r/ /r   r   )"
__future__r   rS   rO   r   typingr   numpyr   rH   torch.nnrU   ultralytics.datar   r   ultralytics.engine.trainerr   ultralytics.modelsr	   ultralytics.nn.tasksr
   ultralytics.utilsr   r   r   ultralytics.utils.patchesr   ultralytics.utils.plottingr   r   ultralytics.utils.torch_utilsr   r   r    r   r   <module>r      sH    #        A 2 # / 7 7 6 ? TT/{ T/r   