
    |h4'                         d dl mZ d dlmZmZmZmZ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mZ d dlmZ  G d	 d
e      Zy)    )Path)AnyDictListTupleUnionN)ClassificationDatasetbuild_dataloader)BaseValidator)LOGGER)ClassifyMetricsConfusionMatrix)plot_imagesc                       e Zd ZdZdd fdZdefdZdej                  j                  ddfdZ
deeef   deeef   fd	Zd
ej                  deeef   ddfdZddZd
eej                  eej                     eej                     f   dej                  fdZdeeef   fdZdedefdZdeeef   dedej6                  j8                  j:                  fdZddZdeeef   deddfdZ deeef   d
ej                  deddfdZ! xZ"S )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="yolo11n-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returnc                     t         |   ||||       d| _        d| _        d| j                  _        t               | _        y)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 (list, optional): List of callback functions to be called during validation.

        Examples:
            >>> from ultralytics.models.yolo.classify import ClassificationValidator
            >>> args = dict(model="yolo11n-cls.pt", data="imagenet10")
            >>> validator = ClassificationValidator(args=args)
            >>> validator()
        Nclassify)super__init__targetspredargstaskr   metrics)self
dataloadersave_dirr   
_callbacks	__class__s        c/var/www/html/test/engine/venv/lib/python3.12/site-packages/ultralytics/models/yolo/classify/val.pyr   z ClassificationValidator.__init__6   s;      	XtZ@	#		&(    c                     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_descL   s    #'JJJr"   modelc                     |j                   | _         t        |j                         | _        g | _        g | _        t        t        |j                   j                                     | _        y)z^Initialize confusion matrix, class names, and tracking containers for predictions and targets.)namesN)	r,   lenncr   r   r   listvaluesconfusion_matrix)r   r*   s     r!   init_metricsz$ClassificationValidator.init_metricsP   sJ    [[
ekk"	 /d5;;;M;M;O6P Qr"   batchc                    |d   j                  | j                  d      |d<   | j                  j                  r|d   j                         n|d   j	                         |d<   |d   j                  | j                        |d<   |S )zTPreprocess input batch by moving data to device and converting to appropriate dtype.imgT)non_blockingcls)todevicer   halffloat)r   r3   s     r!   
preprocessz"ClassificationValidator.preprocessX   sn    U|t{{Fe.2iinnuU|((*%,BTBTBVeU|t{{3er"   predsc                    t        t        | j                        d      }| j                  j	                  |j                  dd      ddd|f   j                  t        j                        j                                | j                  j	                  |d   j                  t        j                        j                                y)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)
descendingNr7   )minr-   r,   r   appendargsorttypetorchint32cpur   )r   r=   r3   n5s       r!   update_metricsz&ClassificationValidator.update_metrics_   s     TZZ!$		qT:1crc6BGGTXXZ[E%L--ekk:>>@Ar"   c                    | j                   j                  | j                  | j                         | j                  j
                  r9dD ]4  }| j                   j                  | j                  || j                         6 | j                  | j                  _	        | j                  | j                  _        | j                   | j                  _         y)a  
        Finalize metrics including confusion matrix and processing speed.

        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.

        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
        )TF)r   	normalizeon_plotN)r1   process_cls_predsr   r   r   plotsplotr   rM   speedr   )r   rL   s     r!   finalize_metricsz(ClassificationValidator.finalize_metricso   s     	//		4<<H99??( n	%%**DMMY`d`l`l*mn!ZZ $(,(=(=%r"   c                 <    t        |t        t        f      r|d   S |S )zSExtract the primary prediction from model output if it's in a list or tuple format.r   )
isinstancer/   tuple)r   r=   s     r!   postprocessz#ClassificationValidator.postprocess   s    %edE];uQxFFr"   c                     | j                   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\\4995||(((r"   img_pathc                 \    t        || j                  d| j                  j                        S )z7Create a ClassificationDataset instance for validation.F)rootr   augmentprefix)r	   r   split)r   r[   s     r!   build_datasetz%ClassificationValidator.build_dataset   s$    $(EZ^ZcZcZiZijjr"   dataset_path
batch_sizec                 j    | j                  |      }t        ||| j                  j                  d      S )aY  
        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.
        )rank)ra   r
   r   workers)r   rb   rc   datasets       r!   get_dataloaderz&ClassificationValidator.get_dataloader   s/     $$\2TYY5F5FRPPr"   c                     ddt        | j                  j                        z  z   }t        j                  |d| j                  j
                  | j                  j                  fz         y)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   sL    hT\\%6%6!777B%!2!2DLL4E4EFFGr"   nic                     t        j                  t        |d               |d<   t        || j                  d| dz  | j
                  | j                         y)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)
        r5   	batch_idx	val_batchz_labels.jpg)labelsfnamer,   rM   N)rF   aranger-   r   r   r,   rM   )r   r3   rr   s      r!   plot_val_samplesz(ClassificationValidator.plot_val_samples   sN     #\\#eEl*;<k--IbT"==**LL		
r"   c           	          t        |d   t        j                  t        |d               t        j                  |d            }t        || j                  d| dz  | j                  | j                         y)	ae  
        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)
        r5   r@   )dim)r5   rt   r7   ru   z	_pred.jpg)rw   r,   rM   N)	dictrF   rx   r-   argmaxr   r   r,   rM   )r   r3   r=   rr   batched_predss        r!   plot_predictionsz(ClassificationValidator.plot_predictions   sh     ell3uU|#45U*

 	--IbT";;**LL		
r"   )NNNN)r   N)#__name__
__module____qualname____doc__r   strr)   rF   nnModuler2   r   r   r<   TensorrJ   rR   r   r   r   rV   r;   rZ   r	   ra   r   intutilsdata
DataLoaderri   rq   ry   r   __classcell__)r    s   @r!   r   r      s   $L),K# KR%((// Rd RS#X 4S> BELL Bc3h BD B >.Gu||T%,,5Gu||I\'\!] Gbgbnbn G)4U
+ )
kc k.C kQ5s+; Q QQVQ\Q\QaQaQlQl QH

d38n 
# 
$ 
*
d38n 
U\\ 
s 
W[ 
r"   r   )pathlibr   typingr   r   r   r   r   rF   ultralytics.datar	   r
   ultralytics.engine.validatorr   ultralytics.utilsr   ultralytics.utils.metricsr   r   ultralytics.utils.plottingr   r   r'   r"   r!   <module>r      s0     0 0  D 6 $ F 2E
m E
r"   