
    /j)                        d dl mZ d dlmZ d dl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mZ d dlmZmZ d d	lmZ  G d
 de          ZdS )    )annotations)Path)AnyN)ClassificationDatasetbuild_dataloader)BaseValidator)LOGGERRANK)ClassifyMetricsConfusionMatrix)plot_imagesc                       e Zd ZdZd&d' fdZd(d	Zd)dZd*dZd+dZd,dZ	d-dZ
d.dZd,dZd/dZd0d!Zd,d"Zd1d$Zd2d%Z xZS )3ClassificationValidatora  A class extending the BaseValidator class for validation based on a classification model.

    This validator handles the validation process for classification models, including metrics calculation, confusion
    matrix generation, and visualization of results.

    Attributes:
        targets (list[torch.Tensor]): Ground truth class labels.
        pred (list[torch.Tensor]): Model predictions.
        metrics (ClassifyMetrics): Object to calculate and store classification metrics.
        names (dict): Mapping of class indices to class names.
        nc (int): Number of classes.
        confusion_matrix (ConfusionMatrix): Matrix to evaluate model performance across classes.

    Methods:
        get_desc: Return a formatted string summarizing classification metrics.
        init_metrics: Initialize confusion matrix, class names, and tracking containers.
        preprocess: Preprocess input batch by moving data to device.
        update_metrics: Update running metrics with model predictions and batch targets.
        finalize_metrics: Finalize metrics including confusion matrix and processing speed.
        postprocess: Extract the primary prediction from model output.
        get_stats: Calculate and return a dictionary of metrics.
        build_dataset: Create a ClassificationDataset instance for validation.
        get_dataloader: Build and return a data loader for classification validation.
        print_results: Print evaluation metrics for the classification model.
        plot_val_samples: Plot validation image samples with their ground truth labels.
        plot_predictions: Plot images with their predicted class labels.

    Examples:
        >>> from ultralytics.models.yolo.classify import ClassificationValidator
        >>> args = dict(model="yolo26n-cls.pt", data="imagenet10")
        >>> validator = ClassificationValidator(args=args)
        >>> validator()

    Notes:
        Torchvision classification models can also be passed to the 'model' argument, i.e. model='resnet18'.
    N
_callbacksdict | NonereturnNonec                    t                                          ||||           d| _        d| _        d| j        _        t                      | _        dS )a  Initialize ClassificationValidator with dataloader, save directory, and other parameters.

        Args:
            dataloader (torch.utils.data.DataLoader, optional): DataLoader to use for validation.
            save_dir (str | Path, optional): Directory to save results.
            args (dict, optional): Arguments containing model and validation configuration.
            _callbacks (dict, optional): Dictionary of callback functions to be called during validation.
        Nclassify)super__init__targetspredargstaskr   metrics)self
dataloadersave_dirr   r   	__class__s        i/home/longshao/multi-rider-rag/.venv/lib/python3.11/site-packages/ultralytics/models/yolo/classify/val.pyr   z ClassificationValidator.__init__8   sK     	XtZ@@@	#	&((    strc                    ddz  S )z=Return a formatted string summarizing classification metrics.z%22s%11s%11s)classestop1_acctop5_acc r   s    r!   get_descz ClassificationValidator.get_descG   s    #'JJJr"   modeltorch.nn.Modulec                    |j         | _         t          |j                   | _        g | _        g | _        t          |j                   | _        dS )z^Initialize confusion matrix, class names, and tracking containers for predictions and targets.)namesN)r.   lenncr   r   r   confusion_matrix)r   r+   s     r!   init_metricsz$ClassificationValidator.init_metricsK   sE    [
ek""	 /ek B B Br"   batchdict[str, Any]c                X   |d                              | j        | j        j        dk              |d<   | j        j        r|d                                         n|d                                         |d<   |d                              | j        | j        j        dk              |d<   |S )zTPreprocess input batch by moving data to device and converting to appropriate dtype.imgcuda)non_blockingcls)todevicetyper   halffloat)r   r3   s     r!   
preprocessz"ClassificationValidator.preprocessS   s    U|t{AQU[A[\\e.2inVuU|((***%,BTBTBVBVeU|t{AQU[A[\\er"   predstorch.Tensorc                   t          t          | j                  d          }| j                            |                    dd          ddd|f                             t          j                  	                                           | j
                            |d                             t          j                  	                                           dS )a  Update running metrics with model predictions and batch targets.

        Args:
            preds (torch.Tensor): Model predictions, typically logits or probabilities for each class.
            batch (dict): Batch data containing images and class labels.

        Notes:
            This method appends the top-N predictions (sorted by confidence in descending order) to the
            prediction list for later evaluation. N is limited to the minimum of 5 and the number of classes.
              T)
