a
    dF&                     @   s   d dl Z d dlmZ d dlm  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G dd dejZG dd dejZdS )    N   )MobileNetV2Backbonec                       s(   e Zd ZdZ fddZdd Z  ZS )IBNormz9 Combine Instance Norm and Batch Norm into One Layer
    c                    sT   t t|   |}t|d | _|| j | _tj| jdd| _tj	| jdd| _
d S )N   T)ZaffineF)superr   __init__intbnorm_channelsZinorm_channelsnnBatchNorm2dbnormInstanceNorm2dinorm)selfin_channels	__class__ `/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/facexlib/matting/modnet.pyr      s    zIBNorm.__init__c                 C   sT   |  |d d d | jdf  }| |d d | jd df  }t||fdS )N.r   )r   r	   
contiguousr   torchcat)r   xZbn_xZin_xr   r   r   forward   s    ""zIBNorm.forward__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 )
Conv2dIBNormReluz! Convolution + IBNorm + ReLu
    r   r   Tc              
      sb   t t|   tj||||||||dg}|	r<|t| |
rR|tjdd tj| | _	d S )N)stridepaddingdilationgroupsbiasTZinplace)
r   r    r   r
   Conv2dappendr   ReLU
Sequentiallayers)r   r   out_channelskernel_sizer!   r"   r#   r$   r%   with_ibn	with_relur+   r   r   r   r   $   s"    zConv2dIBNormRelu.__init__c                 C   s
   |  |S N)r+   )r   r   r   r   r   r   D   s    zConv2dIBNormRelu.forward)r   r   r   r   TTTr   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 )SEBlockz? SE Block Proposed in https://arxiv.org/pdf/1709.01507.pdf
    r   c              	      sd   t t|   td| _ttj|t|| ddtj	ddtjt|| |ddt
 | _d S )Nr   F)r%   Tr&   )r   r1   r   r
   ZAdaptiveAvgPool2dpoolr*   ZLinearr   r)   ZSigmoidfc)r   r   r,   	reductionr   r   r   r   L   s     zSEBlock.__init__c                 C   sF   |  \}}}}| |||}| |||dd}||| S )Nr   )sizer2   viewr3   Z	expand_as)r   r   bc_wr   r   r   r   S   s    zSEBlock.forward)r   r   r   r   r   r   r1   H   s   r1   c                       s(   e Zd ZdZ fddZdd Z  ZS )LRBranchz% Low Resolution Branch of MODNet
    c              	      s   t t|   |j}|| _t|d |d dd| _t|d |d dddd| _t|d |d dddd| _	t|d ddddddd	| _
d S )
N   )r4         r   r   r!   r"   Fr-   r!   r"   r.   r/   )r   r;   r   enc_channelsbackboner1   se_blockr    
conv_lr16x	conv_lr8xconv_lr)r   rB   rA   r   r   r   r   d   s    zLRBranch.__init__c                 C   s   | j |}|d |d |d   }}}| |}tj|dddd}| |}tj|dddd}| |}d }	|s| |}
t	|
}	|	|||gfS )Nr   r   r<   r   bilinearFZscale_factormodeZalign_corners)
rB   r   rC   FinterpolaterD   rE   rF   r   sigmoid)r   img	inferenceZenc_featuresenc2xenc4xZenc32xZlr16xlr8xpred_semanticlrr   r   r   r   p   s    




zLRBranch.forwardr   r   r   r   r   r;   `   s   r;   c                       s(   e Zd ZdZ fddZdd Z  ZS )HRBranchz& High Resolution Branch of MODNet
    c                    sP  t t|   t|d |dddd| _t|d |dddd| _t|d |dddd| _td| d| dddd| _t	td| d d| ddddtd| d| ddddtd| |dddd| _
t	td| d| ddddtd| |ddddt||ddddt||dddd| _t	t|d |ddddt|ddddddd| _d S )Nr   r   r?   r=   r   Fr@   )r   rT   r   r    
tohr_enc2x
conv_enc2x
tohr_enc4x
conv_enc4xr
   r*   	conv_hr4x	conv_hr2xconv_hrr   hr_channelsrA   r   r   r   r      s(    zHRBranch.__init__c                 C   s  t j|dddd}t j|dddd}| |}| tj||fdd}| |}| tj||fdd}t j|dddd}	| tj||	|fdd}t j|dddd}
| 	tj|
|fdd}
d }|st j|
dddd}| 
tj||fdd}t|}||
fS )	Ng      ?rG   FrH   g      ?r   Zdimr   )rJ   rK   rU   rV   r   r   rW   rX   rY   rZ   r[   rL   )r   rM   rO   rP   rQ   rN   Zimg2xZimg4xZhr4xlr4xhr2xpred_detailhrr   r   r   r      s     


zHRBranch.forwardr   r   r   r   r   rT      s   rT   c                       s(   e Zd ZdZ fddZdd Z  ZS )FusionBranchz Fusion Branch of MODNet
    c                    s   t t|   t|d |dddd| _td| |dddd| _tt|d t|d ddddtt|d ddddddd| _	d S )	Nr   r>   r   r?   r=   r   F)r!   r"   r.   r/   )
r   rc   r   r    	conv_lr4xconv_f2xr
   r*   r   conv_fr\   r   r   r   r      s    zFusionBranch.__init__c           	      C   s~   t j|dddd}| |}t j|dddd}| tj||fdd}t j|dddd}| tj||fdd}t|}|S )Nr   rG   FrH   r   r^   )rJ   rK   rd   re   r   r   rf   rL   )	r   rM   rQ   r`   r_   Zlr2xZf2xf
pred_matter   r   r   r      s    

zFusionBranch.forwardr   r   r   r   r   rc      s   
rc   c                       sB   e Zd ZdZd fdd	Zdd Zd	d
 Zdd Zdd Z  Z	S )MODNetz Architecture of MODNet
    r=       Tc                    s   t t|   || _|| _|| _t| j| _t| j| _	t
| j| jj| _t| j| jj| _|  D ]>}t|tjr| | qdt|tjst|tjrd| | qd| jr| j  d S r0   )r   ri   r   r   r]   backbone_pretrainedr   rB   r;   	lr_branchrT   rA   	hr_branchrc   f_branchmodules
isinstancer
   r'   
_init_convr   r   
_init_normZload_pretrained_ckpt)r   r   r]   rk   mr   r   r   r      s    zMODNet.__init__c           
      C   sD   |  ||\}}\}}| |||||\}}| |||}	|||	fS r0   )rl   rm   rn   )
r   rM   rN   rR   rQ   rO   rP   ra   r`   rh   r   r   r   r      s    zMODNet.forwardc                 C   s<   t jt jg}|  D ]"}|D ]}t||r|  qqqd S r0   )r
   r   r   ro   rp   eval)r   Z
norm_typesrs   nr   r   r   freeze_norm   s    
zMODNet.freeze_normc                 C   s4   t jj|jdddd |jd ur0t j|jd d S )Nr   Zfan_inZrelu)arI   Znonlinearity)r
   initZkaiming_uniform_weightr%   	constant_)r   convr   r   r   rq     s    
zMODNet._init_convc                 C   s.   |j d ur*tj|j d tj|jd d S )Nr   r   )ry   r
   rx   rz   r%   )r   Znormr   r   r   rr     s    
zMODNet._init_norm)r=   rj   T)
r   r   r   r   r   r   rv   rq   rr   r   r   r   r   r   ri      s   ri   )r   Ztorch.nnr
   Ztorch.nn.functionalZ
functionalrJ   rB   r   Moduler   r    r1   r;   rT   rc   ri   r   r   r   r   <module>   s   ("8 