U
    ¯Ê¹j</  ã                   @   sÆ   d Z ddlZddlmZ ddlmZ ddlmZmZm	Z	m
Z
mZ ddddd	d
gZ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G dd	„ d	eƒZG dd
„ d
ejƒZdS )z[ EfficientNet, MobileNetV3, etc Blocks

Hacked together by / Copyright 2019, Ross Wightman
é    N)Ú
functional)Úcreate_conv2dÚDropPathÚmake_divisibleÚcreate_act_layerÚget_norm_act_layerÚSqueezeExciteÚ	ConvBnActÚDepthwiseSeparableConvÚInvertedResidualÚCondConvResidualÚEdgeResidualc                 C   s$   | sdS ||  dkst ‚||  S d S )Né   r   )ÚAssertionError)Ú
group_sizeZchannels© r   ú_/var/www/html/bwave/python/venv/lib/python3.8/site-packages/timm/models/_efficientnet_blocks.pyÚ
num_groups   s    r   c                       s:   e Zd ZdZddejejddf‡ fdd„	Zdd„ Z‡  Z	S )r   aç   Squeeze-and-Excitation w/ specific features for EfficientNet/MobileNet family

    Args:
        in_chs (int): input channels to layer
        rd_ratio (float): ratio of squeeze reduction
        act_layer (nn.Module): activation layer of containing block
        gate_layer (Callable): attention gate function
        force_act_layer (nn.Module): override block's activation fn if this is set/bound
        rd_round_fn (Callable): specify a fn to calculate rounding of reduced chs
    g      Ð?Nc                    sv   t t| ƒ ¡  |d kr*|pt}||| ƒ}|p0|}tj||ddd�| _t|dd�| _tj||ddd�| _	t|ƒ| _
d S )Nr   T)Zbias©Úinplace)Úsuperr   Ú__init__ÚroundÚnnZConv2dÚconv_reducer   Úact1Úconv_expandÚgate)ÚselfÚin_chsZrd_ratioZrd_channelsÚ	act_layerZ
gate_layerZforce_act_layerZrd_round_fn©Ú	__class__r   r   r   %   s    zSqueezeExcite.__init__c                 C   s:   |j ddd�}|  |¡}|  |¡}|  |¡}||  |¡ S )N)é   é   T)Zkeepdim)Zmeanr   r   r   r   )r   ÚxZx_ser   r   r   Úforward2   s
    


zSqueezeExcite.forward)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ÚReLUZSigmoidr   r&   Ú__classcell__r   r   r!   r   r      s       þc                       sF   e Zd ZdZdddddejejdf‡ fdd„	Zd	d
„ Zdd„ Z	‡  Z
S )r	   z@ Conv + Norm Layer + Activation w/ optional skip connection
    r   r   Ú Fç        c              	      sx   t t| ƒ ¡  t|
|	ƒ}t||ƒ}|o4|dko4||k| _t|||||||d�| _||dd�| _|rjt	|ƒnt
 ¡ | _d S )Nr   ©ÚstrideÚdilationÚgroupsÚpaddingTr   )r   r	   r   r   r   Úhas_skipr   ÚconvÚbn1r   r   ÚIdentityÚ	drop_path)r   r   Úout_chsZkernel_sizer0   r1   r   Úpad_typeÚskipr    Ú
norm_layerÚdrop_path_rateÚnorm_act_layerr2   r!   r   r   r   =   s    

      ÿzConvBnAct.__init__c                 C   s.   |dkrt dd| jjd�S t d| jjd�S d S )NÚ	expansionr6   r&   ©ÚmoduleZ	hook_typeÚnum_chsr-   ©rA   rB   )Údictr5   Úout_channels©r   Úlocationr   r   r   Úfeature_infoJ   s    zConvBnAct.feature_infoc                 C   s0   |}|   |¡}|  |¡}| jr,|  |¡| }|S ©N)r5   r6   r4   r8   ©r   r%   Úshortcutr   r   r   r&   P   s    

