o
    oi*7                     @  s   d dl mZ d dlmZ d dlZd dlmZ d dlmZmZ d dl	m
Z
mZmZ d dlmZ d dlmZ 			
		d$d%ddZG dd dejZ				
			d&d'd d!ZG d"d# d#ejZdS )(    )annotations)OptionalN)nn)Tensortensor)KORNIA_CHECKKORNIA_CHECK_IS_TENSORKORNIA_CHECK_SHAPE)mask_ignore_pixels)one_hot       @nonepredr   targetalphaOptional[float]gammafloat	reductionstrweightOptional[Tensor]ignore_indexOptional[int]returnc                 C  s   t | g d | jd f| jdd  }t| jd |jd ko,|jdd | jdd kd| d|j  t| j|jkd| j d	|j  t||\}}t|| jd | j| jd
}	|durh|d |	| }	| d}
t	
d|
  | |
 |	 }| jd }dgdgt| jdd   }|durtd| g|g|d   |j|jd}||}|| }|durt|d t|jd |ko| |kd| d|j  t|j| jkd|j d	| j  ||}|| }|dkr|}|S |dkrt	|}|S |dkr	t	|}|S td| )a  Criterion that computes Focal loss.

    According to :cite:`lin2018focal`, the Focal loss is computed as follows:

    .. math::

        \text{FL}(p_t) = -\alpha_t (1 - p_t)^{\gamma} \, \text{log}(p_t)

    Where:
       - :math:`p_t` is the model's estimated probability for each class.

    Args:
        pred: logits tensor with shape :math:`(N, C, *)` where C = number of classes.
        target: labels tensor with shape :math:`(N, *)` where each value is an integer
          representing correct classification :math:`target[i] \in [0, C)`.
        alpha: Weighting factor :math:`\alpha \in [0, 1]`.
        gamma: Focusing parameter :math:`\gamma >= 0`.
        reduction: Specifies the reduction to apply to the
          output: ``'none'`` | ``'mean'`` | ``'sum'``. ``'none'``: no reduction
          will be applied, ``'mean'``: the sum of the output will be divided by
          the number of elements in the output, ``'sum'``: the output will be
          summed.
        weight: weights for classes with shape :math:`(num\_of\_classes,)`.
        ignore_index: labels with this value are ignored in the loss computation.

    Return:
        the computed loss.

    Example:
        >>> C = 5  # num_classes
        >>> pred = torch.randn(1, C, 3, 5, requires_grad=True)
        >>> target = torch.randint(C, (1, 3, 5))
        >>> kwargs = {"alpha": 0.5, "gamma": 2.0, "reduction": 'mean'}
        >>> output = focal_loss(pred, target, **kwargs)
        >>> output.backward()

    BC*r      N   Expected target size , got 1pred and target must be in the same device. Got:  and )num_classesdevicedtype      ?)r(   r'   weight must be Tensor or None.)weight shape must be (num_of_classes,): (,), got 1weight and pred must be in the same device. Got: r   meansumInvalid reduction mode: )r	   shaper   r'   r
   r   r(   
unsqueeze_log_softmaxtorchpowexplenr   viewr   numelr/   r0   NotImplementedError)r   r   r   r   r   r   r   out_sizetarget_masktarget_one_hotlog_pred_softloss_tmpnum_of_classesbroadcast_dims	alpha_facloss rE   G/home/ubuntu/.local/lib/python3.10/site-packages/kornia/losses/focal.py
focal_loss"   sZ   ..



&






rG   c                      s6   e Zd ZdZ				dd fddZdddZ  ZS )	FocalLossa  Criterion that computes Focal loss.

    According to :cite:`lin2018focal`, the Focal loss is computed as follows:

    .. math::

        \text{FL}(p_t) = -\alpha_t (1 - p_t)^{\gamma} \, \text{log}(p_t)

    Where:
       - :math:`p_t` is the model's estimated probability for each class.

    Args:
        alpha: Weighting factor :math:`\alpha \in [0, 1]`.
        gamma: Focusing parameter :math:`\gamma >= 0`.
        reduction: Specifies the reduction to apply to the
          output: ``'none'`` | ``'mean'`` | ``'sum'``. ``'none'``: no reduction
          will be applied, ``'mean'``: the sum of the output will be divided by
          the number of elements in the output, ``'sum'``: the output will be
          summed.
        weight: weights for classes with shape :math:`(num\_of\_classes,)`.
        ignore_index: labels with this value are ignored in the loss computation.

    Shape:
        - Pred: :math:`(N, C, *)` where C = number of classes.
        - Target: :math:`(N, *)` where each value is an integer
          representing correct classification :math:`target[i] \in [0, C)`.

    Example:
        >>> C = 5  # num_classes
        >>> pred = torch.randn(1, C, 3, 5, requires_grad=True)
        >>> target = torch.randint(C, (1, 3, 5))
        >>> kwargs = {"alpha": 0.5, "gamma": 2.0, "reduction": 'mean'}
        >>> criterion = FocalLoss(**kwargs)
        >>> output = criterion(pred, target)
        >>> output.backward()

    r   r   Nr   r   r   r   r   r   r   r   r   r   r   r   Nonec                   s,   t    || _|| _|| _|| _|| _d S N)super__init__r   r   r   r   r   )selfr   r   r   r   r   	__class__rE   rF   rL      s   

