a
    þd‹  ã                   @   sˆ   d dl mZ d dlmZ ddd„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	e 
¡ G dd„ dejƒƒZdS )é    N)ÚARCH_REGISTRYé   c                 C   s   t j| |d|dddS )záA simple wrapper for 3x3 convolution with padding.

    Args:
        inplanes (int): Channel number of inputs.
        outplanes (int): Channel number of outputs.
        stride (int): Stride in convolution. Default: 1.
    é   r   F©Úkernel_sizeÚstrideÚpaddingÚbias)ÚnnÚConv2d)ÚinplanesZ	outplanesr   © r   úb/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/gfpgan/archs/arcface_arch.pyÚconv3x3   s    r   c                       s.   e Zd ZdZdZd‡ fdd„	Zdd„ Z‡  ZS )	Ú
BasicBlocka.  Basic residual block used in the ResNetArcFace architecture.

    Args:
        inplanes (int): Channel number of inputs.
        planes (int): Channel number of outputs.
        stride (int): Stride in convolution. Default: 1.
        downsample (nn.Module): The downsample module. Default: None.
    r   Nc                    s^   t t| ƒ ¡  t|||ƒ| _t |¡| _tjdd| _	t||ƒ| _
t |¡| _|| _|| _d S )NT©Zinplace)Úsuperr   Ú__init__r   Úconv1r
   ÚBatchNorm2dÚbn1ÚReLUÚreluÚconv2Úbn2Ú
