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)ZaffineinFZgn    Zpixelc                 S   s   t j| dddS )N      )pZdim)F	normalizex r   b/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/facexlib/parsing/parsenet.py<lambda>       z$NormLayer.__init__.<locals>.<lambda>Z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nnZBatchNorm2dnormZInstanceNorm2dZ	GroupNormZ	LayerNorm)selfchannelsZnormalize_shaper   	__class__r   r   r      s     zNormLayer.__init__c                 C   s$   | j dkr| ||S | |S d S )NZ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 )Nr)   TZ	leakyrelug?)ZinplacepreluZ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   r(   r   r   r   ZReLUfunc	LeakyReLUZPReLUZSELU)r   r   	relu_typer   r   r   r   6   s    zReluLayer.__init__c                 C   s
   |  |S N)r+   )r   r   r   r   r   r!   F   s    zReluLayer.forward)r)   r"   r   r   r   r   r(   *   s   r(   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   Znearest)Zscale_factormode)r   r   Zinterpolater   r   r   r   r   _   r   r   )bias)r   )r   r/   r   use_padr   
scale_funcr   ZReflectionPad2dintnpceilreflection_padZConv2dconv2dr(   r)   r   r   )
r   Zin_channelsZout_channelsZkernel_sizescaler   r-   r5   r4   Zstrider   r   r   r   L   s    	

zConvLayer.__init__c                 C   s<   |  |}| jr| |}| |}| |}| |}|S r.   )r6   r5   r:   r;   r   r)   )r   r   outr   r   r   r!   g   s    




zConvLayer.forward)r0   r   r   r   TTr#   r$   r%   r   r!   r'   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
    r*   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>r0   r1   r2   )r1   r2   r   r   r   r-   r   )r   r?   r   shortcut_funcr/   conv1conv2)r   Zc_inZc_outr-   r   r<   Zscale_config_dictZ
scale_confr   r   r   r   v   s    zResidualBlock.__init__c                 C   s&   |  |}| |}| |}|| S r.   )rA   rB   rC   )r   r   identityresr   r   r   r!      s    


zResidualBlock.forward)r*   r   r   r"   r   r   r   r   r?   q   s   r?   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 )
Nr@   c                    s   t t|  S r.   )maxminr   Zmax_chZmin_chr   r   r      r   z#ParseNet.__init__.<locals>.<lambda>r0   r   r   r<   r1   r2   )r   r   	res_depthrM   r7   r8   log2encoderappendr/   ranger?   bodydecoderr   Z
Sequentialout_img_convout_mask_conv)r   Zin_sizeZout_sizeZmin_feat_sizeZbase_chZ
parsing_chrO   r-   r   Zch_rangeZact_argsZch_clipZ
down_stepsZup_stepsZhead_chiZcinZcoutr   rN   r   r      s8    




$zParseNet.__init__c                 C   s>   |  |}|| | }| |}| |}| |}||fS r.   )rQ   rT   rU   rV   rW   )r   r   ZfeatZout_imgZout_maskr   r   r   r!      s    



zParseNet.forwardr>   r   r   r   r   rF      s   .rF   )r&   numpyr8   Ztorch.nnr   r   r
   Moduler   r(   r/   r?   rF   r   r   r   r   <module>   s   " '