descendingNr9   )minr/   r.   r   appendargsortr<   torchint32cpur   )r   r@   r3   n5s       r!   update_metricsz&ClassificationValidator.update_metricsZ   s     TZ!$$	qT::111crc6BGGTTXXZZ[[[E%L--ek::>>@@AAAAAr"   c                &   | j                             | j        | j                   | j        j        r,dD ])}| j                             | j        || j                   *| j	        | j
        _	        | j        | j
        _        | j         | j
        _         dS )a  Finalize metrics including confusion matrix and processing speed.

        Examples:
            >>> validator = ClassificationValidator()
            >>> validator.pred = [torch.tensor([[0, 1, 2]])]  # Top-3 predictions for one sample
            >>> validator.targets = [torch.tensor([0])]  # Ground truth class
            >>> validator.finalize_metrics()
            >>> print(validator.metrics.confusion_matrix)  # Access the confusion matrix

        Notes:
            This method processes the accumulated predictions and targets to generate the confusion matrix,
            optionally plots it, and updates the metrics object with speed information.
        )TF)r   	normalizeon_plotN)r1   process_cls_predsr   r   r   plotsplotr   rP   speedr   )r   rO   s     r!   finalize_metricsz(ClassificationValidator.finalize_metricsi   s     	//	4<HHH9? 	n( n n	%**DMY`d`l*mmmm!Z $(,(=%%%r"   7torch.Tensor | list[torch.Tensor] | tuple[torch.Tensor]c                N    t          |t          t          f          r|d         n|S )zSExtract the primary prediction from model output if it's in a list or tuple format.r   )
isinstancelisttuple)r   r@   s     r!   postprocessz#ClassificationValidator.postprocess   s#    %edE];;FuQxxFr"   dict[str, float]c                d    | j                             | j        | j                   | j         j        S )zSCalculate and return a dictionary of metrics by processing targets and predictions.)r   processr   r   results_dictr)   s    r!   	get_statsz!ClassificationValidator.get_stats   s)    T\49555|((r"   c                   t           dk    rdgt          j                    z  }dgt          j                    z  }t          j        | j        |d           t          j        | j        |d           d |D             | _        d |D             | _        dS t           dk    r:t          j        | j        dd           t          j        | j        dd           dS dS )zGather stats from all GPUs.r   N)dstc                    g | ]	}|D ]}|
S r(   r(   ).0rankr   s      r!   
<listcomp>z8ClassificationValidator.gather_stats.<locals>.<listcomp>   s%    JJJ$TJJTJJJJr"   c                    g | ]	}|D ]}|
S r(   r(   )rd   re   r   s      r!   rf   z8ClassificationValidator.gather_stats.<locals>.<listcomp>   s&    UUUPTUUWGUUUUr"   )r
   distget_world_sizegather_objectr   r   )r   gathered_predsgathered_targetss      r!   gather_statsz$ClassificationValidator.gather_stats   s    199"Vd&9&;&;;N $v(;(=(==ty.a@@@@t|-=1EEEEJJ.JJJDIUU0@UUUDLLLAXXty$A6666t|Tq999999 Xr"   img_pathr   c                F    t          || j        d| j        j                  S )z7Create a ClassificationDataset instance for validation.F)rootr   augmentprefix)r   r   split)r   rn   s     r!   build_datasetz%ClassificationValidator.build_dataset   s"    $(EZ^ZcZijjjjr"   dataset_path
