o
    9i                     @   s   d Z ddlmZ 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G d	d
 d
ej
ZG dd dej
ZG dd dejj
ZdddZdddZdS )zXStripped version of https://github.com/richzhang/PerceptualSimilarity/tree/master/models    )
namedtupleN)models   )get_ckpt_pathc                       s>   e Zd Zd fdd	ZdddZedddZd	d
 Z  ZS )LPIPSTc                    s   t    t | _g d| _tddd| _t| jd |d| _t| jd |d| _	t| jd |d| _
t| jd	 |d| _t| jd
 |d| _|   |  D ]}d|_qOd S )N)@            r
   TF)
pretrainedrequires_gradr   )use_dropout   r         )super__init__ScalingLayerscaling_layerchnsvgg16netNetLinLayerlin0lin1lin2lin3lin4load_from_pretrained
parametersr   )selfr   param	__class__ S/data/cameron/vidgen/generative-models/sgm/modules/autoencoding/lpips/loss/lpips.pyr      s   

zLPIPS.__init__	vgg_lpipsc                 C   s:   t |d}| jtj|tdddd td| d S )Nz#sgm/modules/autoencoding/lpips/losscpumap_locationFstrictz$loaded pretrained LPIPS loss from {})r   load_state_dicttorchloaddeviceprintformat)r    nameckptr$   r$   r%   r      s
   
zLPIPS.load_from_pretrainedc                 C   s<   |dkrt |  }t|}|jtj|tdddd |S )Nr&   r'   r(   Fr*   )NotImplementedErrorr   r,   r-   r.   r/   )clsr2   modelr3   r$   r$   r%   from_pretrained#   s   zLPIPS.from_pretrainedc                    s   |  ||  |}}| || |}}i i i }} | j| j| j| j| jgtt| j	D ]}	t
||	 t
||	 ||	< ||	< ||	 ||	  d  |	< q1 fddtt| j	D }
|
d }tdt| j	D ]}||
| 7 }ql|S )Nr   c                    s&   g | ]}t |  | d dqS )Tkeepdim)spatial_averager6   ).0kkdiffslinsr$   r%   
<listcomp>9   s    z!LPIPS.forward.<locals>.<listcomp>r   r   )r   r   r   r   r   r   r   rangelenr   normalize_tensor)r    inputtarget	in0_input	in1_inputouts0outs1feats0feats1r<   resvallr$   r=   r%   forward.   s    zLPIPS.forwardT)r&   )	__name__
__module____qualname__r   r   classmethodr7   rO   __classcell__r$   r$   r"   r%   r      s    

r   c                       s$   e Zd Z fddZdd Z  ZS )r   c                    s^   t t|   | dtg dd d d d d f  | dtg dd d d d d f  d S )Nshift)gQgI+gMbȿscale)gZd;O?gy&1?g?)r   r   r   register_bufferr-   Tensor)r    r"   r$   r%   r   D   s   zScalingLayer.__init__c                 C   s   || j  | j S )N)rV   rW   )r    inpr$   r$   r%   rO   M   s   zScalingLayer.forwardrQ   rR   rS   r   rO   rU   r$   r$   r"   r%   r   C   s    	r   c                       s"   e Zd ZdZd fdd	Z  ZS )r   z+A single linear layer which does a 1x1 convr   Fc              	      sL   t t|   |rt gng }|tj||dddddg7 }tj| | _d S )Nr   r   F)stridepaddingbias)r   r   r   nnDropoutConv2d
Sequentialr6   )r    chn_inchn_outr   layersr"   r$   r%   r   T   s   zNetLinLayer.__init__)r   F)rQ   rR   rS   __doc__r   rU   r$   r$   r"   r%   r   Q   s    r   c                       s&   e Zd Zd fdd	Zdd Z  ZS )r   FTc                    s:  t t|   tj|dj}tj | _tj | _	tj | _
tj | _tj | _d| _tdD ]}| jt|||  q3tddD ]}| j	t|||  qFtddD ]}| j
t|||  qYtddD ]}| jt|||  qltddD ]}| jt|||  q|s|  D ]}d|_qd S d S )	N)r      r   	            F)r   r   r   r   featuresr-   r_   rb   slice1slice2slice3slice4slice5N_slicesrA   
add_modulestrr   r   )r    r   r   vgg_pretrained_featuresxr!   r"   r$   r%   r   d   s.   zvgg16.__init__c           
      C   sh   |  |}|}| |}|}| |}|}| |}|}| |}|}tdg d}||||||}	|	S )N
VggOutputs)relu1_2relu2_2relu3_3relu4_3relu5_3)rm   rn   ro   rp   rq   r   )
r    Xh	h_relu1_2	h_relu2_2	h_relu3_3	h_relu4_3	h_relu5_3vgg_outputsoutr$   r$   r%   rO   {   s   




zvgg16.forward)FTr[   r$   r$   r"   r%   r   c   s    r   绽|=c                 C   s&   t t j| d ddd}| ||  S )Nr   r   T)dimr9   )r-   sqrtsum)rv   epsnorm_factorr$   r$   r%   rC      s   rC   Tc                 C   s   | j ddg|dS )Nr   r   r8   )mean)rv   r9   r$   r$   r%   r:      s   r:   )r   rP   )rf   collectionsr   r-   torch.nnr_   torchvisionr   utilr   Moduler   r   r   r   rC   r:   r$   r$   r$   r%   <module>   s    7
*