a
    dp                     @   sd   d dl Z d dlmZ d dlm  mZ d dlmZ d	e je je	e jdddZ
G dd dejZdS )
    N)one_hot:0yE>)inputtargetepsreturnc           	      C   s   t | tjstdt|  t| jdks<td| j | jdd |jdd ksptd| j d|j | j|jkstd| j d|j t	j
| d	d
}t|| jd	 | j| jd}d}t|| |}t|| |}d| ||  }t| d S )u~  Criterion that computes Sørensen-Dice Coefficient loss.

    According to [1], we compute the Sørensen-Dice Coefficient as follows:

    .. math::

        \text{Dice}(x, class) = \frac{2 |X| \cap |Y|}{|X| + |Y|}

    Where:
       - :math:`X` expects to be the scores of each class.
       - :math:`Y` expects to be the one-hot tensor with the class labels.

    the loss, is finally computed as:

    .. math::

        \text{loss}(x, class) = 1 - \text{Dice}(x, class)

    Reference:
        [1] https://en.wikipedia.org/wiki/S%C3%B8rensen%E2%80%93Dice_coefficient

    Args:
        input: logits tensor with shape :math:`(N, C, H, W)` where C = number of classes.
        labels: labels tensor with shape :math:`(N, H, W)` where each value
          is :math:`0 ≤ targets[i] ≤ C−1`.
        eps: Scalar to enforce numerical stabiliy.

    Return:
        the computed loss.

    Example:
        >>> N = 5  # num_classes
        >>> input = torch.randn(1, N, 3, 5, requires_grad=True)
        >>> target = torch.empty(1, 3, 5, dtype=torch.long).random_(N)
        >>> output = dice_loss(input, target)
        >>> output.backward()
    z&Input type is not a torch.Tensor. Got    z-Invalid input shape, we expect BxNxHxW. Got: Nz/input and target shapes must be the same. Got: z and z2input and target must be in the same device. Got:    )Zdim)Znum_classesdevicedtype)r
         g       @g      ?)
isinstancetorchTensor	TypeErrortypelenshape
ValueErrorr   FZsoftmaxr   r   summean)	r   r   r   Z
input_softZtarget_one_hotdimsintersectionZcardinalityZ
dice_score r   [/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/kornia/losses/dice.py	dice_loss   s    &r   c                       sB   e Zd ZdZd
edd fddZejejejddd	Z  Z	S )DiceLossuW  Criterion that computes Sørensen-Dice Coefficient loss.

    According to [1], we compute the Sørensen-Dice Coefficient as follows:

    .. math::

        \text{Dice}(x, class) = \frac{2 |X| \cap |Y|}{|X| + |Y|}

    Where:
       - :math:`X` expects to be the scores of each class.
       - :math:`Y` expects to be the one-hot tensor with the class labels.

    the loss, is finally computed as:

    .. math::

        \text{loss}(x, class) = 1 - \text{Dice}(x, class)

    Reference:
        [1] https://en.wikipedia.org/wiki/S%C3%B8rensen%E2%80%93Dice_coefficient

    Args:
        eps: Scalar to enforce numerical stabiliy.

    Shape:
        - Input: :math:`(N, C, H, W)` where C = number of classes.
        - Target: :math:`(N, H, W)` where each value is
          :math:`0 ≤ targets[i] ≤ C−1`.

    Example:
        >>> N = 5  # num_classes
        >>> criterion = DiceLoss()
        >>> input = torch.randn(1, N, 3, 5, requires_grad=True)
        >>> target = torch.empty(1, 3, 5, dtype=torch.long).random_(N)
        >>> output = criterion(input, target)
        >>> output.backward()
    r   N)r   r   c                    s   t    || _d S N)super__init__r   )selfr   	__class__r   r   r"   t   s    
zDiceLoss.__init__)r   r   r   c                 C   s   t ||| jS r    )r   r   )r#   r   r   r   r   r   forwardx   s    zDiceLoss.forward)r   )
__name__
__module____qualname____doc__floatr"   r   r   r&   __classcell__r   r   r$   r   r   M   s   &r   )r   )r   Ztorch.nnnnZtorch.nn.functionalZ
functionalr   Zkornia.utils.one_hotr   r   r+   r   Moduler   r   r   r   r   <module>   s
   B