o
    Wh	&                     @   s   d dl m Z  d dl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mZ d d	lmZmZmZ G d
d deZdS )    )copyN)ClassificationDatasetbuild_dataloader)BaseTrainer)yolo)ClassificationModel)DEFAULT_CFGLOGGERRANK)plot_imagesplot_results)is_parallelstrip_optimizertorch_distributed_zero_firstc                       s   e Zd ZdZeddf fdd	Zdd Zd!dd	Z fd
dZd"ddZ	d#ddZ
dd Zdd Zdd Zd$ddZdd Zdd Zdd  Z  ZS )%ClassificationTrainera  
    A class extending the BaseTrainer class for training based on a classification model.

    This trainer handles the training process for image classification tasks, supporting both YOLO classification models
    and torchvision models.

    Attributes:
        model (ClassificationModel): The classification model to be trained.
        data (dict): Dictionary containing dataset information including class names and number of classes.
        loss_names (List[str]): Names of the loss functions used during training.
        validator (ClassificationValidator): Validator instance for model evaluation.

    Methods:
        set_model_attributes: Set the model's class names from the loaded dataset.
        get_model: Return a modified PyTorch model configured for training.
        setup_model: Load, create or download model for classification.
        build_dataset: Create a ClassificationDataset instance.
        get_dataloader: Return PyTorch DataLoader with transforms for image preprocessing.
        preprocess_batch: Preprocess a batch of images and classes.
        progress_string: Return a formatted string showing training progress.
        get_validator: Return an instance of ClassificationValidator.
        label_loss_items: Return a loss dict with labelled training loss items.
        plot_metrics: Plot metrics from a CSV file.
        final_eval: Evaluate trained model and save validation results.
        plot_training_samples: Plot training samples with their annotations.

    Examples:
        >>> from ultralytics.models.yolo.classify import ClassificationTrainer
        >>> args = dict(model="yolo11n-cls.pt", data="imagenet10", epochs=3)
        >>> trainer = ClassificationTrainer(overrides=args)
        >>> trainer.train()
    Nc                    s>   |du ri }d|d< | ddu rd|d< t ||| dS )a)  
        Initialize a ClassificationTrainer object.

        This constructor sets up a trainer for image classification tasks, configuring the task type and default
        image size if not specified.

        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.

        Examples:
            >>> from ultralytics.models.yolo.classify import ClassificationTrainer
            >>> args = dict(model="yolo11n-cls.pt", data="imagenet10", epochs=3)
            >>> trainer = ClassificationTrainer(overrides=args)
            >>> trainer.train()
        Nclassifytaskimgsz   )getsuper__init__)selfcfg	overrides
_callbacks	__class__ Z/var/www/vscode/kcb/lib/python3.10/site-packages/ultralytics/models/yolo/classify/train.pyr   2   s   zClassificationTrainer.__init__c                 C   s   | j d | j_dS )z9Set the YOLO model's class names from the loaded dataset.namesN)datamodelr    r   r   r   r   set_model_attributesK   s   z*ClassificationTrainer.set_model_attributesTc                 C   s   t || jd | jd |otdkd}|r|| | D ]}| jjs,t|dr,|  t	|t
jjr<| jjr<| jj|_q| D ]}d|_qA|S )ad  
        Return a modified PyTorch model configured for training YOLO.

        Args:
            cfg (Any): Model configuration.
            weights (Any): Pre-trained model weights.
            verbose (bool): Whether to display model information.

        Returns:
            (ClassificationModel): Configured PyTorch model for classification.
        ncchannels)r%   chverbosereset_parametersT)r   r!   r
   loadmodulesargs
pretrainedhasattrr*   
isinstancetorchnnDropoutdropoutp
parametersrequires_grad)r   r   weightsr)   r"   mr5   r   r   r   	get_modelO   s   $

zClassificationTrainer.get_modelc                    sd   ddl }t| j|jjv r!|jj| j | jjrdndd| _d}nt  }t	
| j| jd  |S )z
        Load, create or download model for classification tasks.

        Returns:
            (Any): Model checkpoint if applicable, otherwise None.
        r   NIMAGENET1K_V1)r8   r%   )torchvisionstrr"   models__dict__r-   r.   r   setup_modelr   reshape_outputsr!   )r   r<   ckptr   r   r   r@   h   s   
