o
    .wi                     @   sH  d dl mZmZmZ d dlZd dlmZ d dlmZ d dlm	Z	 d dl
mZ d dlmZ 	d"d	ed
eded deeef fddZ	d"dee dededed ddf
ddZ			d#d	ededee deded deeef fddZdededeeed f defddZ				d$d	ededee dededed defd d!ZdS )%    )OptionalTupleUnionN)Tensor)Literal)_ignore_background)_check_same_shape_safe_divideone-hotpredstargetsinput_formatr   indexreturnc                 C   s   |dkr| |fS |   dkr| dd} n|   dkr"| d} |  dkr4|dd}| |fS |  dkr?|d}| |fS )z Reshape tensors to 3D if needed.r      r      )dim	unsqueeze)r   r   r    r   j/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/torchmetrics/functional/segmentation/mean_iou.py_mean_iou_reshape_args   s   

r   num_classesinclude_background	per_classc                 C   s   |dkr| du rt d| dur| dkrt d|  dt|ts)t d| dt|ts6t d| d|d	vrBt d
| ddS )z%Validate the arguments of the metric.r   NDArgument `num_classes` must be provided when `input_format='index'`.r   zNExpected argument `num_classes` must be `None` or a positive integer, but got .zBExpected argument `include_background` must be a boolean, but got z9Expected argument `per_class` must be a boolean, but got r   zJExpected argument `input_format` to be one of 'one-hot', 'index', but got )
ValueError
isinstancebool)r   r   r   r   r   r   r   _mean_iou_validate_args/   s   


r!   Ftargetc              
   C   s.  t | ||\} }t| | |dkr4|du rtdtjjj| |ddd} tjjj||ddd}n1|dkre|du rez| jd }W n t	yX } z	t	d|  d	|d}~ww |d
kretd| d	|snt
| |\} }ttd| j}tj| |@ |d}tj||d}tj| |d}	||	 | }
||
fS )zFUpdate the intersection and union counts for the mean IoU computation.r   Nr   )r   r   r   z4Cannot determine `num_classes` from `preds` tensor: r   r   zBExpected argument `num_classes` to be a positive integer, but got r   r   )r   r   r   torchnn
functionalone_hotmovedimshape
IndexErrorr   listrangendimsum)r   r"   r   r   r   errreduce_axisintersection
target_sumpred_sumunionr   r   r   _mean_iou_updateD   s0   
r6   r2   r5   zero_division)warnnanc                 C   s   t | ||dS )zCompute the mean IoU metric.r7   r	   )r2   r5   r7   r   r   r   _mean_iou_computeg   s   r;   Tc           
      C   s^   t |||| t| ||||\}}t||dd}|dk}	|r#|dS |jdd|	jdd S )a	  Calculates the mean Intersection over Union (mIoU) for semantic segmentation.

    Returns -1 if class is completely absent both from predictions and ground truth labels.

    Args:
        preds: Predictions from model
        target: Ground truth values
        num_classes: Number of classes (required when input_format="index", optional when input_format="one-hot")
        include_background: Whether to include the background class in the computation
        per_class: Whether to compute the IoU for each class separately, else average over all classes
        input_format: What kind of input the function receives. Choose between ``"one-hot"`` for one-hot encoded tensors
            or ``"index"`` for index tensors

    Returns:
        The mean IoU score

    Example:
        >>> import torch
        >>> from torch import randint
        >>> from torchmetrics.functional.segmentation import mean_iou
        >>> # 4 samples, 5 classes, 16x16 prediction
        >>> preds = randint(0, 2, (4, 5, 16, 16), generator=torch.Generator().manual_seed(42))
        >>> # 4 samples, 5 classes, 16x16 target
        >>> target = randint(0, 2, (4, 5, 16, 16), generator=torch.Generator().manual_seed(43))
        >>> mean_iou(preds, target)
        tensor([0.3323, 0.3336, 0.3397, 0.3435])
        >>> mean_iou(preds, target, include_background=False, num_classes=5)
        tensor([0.3250, 0.3258, 0.3307, 0.3398])
        >>> mean_iou(preds, target, include_background=True, num_classes=5, per_class=True)
        tensor([[0.3617, 0.3128, 0.3366, 0.3242, 0.3263],
                [0.3646, 0.2893, 0.3297, 0.3073, 0.3770],
                [0.3756, 0.3168, 0.3505, 0.3400, 0.3155],
                [0.3579, 0.3317, 0.3797, 0.3523, 0.2957]])
        >>> # re-initialize tensors for ``input_format="index"``
        >>> preds = randint(0, 2, (4, 16, 16), generator=torch.Generator().manual_seed(42))
        >>> target = randint(0, 2, (4, 16, 16), generator=torch.Generator().manual_seed(43))
        >>> mean_iou(preds, target, num_classes=5, input_format = "index")
        tensor([0.3617, 0.3128, 0.3047, 0.3499])
        >>> mean_iou(preds, target, num_classes=5, per_class=True, input_format="index")
        tensor([[ 0.3617,  0.3617, -1.0000, -1.0000, -1.0000],
                [ 0.3128,  0.3128, -1.0000, -1.0000, -1.0000],
                [ 0.2727,  0.3366, -1.0000, -1.0000, -1.0000],
                [ 0.3756,  0.3242, -1.0000, -1.0000, -1.0000]])

    r9   r:   r   g      r#   r$   )r!   r6   r;   
nan_to_numnansumr/   )
r   r"   r   r   r   r   r2   r5   scoresvalid_classesr   r   r   mean_ioup   s
   5&r@   )r   )NFr   )NTFr   )typingr   r   r   r%   r   typing_extensionsr   *torchmetrics.functional.segmentation.utilsr   torchmetrics.utilities.checksr   torchmetrics.utilities.computer
   r   intr    r!   tupler6   floatr;   r@   r   r   r   r   <module>   s   




#