Path | str
batch_sizeinttorch.utils.data.DataLoaderc                f    |                      |          }t          ||| j        j        d          S )aP  Build and return a data loader for classification validation.

        Args:
            dataset_path (str | Path): Path to the dataset directory.
            batch_size (int): Number of samples per batch.

        Returns:
            (torch.utils.data.DataLoader): DataLoader object for the classification validation dataset.
        )re   )rt   r   r   workers)r   ru   rw   datasets       r!   get_dataloaderz&ClassificationValidator.get_dataloader   s3     $$\22TY5FRPPPPr"   c                    ddt          | j        j                  z  z   }t          j        |d| j        j        | j        j        fz             dS )z6Print evaluation metrics for the classification model.z%22sz%11.3gallN)r/   r   keysr	   infotop1top5)r   pfs     r!   print_resultsz%ClassificationValidator.print_results   sJ    hT\%6!7!777B%!2DL4EFFGGGGGr"   nic                    t          j        |d         j        d                   |d<   t          || j        d| dz  | j        | j                   dS )a  Plot validation image samples with their ground truth labels.

        Args:
            batch (dict[str, Any]): Dictionary containing batch data with 'img' (images) and 'cls' (class labels).
            ni (int): Batch index used for naming the output file.

        Examples:
            >>> validator = ClassificationValidator()
            >>> batch = {"img": torch.rand(16, 3, 224, 224), "cls": torch.randint(0, 10, (16,))}
            >>> validator.plot_val_samples(batch, 0)
        r6   r   	batch_idx	val_batchz_labels.jpg)labelsfnamer.   rP   N)rI   arangeshaper   r   r.   rP   )r   r3   r   s      r!   plot_val_samplesz(ClassificationValidator.plot_val_samples   sh     #\%,*<Q*?@@k-"=b"="="==*L		
 	
 	
 	
 	
 	
r"   c           	         t          |d         t          j        |d         j        d                   t          j        |d          t          j        |d                    }t          || j        d| dz  | j        | j	                   d	S )
a\  Plot images with their predicted class labels and save the visualization.

        Args:
            batch (dict[str, Any]): Batch data containing images and other information.
            preds (torch.Tensor): Model predictions with shape (batch_size, num_classes).
            ni (int): Batch index used for naming the output file.

        Examples:
            >>> validator = ClassificationValidator()
            >>> batch = {"img": torch.rand(16, 3, 224, 224)}
            >>> preds = torch.rand(16, 10)  # 16 images, 10 classes
            >>> validator.plot_predictions(batch, preds, 0)
        r6   r   rD   )dim)r6   r   r9   confr   z	_pred.jpg)r   r.   rP   N)
dictrI   r   r   argmaxamaxr   r   r.   rP   )r   r3   r@   r   batched_predss        r!   plot_predictionsz(ClassificationValidator.plot_predictions   s     el5<#5a#899U***Eq)))	
 
 
 	-";b";";";;*L		
 	
 	
 	
 	
 	
r"   )NNNN)r   r   r   r   )r   r#   )r+   r,   r   r   )r3   r4   r   r4   )r@   rA   r3   r4   r   r   )r   r   )r@   rV   r   rA   )r   r\   )rn   r#   r   r   )ru   rv   rw   rx   r   ry   )r3   r4   r   rx   r   r   )r3   r4   r@   rA   r   rx   r   r   )__name__
__module____qualname____doc__r   r*   r2   r?   rM   rU   r[   r`   rm   rt   r~   r   r   r   __classcell__)r    s   @r!   r   r      sm       # #J) ) ) ) ) ) )K K K KC C C C   B B B B> > > >,G G G G) ) ) )
: : : :k k k kQ Q Q QH H H H

 
 
 
(
 
 
 
 
 
 
 
r"   r   )
__future__r   pathlibr   typingr   rI   torch.distributeddistributedrh   ultralytics.datar   r   ultralytics.engine.validatorr   ultralytics.utilsr	   r
   ultralytics.utils.metricsr   r   ultralytics.utils.plottingr   r   r(   r"   r!   <module>r      s   # " " " " "                          D D D D D D D D 6 6 6 6 6 6 * * * * * * * * F F F F F F F F 2 2 2 2 2 2F
 F
 F
 F
 F
m F
 F
 F
 F
 F
r"   