a
    d$                     @   s   d dl Z d dl mZ d dlmZ d dlmZ d dlmZ ddl	m
Z
 g dZe
d	d
 Ze
dd Ze
dddZe G dd dejZe G dd dejZe G dd dejZe G dd deZe G dd dejZdS )    N)nn)
functional)VGGFeatureExtractor)LOSS_REGISTRY   )weighted_lossnonemeansumc                 C   s   t j| |ddS Nr	   	reduction)Fl1_losspredtarget r   b/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/basicsr/losses/basic_loss.pyr      s    r   c                 C   s   t j| |ddS r   )r   mse_lossr   r   r   r   r      s    r   -q=c                 C   s   t | | d | S )N   )torchsqrt)r   r   epsr   r   r   charbonnier_loss   s    r   c                       s,   e Zd ZdZd	 fdd	Zd
ddZ  ZS )L1Lossa  L1 (mean absolute error, MAE) loss.

    Args:
        loss_weight (float): Loss weight for L1 loss. Default: 1.0.
        reduction (str): Specifies the reduction to apply to the output.
            Supported choices are 'none' | 'mean' | 'sum'. Default: 'mean'.
          ?r
   c                    s:   t t|   |dvr*td| dt || _|| _d S Nr   Unsupported reduction mode: z. Supported ones are: )superr   __init__
ValueError_reduction_modesloss_weightr   selfr%   r   	__class__r   r   r"   %   s
    zL1Loss.__init__Nc                 K   s   | j t|||| jd S   
        Args:
            pred (Tensor): of shape (N, C, H, W). Predicted tensor.
            target (Tensor): of shape (N, C, H, W). Ground truth tensor.
            weight (Tensor, optional): of shape (N, C, H, W). Element-wise weights. Default: None.
        r   )r%   r   r   r'   r   r   weightkwargsr   r   r   forward-   s    zL1Loss.forward)r   r
   )N__name__
__module____qualname____doc__r"   r/   __classcell__r   r   r(   r   r      s   r   c                       s,   e Zd ZdZd	 fdd	Zd
ddZ  ZS )MSELosszMSE (L2) loss.

    Args:
        loss_weight (float): Loss weight for MSE loss. Default: 1.0.
        reduction (str): Specifies the reduction to apply to the output.
            Supported choices are 'none' | 'mean' | 'sum'. Default: 'mean'.
    r   r
   c                    s:   t t|   |dvr*td| dt || _|| _d S r   )r!   r6   r"   r#   r$   r%   r   r&   r(   r   r   r"   A   s
    zMSELoss.__init__Nc                 K   s   | j t|||| jd S r*   )r%   r   r   r,   r   r   r   r/   I   s    zMSELoss.forward)r   r
   )Nr0   r   r   r(   r   r6   7   s   r6   c                       s,   e Zd ZdZd
 fdd	Zddd	Z  ZS )CharbonnierLossa  Charbonnier loss (one variant of Robust L1Loss, a differentiable
    variant of L1Loss).

    Described in "Deep Laplacian Pyramid Networks for Fast and Accurate
        Super-Resolution".

    Args:
        loss_weight (float): Loss weight for L1 loss. Default: 1.0.
        reduction (str): Specifies the reduction to apply to the output.
            Supported choices are 'none' | 'mean' | 'sum'. Default: 'mean'.
        eps (float): A value used to control the curvature near zero. Default: 1e-12.
    r   r
   r   c                    s@   t t|   |dvr*td| dt || _|| _|| _d S r   )r!   r7   r"   r#   r$   r%   r   r   )r'   r%   r   r   r(   r   r   r"   b   s    zCharbonnierLoss.__init__Nc                 K   s   | j t|||| j| jd S )r+   )r   r   )r%   r   r   r   r,   r   r   r   r/   k   s    zCharbonnierLoss.forward)r   r
   r   )Nr0   r   r   r(   r   r7   S   s   	r7   c                       s0   e Zd ZdZd	 fdd	Zd
 fdd	Z  ZS )WeightedTVLosszYWeighted TV loss.

    Args:
        loss_weight (float): Loss weight. Default: 1.0.
    r   r
   c                    s0   |dvrt d| dtt| j||d d S )N)r
   r   r    z . Supported ones are: mean | sum)r%   r   )r#   r!   r8   r"   r&   r(   r   r   r"   }   s    zWeightedTVLoss.__init__Nc                    s   |d u rd }d }n@|d d d d d dd d f }|d d d d d d d df }t  j|d d d d d dd d f |d d d d dd d d f |d}t  j|d d d d d d d df |d d d d d d dd f |d}|| }|S )Nr   )r-   )r!   r/   )r'   r   r-   Zy_weightZx_weightZy_diffZx_diffZlossr(   r   r   r/      s      JJzWeightedTVLoss.forward)r   r
   )Nr0   r   r   r(   r   r8   u   s   r8   c                       s2   e Zd ZdZd fdd		Zd
d Zdd Z  ZS )PerceptualLossa#  Perceptual loss with commonly used style loss.

    Args:
        layer_weights (dict): The weight for each layer of vgg feature.
            Here is an example: {'conv5_4': 1.}, which means the conv5_4
            feature layer (before relu5_4) will be extracted with weight
            1.0 in calculating losses.
        vgg_type (str): The type of vgg network used as feature extractor.
            Default: 'vgg19'.
        use_input_norm (bool):  If True, normalize the input image in vgg.
            Default: True.
        range_norm (bool): If True, norm images with range [-1, 1] to [0, 1].
            Default: False.
        perceptual_weight (float): If `perceptual_weight > 0`, the perceptual
            loss will be calculated and the loss will multiplied by the
            weight. Default: 1.0.
        style_weight (float): If `style_weight > 0`, the style loss will be
            calculated and the loss will multiplied by the weight.
            Default: 0.
        criterion (str): Criterion used for perceptual loss. Default: 'l1'.
    vgg19TFr           l1c                    s   t t|   || _|| _|| _tt| |||d| _	|| _