z!ClassificationTrainer.setup_modeltrainc                 C   s   t || j|dk|dS )a  
        Create a ClassificationDataset instance given an image path and mode.

        Args:
            img_path (str): Path to the dataset images.
            mode (str): Dataset mode ('train', 'val', or 'test').
            batch (Any): Batch information (unused in this implementation).

        Returns:
            (ClassificationDataset): Dataset for the specified mode.
        rC   )rootr-   augmentprefix)r   r-   )r   img_pathmodebatchr   r   r   build_dataset{   s   z#ClassificationTrainer.build_dataset   r   c                 C   s|   t | | ||}W d   n1 sw   Y  t||| jj|d}|dkr<t| jr6|jj| jj	_
|S |jj| j_
|S )a  
        Return PyTorch DataLoader with transforms to preprocess images.

        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', 'val', or 'test' mode.

        Returns:
            (torch.utils.data.DataLoader): DataLoader for the specified dataset and mode.
        N)rankrC   )r   rJ   r   r-   workersr   r"   datasettorch_transformsmodule
transforms)r   dataset_path
batch_sizerL   rH   rN   loaderr   r   r   get_dataloader   s   

z$ClassificationTrainer.get_dataloaderc                 C   s,   |d  | j|d< |d  | j|d< |S )z+Preprocesses a batch of images and classes.imgcls)todevice)r   rI   r   r   r   preprocess_batch   s   z&ClassificationTrainer.preprocess_batchc                 C   s.   dddt | j   ddg| jddR  S )z5Returns a formatted string showing training progress.
z%11s   EpochGPU_mem	InstancesSize)len
loss_namesr#   r   r   r   progress_string   s   z%ClassificationTrainer.progress_stringc                 C   s(   dg| _ tjj| j| jt| j| jdS )z>Returns an instance of ClassificationValidator for validation.loss)r-   r   )	rb   r   r   ClassificationValidatortest_loadersave_dirr   r-   	callbacksr#   r   r   r   get_validator   s   z#ClassificationTrainer.get_validatorc                    s>    fdd| j D }|du r|S tt|dg}tt||S )a_  
        Return a loss dict with labelled training loss items tensor.

        Args:
            loss_items (torch.Tensor, optional): Loss tensor items.
            prefix (str): Prefix to prepend to loss names.

        Returns:
            (Dict[str, float] | List[str]): Dictionary of loss items or list of loss keys if loss_items is None.
        c                    s   g | ]	}  d | qS )/r   ).0xrF   r   r   
<listcomp>   s    z:ClassificationTrainer.label_loss_items.<locals>.<listcomp>N   )rb   roundfloatdictzip)r   
loss_itemsrF   keysr   rm   r   label_loss_items   s
   z&ClassificationTrainer.label_loss_itemsc                 C   s   t | jd| jd dS )zPlot metrics from a CSV file.T)filer   on_plotN)r   csvrx   r#   r   r   r   plot_metrics   s   z"ClassificationTrainer.plot_metricsc                 C   s   | j | jfD ]9}| r?t| || ju r?td| d | jj| jj_| jj	| jj_	| j|d| _
| j
dd | d qdS )z3Evaluate trained model and save validation results.z
Validating z...)r"   fitnessNon_fit_epoch_end)lastbestexistsr   r	   infor-   r!   	validatorplotsmetricspoprun_callbacks)r   fr   r   r   
final_eval   s   

z ClassificationTrainer.final_evalc                 C   sB   t |d tt|d |d d| jd| d | jd dS )z
        Plot training samples with their annotations.

        Args:
            batch (Dict[str, torch.Tensor]): Batch containing images and class labels.
            ni (int): Number of iterations.
        rV   rW   r'   train_batchz.jpg)images	batch_idxrW   fnamerx   N)r   r1   arangera   viewrg   rx   )r   rI   nir   r   r   plot_training_samples   s   
z+ClassificationTrainer.plot_training_samples)NNT)rC   N)rK   r   rC   )NrC   )__name__
__module____qualname____doc__r   r   r$   r:   r@   rJ   rU   rZ   rc   ri   rv   rz   r   r   __classcell__r   r   r   r   r      s    !




r   )r   r1   ultralytics.datar   r   ultralytics.engine.trainerr   ultralytics.modelsr   ultralytics.nn.tasksr   ultralytics.utilsr   r	   r
   ultralytics.utils.plottingr   r   ultralytics.utils.torch_utilsr   r   r   r   r   r   r   r   <module>   s   