a
    
dM                     @   s   d Z ddl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ZG dd dejZdS )z3Modified from https://github.com/chaofengc/PSFRGAN
    N)
functionalc                       s,   e Zd ZdZd fdd	Zd	ddZ  ZS )
	NormLayerzNormalization Layers.

    Args:
        channels: input channels, for batch norm and instance norm.
        input_size: input shape without batch size, for layer norm.
    Nbnc                    s   t t|   | }|| _|dkr6tj|dd| _n|dkrPtj|dd| _nr|dkrltj	d|dd| _nV|dkrd	d
 | _nB|dkrt
|| _n,|dkrdd
 | _nddksJ d| dd S )Nr   T)affineinFgn    pixelc                 S   s   t j| dddS )N      )pdim)F	normalizex r   X/var/www/html/stable-diffusion-webui/repositories/CodeFormer/facelib/parsing/parsenet.py<lambda>       z$NormLayer.__init__.<locals>.<lambda>layernonec                 S   s   | d S N      ?r   r   r   r   r   r      r   r   r   z
Norm type  not support.)superr   __init__lower	norm_typennBatchNorm2dnormInstanceNorm2d	GroupNorm	LayerNorm)selfchannelsZnormalize_shaper   	__class__r   r   r      s     zNormLayer.__init__c                 C   s$   | j dkr| ||S | |S d S )Nspade)r   r!   )r%   r   refr   r   r   forward#   s    
zNormLayer.forward)Nr   )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 Z  ZS )	ReluLayerzRelu Layer.

    Args:
        relu type: type of relu layer, candidates are
            - ReLU
            - LeakyReLU: default relu slope 0.2
            - PRelu
            - SELU
            - none: direct pass
    reluc                    s   t t|   | }|dkr,td| _nr|dkrFtjddd| _nX|dkr\t|| _nB|dkrrt	d| _n,|dkrd	d
 | _nddksJ d| dd S )Nr3   T	leakyrelug?)inplacepreluselur   c                 S   s   | d S r   r   r   r   r   r   r   B   r   z$ReluLayer.__init__.<locals>.<lambda>r   r   z
Relu type r   )
r   r2   r   r   r   ReLUfunc	LeakyReLUPReLUSELU)r%   r&   	relu_typer'   r   r   r   6   s    zReluLayer.__init__c                 C   s
   |  |S N)r9   )r%   r   r   r   r   r+   F   s    zReluLayer.forward)r3   r,   r   r   r'   r   r2   *   s   r2   c                       s&   e Zd Zd fdd	Zdd Z  ZS )		ConvLayer   r   Tc	           
         s   t t|   || _|| _|dv r&d}|dkr2dnd}	dd | _|dkrRd	d | _ttt	
|d
 d | _tj||||	|d| _t||| _t||d| _d S )N)r   Fdownr
   r   c                 S   s   | S r>   r   r   r   r   r   r   ]   r   z$ConvLayer.__init__.<locals>.<lambda>upc                 S   s   t jj| dddS )Nr
   nearest)scale_factormode)r   r   interpolater   r   r   r   r   _   r   r   )bias)r   )r   r?   r   use_padr   
scale_funcr   ReflectionPad2dintnpceilreflection_padConv2dconv2dr2   r3   r   r!   )
r%   in_channelsout_channelskernel_sizescaler   r=   rH   rG   strider'   r   r   r   L   s    	

zConvLayer.__init__c                 C   s<   |  |}| jr| |}| |}| |}| |}|S r>   )rI   rH   rN   rP   r!   r3   )r%   r   outr   r   r   r+   g   s    




zConvLayer.forward)r@   r   r   r   TTr-   r.   r/   r   r+   r1   r   r   r'   r   r?   J   s         r?   c                       s*   e Zd ZdZd	 fdd	Zdd Z  ZS )
ResidualBlockzU
    Residual block recommended in: http://torch.ch/blog/2016/02/04/resnets.html
    r6   r   r   c                    s   t t|   |dkr*||kr*dd | _nt||d|| _ddgddgddgd}|| }t||d|d ||d	| _t||d|d
 |dd	| _d S )Nr   c                 S   s   | S r>   r   r   r   r   r   r   z   r   z(ResidualBlock.__init__.<locals>.<lambda>r@   rA   rB   )rA   rB   r   r   r   r=   r   )r   rX   r   shortcut_funcr?   conv1conv2)r%   c_inc_outr=   r   rT   Zscale_config_dictZ
scale_confr'   r   r   r   v   s    zResidualBlock.__init__c                 C   s&   |  |}| |}| |}|| S r>   )rZ   r[   r\   )r%   r   identityresr   r   r   r+      s    


zResidualBlock.forward)r6   r   r   r,   r   r   r'   r   rX   q   s   rX   c                
       s<   e Zd Zddddddddddgf	 fd	d
	Zdd Z  ZS )ParseNet   r   @      
   r:   r      c
                    s  t    || _||d}
|	\  fdd}t||}tt|| }tt|| }g | _| jt	d|dd |}t
|D ]@}||||d  }}| jt||fddi|
 |d }qg | _t
|D ]&}| jt||||fi |
 qg | _t
|D ]B}||||d  }}| jt||fdd	i|
 |d }qtj| j | _tj| j | _tj| j | _t	||d| _t	|||| _d S )
NrY   c                    s   t t|  S r>   )maxminr   Zmax_chZmin_chr   r   r      r   z#ParseNet.__init__.<locals>.<lambda>r@   r   r
   rT   rA   rB   )r   r   	res_depthrh   rK   rL   log2encoderappendr?   rangerX   bodydecoderr   
Sequentialout_img_convout_mask_conv)r%   in_sizeout_sizeZmin_feat_sizeZbase_ch
parsing_chrj   r=   r   Zch_rangeZact_argsZch_clipZ
down_stepsZup_stepsZhead_chiZcinZcoutr'   ri   r   r      s8    




$zParseNet.__init__c                 C   s>   |  |}|| | }| |}| |}| |}||fS r>   )rl   ro   rp   rr   rs   )r%   r   featout_imgout_maskr   r   r   r+      s    



zParseNet.forwardrW   r   r   r'   r   ra      s   .ra   )r0   numpyrL   torch.nnr   r   r   Moduler   r2   r?   rX   ra   r   r   r   r   <module>   s   " '