zConvBnAct.forward©r'   r(   r)   r*   r   r+   ÚBatchNorm2dr   rH   r&   r,   r   r   r!   r   r	   :   s         þc                       sN   e Zd ZdZddddddddejejddf‡ fdd	„	Zd
d„ Zdd„ Z	‡  Z
S )r
   zÔ DepthwiseSeparable block
    Used for DS convs in MobileNet-V1 and in the place of IR blocks that have no expansion
    (factor of 1.0). This is an alternative to having a IR with an optional first pw conv.
    r$   r   r-   FNr.   c              	      s¾   t t| ƒ ¡  t||ƒ}t||ƒ}|dko6||ko6| | _|
| _t|||||||d�| _||dd�| _	|rv|||d�nt
 ¡ | _t|||	|d�| _||d| jd�| _|r°t|ƒnt
 ¡ | _d S )Nr   )r0   r1   r3   r2   Tr   ©r    ©r3   )r   Ú	apply_act)r   r
   r   r   r   r4   Z
has_pw_actr   Úconv_dwr6   r   r7   ÚseÚconv_pwÚbn2r   r8   )r   r   r9   Údw_kernel_sizer0   r1   r   r:   ÚnoskipÚpw_kernel_sizeZpw_actr    r<   Úse_layerr=   r>   r2   r!   r   r   r   ^   s&    

      ÿzDepthwiseSeparableConv.__init__c                 C   s.   |dkrt dd| jjd�S t d| jjd�S d S )Nr?   rS   Úforward_prer@   r-   rC   )rD   rS   Úin_channelsrE   rF   r   r   r   rH   s   s    z#DepthwiseSeparableConv.feature_infoc                 C   sN   |}|   |¡}|  |¡}|  |¡}|  |¡}|  |¡}| jrJ|  |¡| }|S rI   )rQ   r6   rR   rS   rT   r4   r8   rJ   r   r   r   r&   y   s    




zDepthwiseSeparableConv.forwardrL   r   r   r!   r   r
   Y   s             ýc                       sR   e Zd ZdZdddddddddejejdddf‡ fd	d
„	Zdd„ Zdd„ Z	‡  Z
S )r   a„   Inverted residual block w/ optional SE

    Originally used in MobileNet-V2 - https://arxiv.org/abs/1801.04381v4, this layer is often
    referred to as 'MBConv' for (Mobile inverted bottleneck conv) and is also used in
      * MNasNet - https://arxiv.org/abs/1807.11626
      * EfficientNet - https://arxiv.org/abs/1905.11946
      * MobileNet-V3 - https://arxiv.org/abs/1905.02244
    r$   r   r-   Fç      ð?Nr.   c                    s   t t| ƒ ¡  t||ƒ}|pi }t||	 ƒ}t||ƒ}||koJ|dkoJ| | _t|||
fd|i|—Ž| _||dd�| _	t|||f||||dœ|—Ž| _
||dd�| _|r´|||d�nt ¡ | _t|||fd|i|—Ž| _||dd�| _|ròt|ƒnt ¡ | _d S )	Nr   r3   Tr   r/   rN   F©rP   )r   r   r   r   r   r   r4   r   rS   r6   rQ   rT   r   r7   rR   Úconv_pwlÚbn3r   r8   )r   r   r9   rU   r0   r1   r   r:   rV   Ú	exp_ratioÚexp_kernel_sizerW   r    r<   rX   Úconv_kwargsr=   r>   Úmid_chsr2   r!   r   r   r   �   s2    

  ÿ  þþzInvertedResidual.__init__c                 C   s.   |dkrt dd| jjd�S t d| jjd�S d S ©Nr?   r]   rY   r@   r-   rC   ©rD   r]   rZ   rE   rF   r   r   r   rH   ¬   s    zInvertedResidual.feature_infoc                 C   sb   |}|   |¡}|  |¡}|  |¡}|  |¡}|  |¡}|  |¡}|  |¡}| jr^|  |¡| }|S rI   )	rS   r6   rQ   rT   rR   r]   r^   r4   r8   rJ   r   r   r   r&   ²   s    