downsampler   ©Úselfr   Úplanesr   r   ©Ú	__class__r   r   r      s    zBasicBlock.__init__c                 C   s`   |}|   |¡}|  |¡}|  |¡}|  |¡}|  |¡}| jd urJ|  |¡}||7 }|  |¡}|S ©N)r   r   r   r   r   r   ©r   ÚxZresidualÚoutr   r   r   Úforward%   s    







zBasicBlock.forward)r   N©Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú	expansionr   r%   Ú__classcell__r   r   r   r   r      s   
r   c                       s.   e Zd ZdZdZd	‡ fdd„	Zdd„ Z‡  ZS )
ÚIRBlockaš  Improved residual block (IR Block) used in the ResNetArcFace architecture.

    Args:
        inplanes (int): Channel number of inputs.
        planes (int): Channel number of outputs.
        stride (int): Stride in convolution. Default: 1.
        downsample (nn.Module): The downsample module. Default: None.
        use_se (bool): Whether use the SEBlock (squeeze and excitation block). Default: True.
    r   NTc                    s|   t t| ƒ ¡  t |¡| _t||ƒ| _t |¡| _t 	¡ | _
t|||ƒ| _t |¡| _|| _|| _|| _| jrxt|ƒ| _d S r!   )r   r-   r   r
   r   Úbn0r   r   r   ÚPReLUÚprelur   r   r   r   Úuse_seÚSEBlockÚse)r   r   r   r   r   r1   r   r   r   r   D   s    
zIRBlock.__init__c                 C   sz   |}|   |¡}|  |¡}|  |¡}|  |¡}|  |¡}|  |¡}| jrP|  |¡}| jd urd|  |¡}||7 }|  |¡}|S r!   )	r.   r   r   r0   r   r   r1   r3   r   r"   r   r   r   r%   R   s    









zIRBlock.forward)r   NTr&   r   r   r   r   r-   8   s   	r-   c                       s.   e Zd ZdZdZd	‡ fdd„	Zdd„ Z‡  ZS )
Ú
Bottlenecka*  Bottleneck block used in the ResNetArcFace architecture.

    Args:
        inplanes (int): Channel number of inputs.
        planes (int): Channel number of outputs.
        stride (int): Stride in convolution. Default: 1.
        downsample (nn.Module): The downsample module. Default: None.
    é   r   Nc                    sœ   t t| ƒ ¡  tj||ddd| _t |¡| _tj||d|ddd| _t |¡| _	tj||| j
 ddd| _t || j
 ¡| _tjdd| _|| _|| _d S )Nr   F)r   r	   r   r   Tr   )r   r4   r   r
   r   r   r   r   r   r   r+   Úconv3Úbn3r   r   r   r   r   r   r   r   r   r   s    zBottleneck.__init__c                 C   s~   |}|   |¡}|  |¡}|  |¡}|  |¡}|  |¡}|  |¡}|  |¡}|  |¡}| jd urh|  |¡}||7 }|  |¡}|S r!   )r   r   r   r   r   r6   r7   r   r"   r   r   r   r%   ~   s    










zBottleneck.forward)r   Nr&   r   r   r   r   r4   g   s   r4   c                       s*   e Zd ZdZd‡ fdd„	Zdd„ Z‡  ZS )r2   zÀThe squeeze-and-excitation block (SEBlock) used in the IRBlock.

    Args:
        channel (int): Channel number of inputs.
        reduction (int): Channel reduction ration. Default: 16.
    é   c                    sP   t t| ƒ ¡  t d¡| _t t ||| ¡t ¡ t || |¡t 	¡ ¡| _
d S ©Nr   )r   r2   r   r
   ZAdaptiveAvgPool2dÚavg_poolÚ
SequentialÚLinearr/   ZSigmoidÚfc)r   ZchannelZ	reductionr   r   r   r      s    "þzSEBlock.__init__c                 C   s@   |  ¡ \}}}}|  |¡ ||¡}|  |¡ ||dd¡}|| S r9   )Úsizer:   Úviewr=   )r   r#   ÚbÚcÚ_Úyr   r   r   r%   ¤   s    zSEBlock.forward)r8   )r'   r(   r)   r*   r   r%   r,   r   r   r   r   r2   •   s   r2   c                       s4   e Zd ZdZd
‡ fdd„	Zddd„Zdd	„ Z‡  ZS )ÚResNetArcFaceaR  ArcFace with ResNet architectures.

    Ref: ArcFace: Additive Angular Margin Loss for Deep Face Recognition.

    Args:
        block (str): Block used in the ArcFace architecture.
        layers (tuple(int)): Block numbers in each layer.
        use_se (bool): Whether use the SEBlock (squeeze and excitation block). Default: True.
    Tc                    s†  |dkrt }d| _|| _tt| ƒ ¡  tjdddddd| _t 	d¡| _
t ¡ | _tjddd| _|  |d|d	 ¡| _| j|d
|d dd| _| j|d|d dd| _| j|d|d dd| _t 	d¡| _t ¡ | _t dd¡| _t d¡| _|  ¡ D ]Š}t|tjƒrtj |j¡ qöt|tj	ƒs4t|tjƒrVtj  |jd¡ tj  |j!d	¡ qöt|tjƒrötj |j¡ tj  |j!d	¡ qöd S )Nr-   é@   r   r   F)r   r   r	   é   )r   r   r   é€   )r   é   i   i €  )"r-   r   r1   r   rD   r   r
   r   r   r   r   r/   r0   Z	MaxPool2dÚmaxpoolÚ_make_layerÚlayer1Úlayer2Úlayer3Úlayer4Úbn4ZDropoutÚdropoutr<   Úfc5ZBatchNorm1dÚbn5ÚmodulesÚ
isinstanceÚinitZxavier_normal_ZweightZ	constant_r	   )r   ÚblockÚlayersr1   Úmr   r   r   r   ·   s4    

zResNetArcFace.__init__r   c              	   C   s¤   d }|dks| j ||j krLt tj| j ||j d|ddt ||j ¡¡}g }| || j |||| jd¡ || _ td|ƒD ]}| || j || jd¡ q|tj|Ž S )Nr   F)r   r   r	   )r1   )	r   r+   r
   r;   r   r   Úappendr1   Úrange)r   rV   r   Z
num_blocksr   r   rW   rB   r   r   r   rJ   Ö   s    þzResNetArcFace._make_layerc                 C   sŽ   |   |¡}|  |¡}|  |¡}|  |¡}|  |¡}|  |¡}|  |¡}|  |¡}|  |¡}|  	|¡}| 
| d¡d¡}|  |¡}|  |¡}|S )Nr   éÿÿÿÿ)r   r   r0   rI   rK   rL   rM   rN   rO   rP   r?   r>   rQ   rR   )r   r#   r   r   r   r%   å   s    











zResNetArcFace.forward)T)r   )r'   r(   r)   r*   r   rJ   r%   r,   r   r   r   r   rD   «   s   

rD   )r   )Ztorch.nnr
   Zbasicsr.utils.registryr   r   ÚModuler   r-   r4   r2   ÚregisterrD   r   r   r   r   Ú<module>   s   
(/.