o

    h                     @   sB   d dl Z d dlmZ ddlmZ ddlmZ G dd dejZdS )    N   )CrossEntropyLoss)convert_to_one_hotc                       sR   e Zd ZdZ				d fdd	Zdd	 Zd
d Zdd
 Z			dddZ  Z	S )LabelSmoothLossa  Initializer for the label smoothed cross entropy loss.

    Refers to `Rethinking the Inception Architecture for Computer Vision
    <https://arxiv.org/abs/1512.00567>`_

    This decreases gap between output scores and encourages generalization.
    Labels provided to forward can be one-hot like vectors (NxC) or class
    indices (Nx1).
    And this accepts linear combination of one-hot like labels from mixup or
    cutmix except multi-label task.

    Args:
        label_smooth_val (float): The degree of label smoothing.
        num_classes (int, optional): Number of classes. Defaults to None.
        mode (str): Refers to notes, Options are 'original', 'classy_vision',
            'multi_label'. Defaults to 'original'
        reduction (str): The method used to reduce the loss.
            Options are "none", "mean" and "sum". Defaults to 'mean'.
        loss_weight (float):  Weight of the loss. Defaults to 1.0.

    Notes:
        if the mode is "original", this will use the same label smooth method
        as the original paper as:

        .. math::
            (1-\epsilon)\delta_{k, y} + \frac{\epsilon}{K}

        where epsilon is the `label_smooth_val`, K is the num_classes and
        delta(k,y) is Dirac delta, which equals 1 for k=y and 0 otherwise.

        if the mode is "classy_vision", this will use the same label smooth
        method as the facebookresearch/ClassyVision repo as:

        .. math::
            \frac{\delta_{k, y} + \epsilon/K}{1+\epsilon}

        if the mode is "multi_label", this will accept labels from multi-label
        task and smoothing them as:

        .. math::
            (1-2\epsilon)\delta_{k, y} + \epsilon
    Noriginalmean      ?c                    s   t    || _|| _t|trd|  krdk s"n J d| || _h d}||v s8J d| d| d|| _h d}||v sNJ d	| d| d|| _|| _	|d
kr_|d|  | _	|dkrot
dd
| _| j| _
d S t
dd| _| j| _
d S )Nr   r   zGLabelSmoothLoss accepts a float label_smooth_val over [0, 1), but gets >   sumnoner   z#LabelSmoothLoss supports reduction z, but gets .>   r   multi_label
classy_visionzLabelSmoothLoss supports mode r
   r   T)use_sigmoid)use_soft)super__init__num_classesloss_weight
isinstancefloatlabel_smooth_val	reductionmode_epsr   cemultilabel_smooth_labelsmooth_labeloriginal_smooth_label)selfr   r   r   r   r   Zaccept_reductionZaccept_mode	__class__ ;/root/Awesome-Backbones/configs/losses/label_smooth_loss.pyr   7   s<   



zLabelSmoothLoss.__init__c                 C   sB   |  dks|  dkr|jd dkrt|dd| j}| S )zkThis function takes one-hot or index label vectors and computes one-
        hot like label vectors (float)r      )dimshaper   viewr   r   )r   labelr!   r!   r"   generate_one_hot_like_label\   s   &z+LabelSmoothLoss.generate_one_hot_like_labelc                 C   s0   | j dksJ |d| j  }|| j| j  7 }|S Nr   r   )r   r   r   one_hot_like_labelr   r!   r!   r"   r   d   s   z%LabelSmoothLoss.original_smooth_labelc                 C   s6   | j dksJ t|| j}||dkd| j  |S r*   )r   torch	full_liker   masked_fill_r+   r!   r!   r"   r   j   s   z'LabelSmoothLoss.multilabel_smooth_labelc           	      K   s   | j dur| j |jd ksJ d| j  d|jd  n|jd | _ | j|d}|j|jks:J d|j d|j | |}| jj||f|||d|S )	a  Label smooth loss.

        Args:
            pred (torch.Tensor): The prediction with shape (N, \*).
            label (torch.Tensor): The ground truth label of the prediction
                with shape (N, \*).
            weight (torch.Tensor, optional): Sample-wise loss weight with shape
                (N, \*). Defaults to None.
            avg_factor (int, optional): Average factor that is used to average
                the loss. Defaults to None.
            reduction_override (str, optional): The method used to reduce the
                loss into a scalar. Options are "none", "mean" and "sum".
                Defaults to None.

        Returns:
            torch.Tensor: Loss.
        Nr   zEnum_classes should equal to cls_score.shape[1], but got num_classes: z and cls_score.shape[1]: )r(   zSLabelSmoothLoss requires output and target to be same shape, but got output.shape: z and target.shape: )weight
avg_factorreduction_override)r   r&   r)   r   r   forward)	r   	cls_scorer(   r0   r1   r2   kwargsr,   Zsmoothed_labelr!   r!   r"   r3   p   s8   

zLabelSmoothLoss.forward)Nr   r   r   )NNN)
__name__
__module____qualname____doc__r   r)   r   r   r3   
__classcell__r!   r!   r   r"   r      s    -%	r   )	r-   torch.nnnncross_entropy_lossr   utilsr   Moduler   r!   r!   r!   r"   <module>   s
   