| j
dkrXtj | _n8| j
dkrptj | _n | j
dkrd | _nt| dd S )N)Zlayer_name_listvgg_typeuse_input_norm
range_normr=   l2froz" criterion has not been supported.)r!   r:   r"   perceptual_weightstyle_weightlayer_weightsr   listkeysvggcriterion_typer   r   r   	criterionZL2lossNotImplementedError)r'   rE   r>   r?   r@   rC   rD   rJ   r(   r   r   r"      s$    



zPerceptualLoss.__init__c              	   C   s>  |  |}|  | }| jdkrd}| D ]Z}| jdkrf|tj|| ||  dd| j|  7 }q.|| || || | j|  7 }q.|| j9 }nd}| j	dkr2d}| D ]r}| jdkr|tj| 
|| | 
||  dd| j|  7 }q|| | 
|| | 
|| | j|  7 }q|| j	9 }nd}||fS )zForward function.

        Args:
            x (Tensor): Input tensor with shape (n, c, h, w).
            gt (Tensor): Ground-truth tensor with shape (n, c, h, w).

        Returns:
            Tensor: Forward results.
        r   rB   )pN)rH   detachrC   rG   rI   r   ZnormrE   rJ   rD   	_gram_mat)r'   xgtZ
x_featuresZgt_featuresZpercep_losskZ
style_lossr   r   r   r/      s6    


*$
zPerceptualLoss.forwardc           	      C   sH   |  \}}}}||||| }|dd}|||| |  }|S )zCalculate Gram matrix.

        Args:
            x (torch.Tensor): Tensor with shape of (n, c, h, w).

        Returns:
            torch.Tensor: Gram matrix.
        r   r   )sizeviewZ	transposeZbmm)	r'   rO   nchwfeaturesZ
features_tZgramr   r   r   rN      s
    	zPerceptualLoss._gram_mat)r;   TFr   r<   r=   )r1   r2   r3   r4   r"   r/   rN   r5   r   r   r(   r   r:      s         *r:   )r   )r   r   Ztorch.nnr   r   Zbasicsr.archs.vgg_archr   Zbasicsr.utils.registryr   Z	loss_utilr   r$   r   r   r   registerModuler   r6   r7   r8   r:   r   r   r   r   <module>   s,   

!