o

    hn                     @   sV   d dl Z d dlZd dlm  mZ dd Zd
ddZdd Zd	ej	d
ej	fddZ
dS )    Nc                 C   s<   t j|}|dkr| S |dkr|  S |dkr|  S dS )zReduce loss as specified.

    Args:
        loss (Tensor): Elementwise loss tensor.
        reduction (str): Options are "none", "mean" and "sum".

    Return:
        Tensor: Reduced loss tensor.
    r         N)F
_Reductionget_enummeansum)loss	reductionreduction_enum r   //root/Awesome-Backbones/configs/losses/utils.pyreduce_loss   s   
r   r   c                 C   sR   |dur| | } |du rt | |} | S |dkr|  | } | S |dkr'td| S )aS  Apply element-wise weight and reduce loss.

    Args:
        loss (Tensor): Element-wise loss.
        weight (Tensor): Element-wise weights.
        reduction (str): Same as built-in losses of PyTorch.
        avg_factor (float): Average factor when computing the mean of losses.

    Returns:
        Tensor: Processed loss values.
    Nr   nonez/avg_factor can not be used with reduction="sum")r   r   
ValueError)r	   weightr
   
avg_factorr   r   r
   weight_reduce_loss   s   

r   c                    s"   t  			d fdd	}|S )a  Create a weighted version of a given loss function.

    To use this decorator, the loss function must have the signature like
    ``loss_func(pred, target, **kwargs)``. The function only needs to compute
    element-wise loss without any reduction. This decorator will add weight
    and reduction arguments to the function. The decorated function will have
    the signature like ``loss_func(pred, target, weight=None, reduction='mean',
    avg_factor=None, **kwargs)``.

    :Example:

    >>> import torch
    >>> @weighted_loss
    >>> def l1_loss(pred, target):
    >>>     return (pred - target).abs()

    >>> pred = torch.Tensor([0, 2, 3])
    >>> target = torch.Tensor([1, 1, 1])
    >>> weight = torch.Tensor([1, 0, 1])

    >>> l1_loss(pred, target)
    tensor(1.3333)
    >>> l1_loss(pred, target, weight)
    tensor(1.)
    >>> l1_loss(pred, target, reduction='none')
    tensor([1., 1., 2.])
    >>> l1_loss(pred, target, weight, avg_factor=2)
    tensor(1.5000)
    Nr   c                    s$    | |fi |}t ||||}|S )N)r   )predtargetr   r
   r   kwargsr	   	loss_funcr   r
   wrapperX   s   zweighted_loss.<locals>.wrapperNr   N)	functoolswraps)r   r   r   r   r
   
weighted_loss9   s   r   targetsreturnc                 C   s6   t |  |k s
J dtj|  d|d}|S )a8  This function converts target class indices to one-hot vectors, given
    the number of classes.

    Args:
        targets (Tensor): The ground truth label of the prediction
                with shape (N, 1)
        classes (int): the number of classes.

    Returns:
        Tensor: Processed loss values.
    z/Class Index must be less than number of classes)num_classes)torchmaxitemr   one_hotlongsqueeze)r   classesZone_hot_targetsr   r   r
   convert_to_one_hotg   s   r)   r   )r   r"   torch.nn.functionalnn
functionalr   r   r   r   Tensorr)   r   r   r   r
   <module>   s   
.