
    3j                        S SK Jr  S SKJr  S SKrS SKJrJr  S SKJrJ	r	J
r
  S	S
S jjr " S S\R                  5      rg)    )annotations)OptionalN)Tensornn)KORNIA_CHECKKORNIA_CHECK_IS_TENSORKORNIA_CHECK_SHAPEc                   [        U / SQ5        [        U/ SQ5        U R                  S   S:  d  [        SU R                   35      eU R                  SS UR                  SS :X  d%  [        SU R                   SUR                   35      eU R                  UR                  :X  d%  [        S	U R                   SUR                   35      eU R                  S   nUb  [	        US
5        [        UR                  S   U:H  =(       a    UR                  5       U:H  SU SUR                   35        [        UR                  U R                  :H  SUR                   SU R                   35        U R                  U R                  S   U R                  S   S5      nUR                  UR                  S   S5      nUR                  u  pgnUR                  S5      n	[        R                  R                  R                  UR                  [        R                  5      US9R                  SSS5      R                  U R                   5      n
X-
  R#                  5       n[        R$                  " USSS9u  p[        R&                  " X`R                  S9R)                  S5      R)                  S5      R+                  XgU5      nX^U4   nUR-                  SSS9nUUR/                  S5      -
  nUSU-
  R/                  S5      -   nSUU-  -
  nUS:  a  USSS24   USSS24   -
  USSS24'   UU-  nUR-                  S5      R1                  S5      nUb  UU-  nUR1                  5       nU$ )u  Criterion that computes a surrogate multi-class intersection-over-union (IoU) loss.

According to [1], 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 long tensor with the class labels.

the loss, is finally computed as:

.. math::

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

Reference:
    [1] https://arxiv.org/pdf/1705.08790.pdf

.. note::
    This loss function only supports multi-class (C > 1) labels. For binary
    labels please use the Lovasz-Hinge loss.

Args:
    pred: logits tensor with shape :math:`(N, C, H, W)` where C = number of classes > 1.
    target: labels tensor with shape :math:`(N, H, W)` where each value
      is in range :math:`0 ≤ targets[i] ≤ C-1`.
    weight: weights for classes with shape :math:`(num\_of\_classes,)`.

Return:
    a scalar with the computed loss.

Example:
    >>> N = 5  # 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_softmax_loss(pred, target)
    >>> output.backward()

)BNHW)r   r   r      z8Invalid pred shape, we expect BxNxHxW, with N > 1. Got: Nz.pred and target shapes must be the same. Got: z and z1pred and target must be in the same device. Got: zweight must be Tensor or None.r   z)weight shape must be (num_of_classes,): (z,), got z1weight and pred must be in the same device. Got: )num_classes   T)dim
descending)device)keepdimg      ?.)r	   shape
ValueErrorr   r   r   numelreshapesoftmaxtorchr   
functionalone_hottoint64permutedtypeabssortarange	unsqueezeexpandsumcumsummean)predtargetweightnum_of_classespred_flattentarget_flattenr   Cr   	pred_soft
foregrounderrorserrors_sortedpermutationsbatch_indextarget_sortedtarget_sorted_sumintersectionuniongradientweighted_errorsloss_per_class
final_losss                          V/home/wildlama/miniconda3/lib/python3.13/site-packages/kornia/losses/lovasz_softmax.pylovasz_softmax_lossrB      sF   Z t12v/::a=1STXT^T^S_`aa::bc?fll23//I$**UZ[a[g[gZhijj;;&--'LT[[MY^_e_l_l^mnooZZ]Nv'GH\\!_.S6<<>^3S77GxPVP\P\~^	
 	MMT[[(?eTXT_T_S`a	
  <<

1tzz!}bIL#^^FLLOR@N   GA! %,,Q/I 	##N$5$5ekk$BPQ#RZZ[\^_abcffgkgqgqr   ,113F"'**Vt"LM,,q5??BLLQOVVWX]^_K"#<=M%))!T):$}';';A'>>L}!4 < <Q ??E\E))H1u$S!"W-crc0BBab#h.O$((+003N& ',,.J    c                  >   ^  \ rS rSrSrSSU 4S jjjrSS jrSrU =r$ )	LovaszSoftmaxLoss   u#  Criterion that computes a surrogate multi-class intersection-over-union (IoU) loss.

According to [1], 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] https://arxiv.org/pdf/1705.08790.pdf

.. note::
    This loss function only supports multi-class (C > 1) labels. For binary
    labels please use the Lovasz-Hinge loss.

Args:
    pred: logits tensor with shape :math:`(N, C, H, W)` where C = number of classes > 1.
    labels: labels tensor with shape :math:`(N, H, W)` where each value
      is in range :math:`0 ≤ targets[i] ≤ C-1`.
    weight: weights for classes with shape :math:`(num\_of\_classes,)`.

Return:
    a scalar with the computed loss.

Example:
    >>> N = 5  # num_classes
    >>> criterion = LovaszSoftmaxLoss()
    >>> 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()

c                .   > [         TU ]  5         Xl        g N)super__init__r.   )selfr.   	__class__s     rA   rJ   LovaszSoftmaxLoss.__init__   s    rC   c                *    [        XU R                  S9$ )N)r,   r-   r.   )rB   r.   )rK   r,   r-   s      rA   forwardLovaszSoftmaxLoss.forward   s    "DKKPPrC   )r.   rH   )r.   Optional[Tensor]returnNone)r,   r   r-   r   rR   r   )	__name__
__module____qualname____firstlineno____doc__rJ   rO   __static_attributes____classcell__)rL   s   @rA   rE   rE      s    ,\ Q QrC   rE   rH   )r,   r   r-   r   r.   rQ   rR   r   )
__future__r   typingr   r   r   r   kornia.core.checkr   r   r	   rB   ModulerE    rC   rA   <module>r`      s2   $ #    V VdN4Q		 4QrC   