
    h:)                        S SK Jr  S SKrS SKrS SKJr  S SKJr  S SKrS SK	r	S SK
Jr  S SKJrJr  S SKJr  S SKJr  S SKJr  S S	KJrJrJr  S S
KJr  S SKJrJr  S SKJrJ r    " S S\5      r!g)    )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                     ^  \ rS rSrSr\SS4SU 4S jjjrSSS jjrSSS jjrSS jr	S r
SSS	 jjrS
 rSSS jjrS rSS jrS rU 4S jrSrU =r$ )DetectionTrainer   aJ  
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U ]  XU5        g)ax  
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       ^/home/james-whalen/.local/lib/python3.13/site-packages/ultralytics/models/yolo/detect/train.pyr   DetectionTrainer.__init__8   s     	4    c           
         [        [        U R                  (       a-  [        U R                  5      R                  R                  5       OS5      S5      n[        U R                  XU R                  X"S:H  US9$ )au  
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_datasetDetectionTrainer.build_datasetC   sX     djj\$**-4488:aPRTU!$))XdiidafYfoqrrr    c           	        US;   d   SU S35       e[        U5         U R                  XU5      nSSS5        US:H  n[        WSS5      (       a  U(       a  [        R                  " S5        Sn[        UUUS:X  a  U R                  R                  OU R                  R                  S	-  UUU R                  R                  =(       a    US:H  S
9$ ! , (       d  f       N= f)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 .Nr2   r%   FzJ'rect=True' is incompatible with DataLoader shuffle, setting shuffle=False   )r-   workersshufflerank	drop_last)	r   r/   getattrr   warningr   r*   r5   compile)r   dataset_path
batch_sizer7   r$   datasetr6   s          r   get_dataloaderDetectionTrainer.get_dataloaderR   s     ''V+NtfTU)VV')$/((ZHG 0'/7FE**wNNghG)-DII%%dii>O>ORS>Sii'';DGO
 	
 0/s   C
Cc                   UR                  5        HY  u  p#[        U[        R                  5      (       d  M&  UR	                  U R
                  U R
                  R                  S:H  S9X'   M[     US   R                  5       S-  US'   U R                  R                  (       Ga  US   n[        R                  " [        U R                  R                  S-  5      [        U R                  R                  S-  U R                  -   5      5      U R                  -  U R                  -  nU[        UR                   SS 5      -  nUS	:w  an  UR                   SS  Vs/ s H5  n["        R$                  " Xv-  U R                  -  5      U R                  -  PM7     nn[&        R(                  R+                  XHS
SS9nXAS'   U$ s  snf )z
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      ?r4   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_batch!DetectionTrainer.preprocess_batcho   sx    KKMDA!U\\**44$++:J:Jf:T4U " U|))+c1e99   <D  TYY__s%:!;SSVAVY]YdYdAd=ef;;++ 
 c$**QR.))BQwKO::VWVX>KYaDIIaft{{23dkkA>   }}00Z_d0e%Ls   <F;c                    U R                   S   U R                  l        U R                   S   U R                  l        U R                  U R                  l        g)z2Set model attributes based on dataset information.ncnamesN)r+   r)   rf   rg   r*   r   s    r   set_model_attributes%DetectionTrainer.set_model_attributes   s;     		$

99W-

))

r    c                    [        XR                  S   U R                  S   U=(       a	    [        S:H  S9nU(       a  UR                  U5        U$ )a  
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.
rf   channels)rf   chverbose)r
   r+   r   load)r   r   weightsro   r)   s        r   	get_modelDetectionTrainer.get_model   sD     syy499Z;PZaZpfjnpfpqJJwr    c                    SU l         [        R                  R                  U R                  U R
                  [        U R                  5      U R                  S9$ )z6Return a DetectionValidator for YOLO model validation.)box_losscls_lossdfl_loss)save_dirr*   r   )	
loss_namesr	   detectDetectionValidatortest_loaderrx   r   r*   	callbacksrh   s    r   get_validatorDetectionTrainer.get_validator   sG    <{{--t}}4		?W[WeWe . 
 	
r    c                    U R                    Vs/ s H	  o2 SU 3PM     nnUb9  U Vs/ s H  n[        [        U5      S5      PM     nn[        [	        XA5      5      $ U$ s  snf s  snf )a0  
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.
/   )ry   roundrQ   dictzip)r   
loss_itemsprefixra   keyss        r   label_loss_items!DetectionTrainer.label_loss_items   sf     *.9A(!A39!6@Aj%a!,jJAD-..K :As
   AA$c                j    SSS[        U R                  5      -   -  -   SS/U R                  QSPSP7-  $ )z`Return a formatted string of training progress with epoch, GPU memory, loss, instances and size.
z%11s   EpochGPU_mem	InstancesSize)lenry   rh   s    r   progress_string DetectionTrainer.progress_string   sT    vS%9!9::?
 __?
 	?

 ?
 
 	
r    c                X    [        UUS   U R                  SU S3-  U R                  S9  g)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   rx   r   )r   r-   nis      r   plot_training_samples&DetectionTrainer.plot_training_samples   s3     		"--Kt4"88LL		
r    c                   [         R                  " U R                  R                  R                   Vs/ s H  oS   PM	     snS5      n[         R                  " U R                  R                  R                   Vs/ s H  oS   PM	     snS5      n[        X#R                  5       U R                  S   U R                  U R                  S9  gs  snf s  snf )z1Create a labeled training plot of the YOLO model.bboxesr   clsrg   )rg   rx   r   N)
npconcatenatetrain_loaderr>   r   r   squeezer+   rx   r   )r   lbboxesr   s       r   plot_training_labels%DetectionTrainer.plot_training_labels   s    t7H7H7P7P7W7WX7W87WXZ[\nn$2C2C2K2K2R2RS2RBi2RSUVWE;;=		'0BT]]dhdpdpq  YSs   C;Cc                  > [        U R                  SS0S9 U l        U R                  U R                  S   SSS9nSSS5        [	        S WR
                   5       5      S	-  nA[        TU ]  U5      $ ! , (       d  f       N== f)
zl
Get optimal batch size by calculating memory occupation of model.

Returns:
    (int): Optimal batch size.
cacheF)r   r2      )r$   r-   Nc              3  >   #    U  H  n[        US    5      v   M     g7f)r   N)r   ).0labels     r   	<genexpr>.DetectionTrainer.auto_batch.<locals>.<genexpr>   s     N9M#eEl++9Ms   r   )r   r*   r/   r+   r'   r   r   
auto_batch)r   train_datasetmax_num_objr   s      r   r   DetectionTrainer.auto_batch   s|     diiGU3CD	 ..tyy/AWY.ZM EN9M9MNNQRRw!+..	 EDs   $A33
B)r*   ry   )r   zdict[str, Any] | None)r2   N)r,   strr$   r   r-   z
int | None)r   r   r2   )r<   r   r=   r(   r7   r(   r$   r   )r-   r   returnr   )NNT)r   
str | Nonerq   r   ro   bool)Nr2   )r   zlist[float] | Noner   r   )r-   zdict[str, Any]r   r(   r   None)__name__
__module____qualname____firstlineno____doc__r   r   r/   r?   rc   ri   rr   r~   r   r   r   r   r   __static_attributes____classcell__)r   s   @r   r   r      sZ    > '4\` 	5 	5s
:<$"
$

r/ /r    r   )"
__future__r   rW   rS   r   typingr   numpyr   rL   torch.nnrY   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    