a
    d&                     @   sT   d dl Z d dlmZ d dl mZ d dlmZ eeedddZG dd dejZdS )	    N)Tensor)KORNIA_CHECK_SHAPEpredtargetreturnc                 C   s  t | g d t |g d | jd dks:td| j | jdd |jdd ksntd| j d|j | j|jkstd	| j d|j | | jd
 d}||jd
 d}|j\}}d| d }d||  }|jddd\}}	tj|| jdddd|d}
||
|		df }|	||}|j
ddd}||d }|d| d }d||  }|dkr|dddf |dddf  |dddf< | | 
d }|S )a   Criterion that computes a surrogate binary intersection-over-union (IoU) loss.

    According to [2], we compute the IoU as follows:

    .. math::

        \text{IoU}(x, class) = \frac{|X \cap Y|}{|X \cup Y|}

    [1] approximates this fomular with a surrogate, which is fully differentable.

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

    the loss, is finally computed as:

    .. math::

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

    Reference:
        [1] http://proceedings.mlr.press/v37/yub15.pdf
        [2] https://arxiv.org/pdf/1705.08790.pdf

    . note::
        This loss function only supports binary labels. For multi-class labels please
        use the Lovasz-Softmax loss.

    Args:
        pred: logits tensor with shape :math:`(N, 1, H, W)`.
        labels: labels tensor with shape :math:`(N, H, W)` with binary values.

    Return:
        a scalar with the computed loss.

    Example:
        >>> N = 1  # num_classes
        >>> pred = torch.randn(1, N, 3, 5, requires_grad=True)
        >>> target = torch.empty(1, 3, 5, dtype=torch.long).random_(N)
        >>> output = lovasz_hinge_loss(pred, target)
        >>> output.backward()
    )B1HW)r   r
   r      z,Invalid pred shape, we expect Bx1xHxW. Got: Nz.pred and target shapes must be the same. Got: z and z1pred and target must be in the same device. Got: r   g       @g      ?T)ZdimZ
descending)device)Zkeepdim.)r   shape
ValueErrorr   ZreshapesorttorchZarangerepeatviewsumZcumsumZrelumean)r   r   Zpred_flattenZtarget_flattenr   NZsignserrorsZerrors_sortedZpermutationZbatch_indexZtarget_sortedZtarget_sorted_sumintersectionunionZgradientZloss r   c/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/kornia/losses/lovasz_hinge.pylovasz_hinge_loss   s2    +
&
,r   c                       s8   e Zd ZdZdd fddZeeedddZ  ZS )	LovaszHingeLossa"  Criterion that computes a surrogate binary intersection-over-union (IoU) loss.

    According to [2], we compute the IoU as follows:

    .. math::

        \text{IoU}(x, class) = \frac{|X \cap Y|}{|X \cup Y|}

    [1] approximates this fomular with a surrogate, which is fully differentable.

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

    the loss, is finally computed as:

    .. math::

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

    Reference:
        [1] http://proceedings.mlr.press/v37/yub15.pdf
        [2] https://arxiv.org/pdf/1705.08790.pdf

    . note::
        This loss function only supports binary labels. For multi-class labels please
        use the Lovasz-Softmax loss.

    Args:
        pred: logits tensor with shape :math:`(N, 1, H, W)`.
        labels: labels tensor with shape :math:`(N, H, W)` with binary values.

    Return:
        a scalar with the computed loss.

    Example:
        >>> N = 1  # num_classes
        >>> criterion = LovaszHingeLoss()
        >>> pred = torch.randn(1, N, 3, 5, requires_grad=True)
        >>> target = torch.empty(1, 3, 5, dtype=torch.long).random_(N)
        >>> output = criterion(pred, target)
        >>> output.backward()
    N)r   c                    s   t    d S )N)super__init__)self	__class__r   r   r!      s    zLovaszHingeLoss.__init__r   c                 C   s   t ||dS )N)r   r   )r   )r"   r   r   r   r   r   forward   s    zLovaszHingeLoss.forward)__name__
__module____qualname____doc__r!   r   r%   __classcell__r   r   r#   r   r   [   s   ,r   )	r   Ztorch.nnnnr   Zkornia.testingr   r   Moduler   r   r   r   r   <module>   s
   P