zFocalLoss.__init__r   r   r   c                 C  s   t ||| j| j| j| j| jS rJ   )rG   r   r   r   r   r   rM   r   r   rE   rE   rF   forward   s   zFocalLoss.forwardr   r   Nr   )r   r   r   r   r   r   r   r   r   r   r   rI   r   r   r   r   r   r   __name__
__module____qualname____doc__rL   rQ   __classcell__rE   rE   rN   rF   rH      s    )rH         ?
pos_weightc                 C  sJ  t | g d t| j|jkd| j d|j  t| j|jkd| j d|j  tj| }tj|  }	t||\}}
|
durI|	|
 }	||
 }|	 	| | | }| 	| d|  |	 }|durq|| }d| | }| jd }d	gdgt
| jd
d   }|durt|d t|jd |ko| |kd| d|j  t|j| jkd|j d| j  ||}|| }|| }|durt|d t|jd |ko| |kd| d|j  t|j| jkd|j d| j  ||}|| }|dkr|}|S |dkrt|}|S |dkrt|}|S td| )a  Criterion that computes Binary Focal loss.

    According to :cite:`lin2018focal`, the Focal loss is computed as follows:

    .. math::

        \text{FL}(p_t) = -\alpha_t (1 - p_t)^{\gamma} \, \text{log}(p_t)

    where:
       - :math:`p_t` is the model's estimated probability for each class.

    Args:
        pred: logits tensor with shape :math:`(N, C, *)` where C = number of classes.
        target: labels tensor with the same shape as pred :math:`(N, C, *)`
          where each value is between 0 and 1.
        alpha: Weighting factor :math:`\alpha \in [0, 1]`.
        gamma: Focusing parameter :math:`\gamma >= 0`.
        reduction: Specifies the reduction to apply to the
          output: ``'none'`` | ``'mean'`` | ``'sum'``. ``'none'``: no reduction
          will be applied, ``'mean'``: the sum of the output will be divided by
          the number of elements in the output, ``'sum'``: the output will be
          summed.
        pos_weight: a weight of positive examples with shape :math:`(num\_of\_classes,)`.
          It is possible to trade off recall and precision by adding weights to positive examples.
        weight: weights for classes with shape :math:`(num\_of\_classes,)`.
        ignore_index: labels with this value are ignored in the loss computation.

    Returns:
        the computed loss.

    Examples:
        >>> C = 3  # num_classes
        >>> pred = torch.randn(1, C, 5, requires_grad=True)
        >>> target = torch.randint(2, (1, C, 5))
        >>> kwargs = {"alpha": 0.25, "gamma": 2.0, "reduction": 'mean'}
        >>> output = binary_focal_loss_with_logits(pred, target, **kwargs)
        >>> output.backward()

    r   r"   r#   r$   r%   Nr)   r!   r*   r    z"pos_weight must be Tensor or None.r   z-pos_weight shape must be (num_of_classes,): (r-   z5pos_weight and pred must be in the same device. Got: r+   r,   r.   r   r/   r0   r1   )r	   r   r2   r'   r   