zInvertedResidual.forwardrL   r   r   r!   r   r   …   s$   
           ýc                       sJ   e Zd ZdZdddddddddejejddd	f‡ fd
d„	Zdd„ Z‡  Z	S )r   z, Inverted residual block w/ CondConv routingr$   r   r-   Fr[   Nr   r.   c                    sV   || _ t| j d�}tt| ƒj||||||||||	|
|||||d� t || j ¡| _d S )N)Únum_experts)rU   r0   r1   r   r:   r    rV   r_   r`   rW   rX   r<   ra   r=   )re   rD   r   r   r   r   ZLinearÚ
routing_fn)r   r   r9   rU   r0   r1   r   r:   rV   r_   r`   rW   r    r<   rX   re   r=   ra   r!   r   r   r   Ã   s*    
            üzCondConvResidual.__init__c                 C   sŠ   |}t  |d¡ d¡}t |  |¡¡}|  ||¡}|  |¡}|  ||¡}|  	|¡}|  
|¡}|  ||¡}|  |¡}| jr†|  |¡| }|S )Nr   )ÚFZadaptive_avg_pool2dÚflattenÚtorchZsigmoidrf   rS   r6   rQ   rT   rR   r]   r^   r4   r8   )r   r%   rK   Zpooled_inputsZrouting_weightsr   r   r   r&   Ó   s    



zCondConvResidual.forward)
r'   r(   r)   r*   r   r+   rM   r   r&   r,   r   r   r!   r   r   À   s"              ýc                       sP   e Zd ZdZdddddddddejejdd	f‡ fd
d„	Zdd„ Zdd„ Z	‡  Z
S )r   a(   Residual block with expansion convolution followed by pointwise-linear w/ stride

    Originally introduced in `EfficientNet-EdgeTPU: Creating Accelerator-Optimized Neural Networks with AutoML`
        - https://ai.googleblog.com/2019/08/efficientnet-edgetpu-creating.html

    This layer is also called FusedMBConv in the MobileDet, EfficientNet-X, and EfficientNet-V2 papers
      * MobileDet - https://arxiv.org/abs/2004.14525
      * EfficientNet-X - https://arxiv.org/abs/2102.05610
      * EfficientNet-V2 - https://arxiv.org/abs/2104.00298
    r$   r   r   r-   Fr[   Nr.   c              	      sÖ   t t| ƒ ¡  t||ƒ}|dkr.t||
 ƒ}nt||
 ƒ}t||ƒ}||koX|dkoX|	 | _t|||||||d�| _||dd�| _	|r’|||d�nt
 ¡ | _t||||d�| _||dd	�| _|rÈt|ƒnt
 ¡ | _d S )
Nr   r   r/   Tr   rN   rO   Fr\   )r   r   r   r   r   r   r4   r   Úconv_expr6   r   r7   rR   r]   rT   r   r8   )r   r   r9   r`   r0   r1   r   r:   Zforce_in_chsrV   r_   rW   r    r<   rX   r=   r>   rb   r2   r!   r   r   r   ï   s*    

      ÿzEdgeResidual.__init__c                 C   s.   |dkrt dd| jjd�S t d| jjd�S d S rc   rd   rF   r   r   r   rH   	  s    zEdgeResidual.feature_infoc                 C   sN   |}|   |¡}|  |¡}|  |¡}|  |¡}|  |¡}| jrJ|  |¡| }|S rI   )rj   r6   rR   r]   rT   r4   r8   rJ   r   r   r   r&     s    




zEdgeResidual.forwardrL   r   r   r!   r   r   ã   s"             ý)r*   ri   Ztorch.nnr   r   rg   Ztimm.layersr   r   r   r   r   Ú__all__r   ÚModuler   r	   r
   r   r   r   r   r   r   r   Ú<module>   s$        ÿ	!,;#