functional
logsigmoidr
   r7   r6   r8   r   r:   r9   r5   r/   r0   r;   )r   r   r   r   r   r[   r   r   log_probs_poslog_probs_negr=   pos_termneg_termrA   rB   r@   rD   rE   rE   rF   binary_focal_loss_with_logits   sl   1"












rb   c                      s8   e Zd ZdZ					dd fddZdddZ  ZS )BinaryFocalLossWithLogitsa[  Criterion that computes Focal loss.

    According to :cite:`lin2018focal`, the Focal loss is computed as follows:

    .. math::

        \text{FL}(p_t) = -\alpha_t (1 - p_t)^{\gamma} \, \text{log}(p_t)

    where:
       - :math:`p_t` is the model's estimated probability for each class.

    Args:
        alpha: Weighting factor :math:`\alpha \in [0, 1]`.
        gamma: Focusing parameter :math:`\gamma >= 0`.
        reduction: Specifies the reduction to apply to the
          output: ``'none'`` | ``'mean'`` | ``'sum'``. ``'none'``: no reduction
          will be applied, ``'mean'``: the sum of the output will be divided by
          the number of elements in the output, ``'sum'``: the output will be
          summed.
        pos_weight: a weight of positive examples with shape :math:`(num\_of\_classes,)`.
          It is possible to trade off recall and precision by adding weights to positive examples.
        weight: weights for classes with shape :math:`(num\_of\_classes,)`.
        ignore_index: labels with this value are ignored in the loss computation.

    Shape:
        - Pred: :math:`(N, C, *)` where C = number of classes.
        - Target: the same shape as Pred :math:`(N, C, *)`
          where each value is between 0 and 1.

    Examples:
        >>> C = 3  # num_classes
        >>> pred = torch.randn(1, C, 5, requires_grad=True)
        >>> target = torch.randint(2, (1, C, 5))
        >>> kwargs = {"alpha": 0.25, "gamma": 2.0, "reduction": 'mean'}
        >>> criterion = BinaryFocalLossWithLogits(**kwargs)
        >>> output = criterion(pred, target)
        >>> output.backward()

    r   r   Nr   r   r   r   r   r   r   r[   r   r   r   r   r   rI   c                   s2   t    || _|| _|| _|| _|| _|| _d S rJ   )rK   rL   r   r   r   r[   r   r   )rM   r   r   r   r[   r   r   rN   rE   rF   rL   `  s   
	
z"BinaryFocalLossWithLogits.__init__r   r   r   c              	   C  s"   t ||| j| j| j| j| j| jS rJ   )rb   r   r   r   r[   r   r   rP   rE   rE   rF   rQ   q  s   z!BinaryFocalLossWithLogits.forward)r   r   NNr   )r   r   r   r   r   r   r[   r   r   r   r   r   r   rI   rS   rT   rE   rE   rN   rF   rc   7  s    +rc   rR   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )rZ   r   r   NNr   )r   r   r   r   r   r   r   r   r   r   r[   r   r   r   r   r   r   r   )
__future__r   typingr   r5   r   kornia.corer   r   kornia.core.checkr   r   r	   kornia.losses._utilsr
   kornia.utils.one_hotr   rG   ModulerH   rb   rc   rE   rE   rE   rF   <module>   s,   
i=r