U
    ¯Ê¹j½  ã                   @   s’  d dl Z d dlmZ d dlmZmZmZ d dlZd dlm	Z	 d dl
mZmZ d dlmZmZmZmZmZmZmZ ddlmZ ddlmZ dd	lmZmZ d
d„ ZG dd„ de	jƒZG dd„ de	jƒZe	j dfe!e!e	je"e	j#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(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@d)d*„Z/ee/d+d,�e/d+d,�e/d+d,�e/d+d,�e/d+d,�e/d+d,�e/d+d-d.�e/d+d,�e/d+d,�e/d+d,�e/d+d,�e/d+d,�e/d+d,�e/d+d-d.�d/œƒZ0dAd0d1„Z1edBd2d3„ƒZ2edCd4d5„ƒZ3edDd6d7„ƒZ4edEd8d9„ƒZ5edFd:d;„ƒZ6edGd<d=„ƒZ7edHd>d?„ƒZ8dS )Ié    N)Úpartial)ÚTupleÚOptionalÚUnion©ÚIMAGENET_DEFAULT_MEANÚIMAGENET_DEFAULT_STD)ÚDropPathÚtrunc_normal_Úcreate_conv2dÚConvNormActÚSqueezeExciteÚuse_fused_attnÚClassifierHeadé   )Úbuild_model_with_cfg)Úcheckpoint_seq)Úregister_modelÚgenerate_default_cfgsc                 C   s$   | sdS ||  dkst ‚||  S d S )Nr   r   )ÚAssertionError)Ú
group_sizeZchannels© r   úR/var/www/html/bwave/python/venv/lib/python3.8/site-packages/timm/models/fastvit.pyÚ
num_groups   s    r   c                       s´   e Zd ZdZddddddddejf	eeeeeeeeeeeejddœ‡ fdd	„Z	e
je
jd
œdd„Zdd„ Zee
je
jf dœdd„Zeejejf ee
je
jf dœdd„Z‡  ZS )ÚMobileOneBlocka#  MobileOne building block.

    This block has a multi-branched architecture at train-time
    and plain-CNN style architecture at inference time
    For more details, please refer to our paper:
    `An Improved One millisecond Mobile Backbone` -
    https://arxiv.org/pdf/2206.04040.pdf
    r   r   FTN)Úin_chsÚout_chsÚkernel_sizeÚstrideÚdilationr   Úinference_modeÚuse_seÚuse_actÚuse_scale_branchÚnum_conv_branchesÚ	act_layerÚreturnc              	      s&  t tˆƒ ¡  |ˆ_t||ƒˆ_|ˆ_|ˆ_ˆ ˆ_|ˆ_	|ˆ_
|ˆ_|rTt|dd�nt ¡ ˆ_|r~t||ˆ ||ˆjdd�ˆ_nŽdˆ_||kr |dkr tj|d�ndˆ_|dkrÒt ‡ ‡fdd	„tˆjƒD ƒ¡ˆ_ndˆ_dˆ_ˆ dk�r|
�rtˆj	ˆj
dˆjˆjd
d�ˆ_|	�r|ƒ nt ¡ ˆ_dS )a·  Construct a MobileOneBlock module.

        Args:
            in_chs: Number of channels in the input.
            out_chs: Number of channels produced by the block.
            kernel_size: Size of the convolution kernel.
            stride: Stride size.
            dilation: Kernel dilation factor.
            group_size: Convolution group size.
            inference_mode: If True, instantiates model in inference mode.
            use_se: Whether to use SE-ReLU activations.
            use_act: Whether to use activation. Default: ``True``
            use_scale_branch: Whether to use scale branch. Default: ``True``
            num_conv_branches: Number of linear conv branches.
        r   )Z
rd_divisorT©r   r   r   ÚgroupsÚbiasN)Únum_featuresr   c              
      s(   g | ] }t ˆjˆjˆ ˆjˆjd d�‘qS )F©r   r   r(   Ú	apply_act)r   r   r   r   r(   )Ú.0Ú_©r   Úselfr   r   Ú
<listcomp>k   s   ùúz+MobileOneBlock.__init__.<locals>.<listcomp>Fr+   )Úsuperr   Ú__init__r    r   r(   r   r   r   r   r   r$   r   ÚnnÚIdentityÚser   Úreparam_convÚBatchNorm2dÚidentityZ
ModuleListÚrangeÚconv_kxkÚ
conv_scaler   Úact)r0   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   ©Ú	__class__r/   r   r3   *   sV    ù
ÿÿýøú	zMobileOneBlock.__init__©Úxr&   c                 C   sŠ   | j dk	r |  |  |   |¡¡¡S d}| jdk	r8|  |¡}d}| jdk	rP|  |¡}|| }| jdk	rz| jD ]}|||ƒ7 }qh|  |  |¡¡S )zApply forward pass.Nr   )r7   r=   r6   r9   r<   r;   )r0   rA   Zidentity_outZ	scale_outÚoutÚrcr   r   r   Úforward†   s    






zMobileOneBlock.forwardc              	   C   s¨   | j dk	rdS |  ¡ \}}t| j| j| j| j| j| jdd�| _ || j j	_
|| j j_
|  ¡ D ]\}}d|krlqZ| ¡  qZ|  d¡ |  d¡ t| dƒrž|  d¡ d| _dS )a  Following works like `RepVGG: Making VGG-style ConvNets Great Again` -
        https://arxiv.org/pdf/2101.03697.pdf. We re-parameterize multi-branched
        architecture used at training time to obtain a plain CNN-like structure
        for inference.
        NT)Zin_channelsZout_channelsr   r   r   r(   r)   r7   r;   r<   r9   )r7   Ú_get_kernel_biasr   r   r   r   r   r   r(   ÚweightÚdatar)   Únamed_parametersÚdetach_Ú__delattr__Úhasattrr    )r0   Úkernelr)   ÚnameÚparar   r   r   ÚreparameterizeŸ   s.    
ù	






zMobileOneBlock.reparameterize©r&   c                 C   sÌ   d}d}| j dk	rD|  | j ¡\}}| jd }tjj |||||g¡}d}d}| jdk	rf|  | j¡\}}d}d}| jdk	r¬t	| j
ƒD ](}|  | j| ¡\}	}
||	7 }||
7 }q‚|| | }|| | }||fS )z×Method to obtain re-parameterized kernel and bias.
        Reference: https://github.com/DingXiaoH/RepVGG/blob/main/repvgg.py#L83

        Returns:
            Tuple of (kernel, bias) after fusing branches.
        r   Né   )r<   Ú_fuse_bn_tensorr   Útorchr4   Ú
functionalÚpadr9   r;   r:   r$   )r0   Zkernel_scaleZ
bias_scalerU   Zkernel_identityZbias_identityZkernel_convZ	bias_convZixZ_kernelZ_biasZkernel_finalZ
bias_finalr   r   r   rE   Â   s(    




zMobileOneBlock._get_kernel_bias)Úbranchr&   c                 C   s  t |tƒr<|jj}|jj}|jj}|jj}|jj}|jj}n¦t |t	j
ƒsLt‚t| dƒs¾| j| j }tj| j|| j| jf|jj|jjd�}	t| jƒD ]$}
d|	|
|
| | jd | jd f< q’|	| _| j}|j}|j}|j}|j}|j}||  ¡ }||  dddd¡}|| ||| |  fS )a   Method to fuse batchnorm layer with preceeding conv layer.
        Reference: https://github.com/DingXiaoH/RepVGG/blob/main/repvgg.py#L95

        Args:
            branch: Sequence of ops to be fused.

        Returns:
            Tuple of (kernel, bias) after fusing batchnorm.
        Ú	id_tensor©ÚdtypeÚdevicer   rQ   éÿÿÿÿ)Ú
isinstancer   ÚconvrF   ÚbnÚrunning_meanÚrunning_varr)   Úepsr4   r8   r   rK   r   r(   rS   Úzerosr   rY   rZ   r:   rW   ÚsqrtÚreshape)r0   rV   rL   r_   r`   ÚgammaÚbetara   Ú	input_dimÚkernel_valueÚiÚstdÚtr   r   r   rR   å   s<    


ýþÿzMobileOneBlock._fuse_bn_tensor)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r4   ÚGELUÚintÚboolÚModuler3   rS   ÚTensorrD   rO   r   rE   r   Ú
Sequentialr8   rR   Ú__classcell__r   r   r>   r   r       s>   óò\#$þr   c                       s¤   e Zd ZdZdeeeeeee eeej ddœ	‡ fdd„Z	e
je
jdœdd	„Zee
je
jf d
œdd„Zdd
œdd„Zee
jejee
je
jf dœdd„ƒZ‡  ZS )ÚReparamLargeKernelConvzàBuilding Block of RepLKNet

    This class defines overparameterized large kernel conv block
    introduced in `RepLKNet <https://arxiv.org/abs/2203.06717>`_

    Reference: https://github.com/DingXiaoH/RepLKNet-pytorch
    NF)	r   r   r   r   r   Úsmall_kernelr    r%   r&   c	           	   	      sÆ   t t| ƒ ¡  || _t||ƒ| _|| _|| _|| _|| _	|rXt
||||d| jdd�| _nRd| _t|||| j| jdd�| _|dk	rª||ks�tdƒ‚t|||| j| jdd�| _|dk	r¸|ƒ nt ¡ | _dS )a!  Construct a ReparamLargeKernelConv module.

        Args:
            in_chs: Number of input channels.
            out_chs: Number of output channels.
            kernel_size: Kernel size of the large kernel conv branch.
            stride: Stride size. Default: 1
            group_size: Group size. Default: 1
            small_kernel: Kernel size of small kernel conv branch.
            inference_mode: If True, instantiates model in inference mode. Default: ``False``
            act_layer: Activation module. Default: ``nn.GELU``
        r   Tr'   NFr+   zDThe kernel size for re-param cannot be larger than the large kernel!)r2   rw   r3   r   r   r(   r   r   r   rx   r   r7   r   Ú
large_convr   Ú
small_convr4   r5   r=   )	r0   r   r   r   r   r   rx   r    r%   r>   r   r   r3     sP    ù

úÿþú	zReparamLargeKernelConv.__init__r@   c                 C   sF   | j d k	r|   |¡}n"|  |¡}| jd k	r8||  |¡ }|  |¡}|S ©N)r7   ry   rz   r=   )r0   rA   rB   r   r   r   rD   \  s    



zReparamLargeKernelConv.forwardrP   c                 C   sn   |   | jj| jj¡\}}t| dƒrf|   | jj| jj¡\}}||7 }|tj || j	| j
 d gd ¡7 }||fS )zÉMethod to obtain re-parameterized kernel and bias.
        Reference: https://github.com/DingXiaoH/RepLKNet-pytorch

        Returns:
            Tuple of (kernel, bias) after fusing branches.
        rz   rQ   é   )Ú_fuse_bnry   r]   r^   rK   rz   r4   rT   rU   r   rx   )r0   Úeq_kÚeq_bZsmall_kZsmall_br   r   r   Úget_kernel_biasf  s    
 ÿz&ReparamLargeKernelConv.get_kernel_biasc                 C   sb   |   ¡ \}}t| j| j| j| j| jdd�| _|| jj_	|| jj
_	|  d¡ t| dƒr^|  d¡ dS )a  
        Following works like `RepVGG: Making VGG-style ConvNets Great Again` -
        https://arxiv.org/pdf/2101.03697.pdf. We re-parameterize multi-branched
        architecture used at training time to obtain a plain CNN-like structure
        for inference.
        T©r   r   r(   r)   ry   rz   N)r€   r   r   r   r   r   r(   r7   rF   rG   r)   rJ   rK   )r0   r~   r   r   r   r   rO   v  s    ú	



z%ReparamLargeKernelConv.reparameterize)r]   r^   r&   c           
      C   s\   | j }|j}|j}|j }|j}|j}||  ¡ }||  dddd¡}	||	 ||| |  fS )zéMethod to fuse batchnorm layer with conv layer.

        Args:
            conv: Convolutional kernel weights.
            bn: Batchnorm 2d layer.

        Returns:
            Tuple of (kernel, bias) after fusing batchnorm.
        r[   r   )rF   r_   r`   r)   ra   rc   rd   )
r]   r^   rL   r_   r`   re   rf   ra   rj   rk   r   r   r   r}   �  s    zReparamLargeKernelConv._fuse_bn)NFN)rl   rm   rn   ro   rq   r   rr   r4   rs   r3   rS   rt   rD   r   r€   rO   Ústaticmethodr8   r}   rv   r   r   r>   r   rw     s.      ÷öB
 þrw   F)r   r   r%   r    r&   c                 C   s@   t  t| |dd||d�t||ddd||d�t||dd||d�¡S )a,  Build convolutional stem with MobileOne blocks.

    Args:
        in_chs: Number of input channels.
        out_chs: Number of output channels.
        inference_mode: Flag to instantiate model in inference mode. Default: ``False``

    Returns:
        nn.Sequential object with stem elements.
    é   rQ   ©r   r   r   r   r%   r    r   )r   r   r   r   r   r%   r    )r4   ru   r   )r   r   r%   r    r   r   r   Úconvolutional_stem¥  s6    úù	úîr…   c                       sX   e Zd ZU dZejje ed< de	e	ee
e
ddœ‡ fdd	„Zejejd
œdd„Z‡  ZS )Ú	Attentionz§Multi-headed Self Attention module.

    Source modified from:
    https://github.com/rwightman/pytorch-image-models/blob/master/timm/models/vision_transformer.py
    Ú
fused_attné    Fç        N)ÚdimÚhead_dimÚqkv_biasÚ	attn_dropÚ	proj_dropr&   c                    s€   t ƒ  ¡  || dkstdƒ‚|| _|| | _|d | _tƒ | _tj	||d |d�| _
t |¡| _t 	||¡| _t |¡| _dS )a}  Build MHSA module that can handle 3D or 4D input tensors.

        Args:
            dim: Number of embedding dimensions.
            head_dim: Number of hidden dimensions per head. Default: ``32``
            qkv_bias: Use bias or not. Default: ``False``
            attn_drop: Dropout rate for attention tensor.
            proj_drop: Dropout rate for projection tensor.
        r   z#dim should be divisible by head_dimg      à¿rƒ   )r)   N)r2   r3   r   r‹   Ú	num_headsÚscaler   r‡   r4   ÚLinearÚqkvÚDropoutr�   ÚprojrŽ   )r0   rŠ   r‹   rŒ   r�   rŽ   r>   r   r   r3   Ú  s    


zAttention.__init__r@   c                 C   s  |j \}}}}|| }| d¡ dd¡}|  |¡ ||d| j| j¡ ddddd¡}| d¡\}}	}
| j	rŽt
jjj||	|
| jr„| jjndd	�}n8|| j }||	 dd¡ }|jdd
�}|  |¡}||
 }| dd¡ |||¡}|  |¡}|  |¡}| dd¡ ||||¡}|S )NrQ   éþÿÿÿr[   rƒ   r   r   r|   r‰   )Z	dropout_p©rŠ   )ÚshapeÚflattenZ	transposer’   rd   r�   r‹   ZpermuteZunbindr‡   rS   r4   rT   Zscaled_dot_product_attentionZtrainingr�   Úpr�   Zsoftmaxr”   rŽ   )r0   rA   ÚBÚCÚHÚWÚNr’   ÚqÚkÚvZattnr   r   r   rD   ÷  sF    
    ÿ    þÿ  þ



zAttention.forward)rˆ   Fr‰   r‰   )rl   rm   rn   ro   rS   ÚjitÚFinalrr   Ú__annotations__rq   Úfloatr3   rt   rD   rv   r   r   r>   r   r†   Ò  s   
    úùr†   c                
       sT   e Zd ZdZejddfeeeeejeeddœ‡ fdd„Z	e
je
jdœdd	„Z‡  ZS )
Ú
PatchEmbedz$Convolutional patch embedding layer.FN)Ú
patch_sizer   r   Ú	embed_dimr%   Úlkc_use_actr    r&   c                    sH   t ƒ  ¡  t t||||dd||r&|ndd�t||dd||d�¡| _dS )a{  Build patch embedding layer.

        Args:
            patch_size: Patch size for embedding computation.
            stride: Stride for convolutional embedding layer.
            in_chs: Number of channels of input tensor.
            embed_dim: Number of embedding dimensions.
            inference_mode: Flag to instantiate model in inference mode. Default: ``False``
        r   rƒ   N)r   r   r   r   r   rx   r    r%   r„   )r2   r3   r4   ru   rw   r   r”   )r0   r§   r   r   r¨   r%   r©   r    r>   r   r   r3     s*    

ø
úõzPatchEmbed.__init__r@   c                 C   s   |   |¡}|S r{   )r”   ©r0   rA   r   r   r   rD   B  s    
zPatchEmbed.forward)rl   rm   rn   ro   r4   rp   rq   rs   rr   r3   rS   rt   rD   rv   r   r   r>   r   r¦     s   ø÷)r¦   c                       s&   e Zd Zd‡ fdd„	Zdd„ Z‡  ZS )ÚLayerScale2dçñhãˆµøä>Fc                    s.   t ƒ  ¡  || _t |t |dd¡ ¡| _d S )Nr   )r2   r3   Úinplacer4   Ú	ParameterrS   Zonesre   )r0   rŠ   Zinit_valuesr­   r>   r   r   r3   H  s    
zLayerScale2d.__init__c                 C   s   | j r| | j¡S || j S r{   )r­   Zmul_re   rª   r   r   r   rD   M  s    zLayerScale2d.forward)r¬   F)rl   rm   rn   r3   rD   rv   r   r   r>   r   r«   G  s   r«   c                       sJ   e Zd ZdZdedœ‡ fdd„Zejejdœd	d
„Zddœdd„Z	‡  Z
S )ÚRepMixerzÑReparameterizable token mixer.

    For more details, please refer to our paper:
    `FastViT: A Fast Hybrid Vision Transformer using Structural Reparameterization <https://arxiv.org/pdf/2303.14189.pdf>`_
    rƒ   r¬   F©r    c              	      sž   t ƒ  ¡  || _|| _|| _|rJtj| j| j| jd| jd | jdd�| _nPd| _t|||ddddd�| _	t|||ddd	�| _
|dk	r’t||ƒ| _ntj| _dS )
a˜  Build RepMixer Module.

        Args:
            dim: Input feature map dimension. :math:`C_{in}` from an expected input of size :math:`(B, C_{in}, H, W)`.
            kernel_size: Kernel size for spatial mixing. Default: 3
            layer_scale_init_value: Initial value for layer scale. Default: 1e-5
            inference_mode: If True, instantiates model in inference mode. Default: ``False``
        r   rQ   T©r   r   Úpaddingr(   r)   NFr   )r   r"   r#   r$   )r   r"   )r2   r3   rŠ   r   r    r4   ÚConv2dr7   r   ÚnormÚmixerr«   Úlayer_scaler5   )r0   rŠ   r   Úlayer_scale_init_valuer    r>   r   r   r3   X  sD    
ù

ù	ûzRepMixer.__init__r@   c                 C   s8   | j d k	r|   |¡}n||  |  |¡|  |¡ ¡ }|S r{   )r7   r¶   rµ   r´   rª   r   r   r   rD   �  s    
zRepMixer.forwardNrP   c                 C   s   | j r
dS | j ¡  | j ¡  t| jtƒrx| jj| jj 	d¡| jj
j| jj
j   }t | jj¡| jj
j| jj
j  }n0| jj| jj
j | jj
j }| jj
j| jj
j }t| j| j| jd| jdd�| _
|| j
j_|| j
j_|  ¡ D ]\}}d|krôqâ| ¡  qâ|  d¡ |  d¡ |  d	¡ dS )
ziReparameterize mixer and norm into a single
        convolutional layer for efficient inference.
        Nr[   r   Tr�   r7   rµ   r´   r¶   )r    rµ   rO   r´   r\   r¶   r«   rW   re   Z	unsqueezer7   rF   rS   Zsqueezer)   r   rŠ   r   rG   rH   rI   rJ   )r0   ÚwÚbrM   rN   r   r   r   rO   ”  sF    

ÿÿÿþÿú




zRepMixer.reparameterize)rƒ   r¬   F)rl   rm   rn   ro   rr   r3   rS   rt   rD   rO   rv   r   r   r>   r   r¯   Q  s   	   ûû5r¯   c                       sl   e Zd ZdZddejdfeee ee eje	ddœ‡ fdd„Z
ejddœdd	„Zejejd
œdd„Z‡  ZS )ÚConvMlpzConvolutional FFN Module.Nr‰   )r   Úhidden_channelsr   r%   Údropr&   c                    sv   t ƒ  ¡  |p|}|p|}t||d|dd�| _tj||dd�| _|ƒ | _tj||dd�| _t 	|¡| _
|  | j¡ dS )a_  Build convolutional FFN module.

        Args:
            in_chs: Number of input channels.
            hidden_channels: Number of channels after expansion. Default: None
            out_chs: Number of output channels. Default: None
            act_layer: Activation layer. Default: ``GELU``
            drop: Dropout rate. Default: ``0.0``.
        é   F)r   r(   r,   r   )r   N)r2   r3   r   r]   r4   r³   Úfc1r=   Úfc2r“   r¼   ÚapplyÚ_init_weights)r0   r   r»   r   r%   r¼   r>   r   r   r3   Ä  s    
ûzConvMlp.__init__©Úmr&   c                 C   s8   t |tjƒr4t|jdd� |jd k	r4tj |jd¡ d S )Nç{®Gáz”?©rj   r   )r\   r4   r³   r
   rF   r)   ÚinitÚ	constant_©r0   rÃ   r   r   r   rÁ   å  s    
zConvMlp._init_weightsr@   c                 C   s@   |   |¡}|  |¡}|  |¡}|  |¡}|  |¡}|  |¡}|S r{   )r]   r¾   r=   r¼   r¿   rª   r   r   r   rD   ë  s    





zConvMlp.forward)rl   rm   rn   ro   r4   rp   rq   r   rs   r¥   r3   rÁ   rS   rt   rD   rv   r   r   r>   r   rº   Á  s   úù!rº   c                       sd   e Zd ZdZdeee eeeeef f ddœ‡ fdd„Ze	j
e	j
dœd	d
„Zddœdd„Z‡  ZS )ÚRepConditionalPosEnca"  Implementation of conditional positional encoding.

    For more details refer to paper:
    `Conditional Positional Encodings for Vision Transformers <https://arxiv.org/pdf/2102.10882.pdf>`_

    In our implementation, we can reparameterize this module to eliminate a skip connection.
    N©r½   r½   F)rŠ   Údim_outÚspatial_shaper&   c              	      sæ   t t| ƒ ¡  t|tƒr&t|gd ƒ}t|tƒsDtdt|ƒ› d�ƒ‚t	|ƒdksdtdt	|ƒ› d�ƒ‚|| _
|| _|pv|| _|| _|r°tj| j| j| j
d|d d | jdd�| _n2d	| _tj| j| j|dt|d d ƒ| jdd
�| _d	S )at  Build reparameterizable conditional positional encoding

        Args:
            dim: Number of input channels.
            dim_out: Number of embedding dimensions. Default: 768
            spatial_shape: Spatial shape of kernel for positional encoding. Default: (7, 7)
            inference_mode: Flag to instantiate block in inference mode. Default: ``False``
        rQ   z/"spatial_shape" must by a sequence or int, get z	 instead.z+Length of "spatial_shape" should be 2, got r   r   Tr±   N)r(   r)   )r2   rÉ   r3   r\   rq   Útupler   r   ÚtypeÚlenrÌ   rŠ   rË   r(   r4   r³   r7   Úpos_enc)r0   rŠ   rË   rÌ   r    r>   r   r   r3   þ  sB    
ÿÿ

ù

ùzRepConditionalPosEnc.__init__r@   c                 C   s(   | j d k	r|   |¡}n|  |¡| }|S r{   )r7   rÐ   rª   r   r   r   rD   4  s    
zRepConditionalPosEnc.forwardrP   c           	   	   C   s  | j | j }tj| j || jd | jd f| jjj| jjjd�}t	| j ƒD ],}d|||| | jd d | jd d f< qH|}|| jj }| jj
}tj| j | j| jdt| jd d ƒ| jdd�| _|| jj_|| jj
_|  ¡ D ]\}}d|krìqÚ| ¡  qÚ|  d¡ d S )	Nr   r   rX   rQ   Tr±   r7   rÐ   )rŠ   r(   rS   rb   rÌ   rÐ   rF   rY   rZ   r:   r)   r4   r³   rË   rq   r7   rG   rH   rI   rJ   )	r0   rg   rh   ri   rW   Zw_finalZb_finalrM   rN   r   r   r   rO   ;  sL    üø
ûýÿù	


z#RepConditionalPosEnc.reparameterize)NrÊ   F)rl   rm   rn   ro   rq   r   r   r   r3   rS   rt   rD   rO   rv   r   r   r>   r   rÉ   õ  s      ûú6rÉ   c                
       sP   e Zd ZdZddejddddfeeeejeeee	dœ‡ fdd	„Z
d
d„ Z‡  ZS )ÚRepMixerBlockzãImplementation of Metaformer block with RepMixer as token mixer.

    For more details on Metaformer structure, please refer to:
    `MetaFormer Is Actually What You Need for Vision <https://arxiv.org/pdf/2111.11418.pdf>`_
    rƒ   ç      @r‰   r¬   F)rŠ   r   Ú	mlp_ratior%   rŽ   Ú	drop_pathr·   r    c	           	         st   t ƒ  ¡  t||||d�| _t|t|| ƒ||d�| _|dk	rLt||ƒ| _n
t	 
¡ | _|dkrft|ƒnt	 
¡ | _dS )a,  Build RepMixer Block.

        Args:
            dim: Number of embedding dimensions.
            kernel_size: Kernel size for repmixer. Default: 3
            mlp_ratio: MLP expansion ratio. Default: 4.0
            act_layer: Activation layer. Default: ``nn.GELU``
            proj_drop: Dropout rate. Default: 0.0
            drop_path: Drop path rate. Default: 0.0
            layer_scale_init_value: Layer scale value at initialization. Default: 1e-5
            inference_mode: Flag to instantiate block in inference mode. Default: ``False``
        )r   r·   r    ©r   r»   r%   r¼   Nr‰   )r2   r3   r¯   Útoken_mixerrº   rq   Úmlpr«   r¶   r4   r5   r	   rÔ   )	r0   rŠ   r   rÓ   r%   rŽ   rÔ   r·   r    r>   r   r   r3   p  s"    
ü
ü
zRepMixerBlock.__init__c                 C   s(   |   |¡}||  |  |  |¡¡¡ }|S r{   )rÖ   rÔ   r¶   r×   rª   r   r   r   rD   �  s    
zRepMixerBlock.forward)rl   rm   rn   ro   r4   rp   rq   r¥   rs   rr   r3   rD   rv   r   r   r>   r   rÑ   i  s&   	÷÷-rÑ   c                	       sP   e Zd ZdZdejejdddfeeej	ej	eeedœ‡ fdd„Z
dd	„ Z‡  ZS )
ÚAttentionBlockzßImplementation of metaformer block with MHSA as token mixer.

    For more details on Metaformer structure, please refer to:
    `MetaFormer Is Actually What You Need for Vision <https://arxiv.org/pdf/2111.11418.pdf>`_
    rÒ   r‰   r¬   )rŠ   rÓ   r%   Ú
norm_layerrŽ   rÔ   r·   c                    s²   t ƒ  ¡  ||ƒ| _t|d�| _|dk	r6t||ƒ| _n
t ¡ | _|dkrPt	|ƒnt ¡ | _
t|t|| ƒ||d�| _|dk	rŠt||ƒ| _n
t ¡ | _|dkr¤t	|ƒnt ¡ | _dS )aÜ  Build Attention Block.

        Args:
            dim: Number of embedding dimensions.
            mlp_ratio: MLP expansion ratio. Default: 4.0
            act_layer: Activation layer. Default: ``nn.GELU``
            norm_layer: Normalization layer. Default: ``nn.BatchNorm2d``
            proj_drop: Dropout rate. Default: 0.0
            drop_path: Drop path rate. Default: 0.0
            layer_scale_init_value: Layer scale value at initialization. Default: 1e-5
        r–   Nr‰   rÕ   )r2   r3   r´   r†   rÖ   r«   Úlayer_scale_1r4   r5   r	   Ú
drop_path1rº   rq   r×   Úlayer_scale_2Ú
drop_path2)r0   rŠ   rÓ   r%   rÙ   rŽ   rÔ   r·   r>   r   r   r3   ª  s"    



ü
zAttentionBlock.__init__c              
   C   s>   ||   |  |  |  |¡¡¡¡ }||  |  |  |¡¡¡ }|S r{   )rÛ   rÚ   rÖ   r´   rÝ   rÜ   r×   rª   r   r   r   rD   Ö  s     zAttentionBlock.forward)rl   rm   rn   ro   r4   rp   r8   rq   r¥   rs   r3   rD   rv   r   r   r>   r   rØ   £  s"   	øø,rØ   c                       st   e Zd Zddddddejejdddd	d	feeeeeeee	ej
 eeej
ej
eee	e d
œ‡ fdd„Zdd„ Z‡  ZS )ÚFastVitStageTr½   rQ   Nrƒ   rÒ   r‰   r¬   F)rŠ   rË   ÚdepthÚtoken_mixer_typeÚ
downsampleÚdown_patch_sizeÚdown_strideÚpos_emb_layerr   rÓ   r%   rÙ   Úproj_drop_rateÚdrop_path_rater·   c                    sì   t ƒ  ¡  d| _|r.t|||||||d�| _n||ks:t‚t ¡ | _|dk	r\|||d�| _n
t ¡ | _g }t	|ƒD ]h}|dkr¢| 
t||	|
|||| ||d�¡ qr|dkrÌ| 
t||
||||| |d�¡ qrtd	 |¡ƒ‚qrtj|Ž | _dS )
aQ  FastViT stage.

        Args:
            dim: Number of embedding dimensions.
            depth: Number of blocks in stage
            token_mixer_type: Token mixer type.
            kernel_size: Kernel size for repmixer.
            mlp_ratio: MLP expansion ratio.
            act_layer: Activation layer.
            norm_layer: Normalization layer.
            proj_drop_rate: Dropout rate.
            drop_path_rate: Drop path rate.
            layer_scale_init_value: Layer scale value at initialization.
            inference_mode: Flag to instantiate block in inference mode.
        F)r§   r   r   r¨   r%   r©   r    Nr°   Úrepmixer)r   rÓ   r%   rŽ   rÔ   r·   r    Ú	attention)rÓ   r%   rÙ   rŽ   rÔ   r·   z"Token mixer type: {} not supported)r2   r3   Úgrad_checkpointingr¦   rá   r   r4   r5   Úpos_embr:   ÚappendrÑ   rØ   Ú
ValueErrorÚformatru   Úblocks)r0   rŠ   rË   rß   rà   rá   râ   rã   rä   r   rÓ   r%   rÙ   rå   ræ   r·   r©   r    rî   Z	block_idxr>   r   r   r3   Ý  sX    #
ù



ø

ù

ÿzFastVitStage.__init__c                 C   s@   |   |¡}|  |¡}| jr2tj ¡ s2t| j|ƒ}n
|  |¡}|S r{   )rá   rê   ré   rS   r¢   Zis_scriptingr   rî   rª   r   r   r   rD   3  s    


zFastVitStage.forward)rl   rm   rn   r4   rp   r8   rq   Ústrrr   r   rs   r¥   r3   rD   rv   r   r   r>   r   rÞ   Ü  s>   îðVrÞ   c                       sh  e Zd ZU ejje ed< ddddddddd	d
ddddddddej	ej
ddfeeedf eedf eedf eedf eedf eeeeej df eeeeeeeeeejejeeddœ‡ fdd„Zejddœdd„Zejjdd„ ƒZejjd,dd„ƒZejjd-dd„ƒZejjd d!„ ƒZd.d"d#„Zejejd$œd%d&„Zd/ejed'œd(d)„Zejejd$œd*d+„Z‡  ZS )0ÚFastVitÚ	fork_featrƒ   ©rQ   rQ   é   rQ   ©rç   rç   rç   rç   ©é@   é€   é   i   ©r|   r|   r|   r|   )FTTTéè  )NNNNr½   rQ   r‰   r¬   Fg       @Úavg.N)Úin_chansÚlayersÚtoken_mixersÚ
embed_dimsÚ
mlp_ratiosÚdownsamplesÚrepmixer_kernel_sizeÚnum_classesÚpos_embsrâ   rã   Ú	drop_raterå   ræ   r·   rñ   Ú	cls_ratioÚglobal_poolrÙ   r%   r©   r    r&   c           #         sø  t ƒ  ¡  |rdn|| _|| _|| _g | _t||d ||ƒ| _|d }d}dd„ t 	d|t
|ƒ¡ |¡D ƒ}g }tt|ƒƒD ]œ}|| p’||| k}t||| || ||
||	| || ||| ||||| |||d�}| |¡ || }|rô|d9 }|  jt|d| d|› �d	�g7  _q|tj|Ž | _|| _| j�r dddd
g| _t| jƒD ]P\}}|dk�rxtj dd ¡�rxt ¡ } n||| ƒ} d|› �}!|  |!| ¡ �qLnHt|d | ƒ | _}"t|d |"d
dd|d|dd�	| _t|"|||d�| _ |  !| j"¡ d S )Nr   r   c                 S   s   g | ]}|  ¡ ‘qS r   )Útolist)r-   rA   r   r   r   r1   n  s     z$FastVit.__init__.<locals>.<listcomp>)rŠ   rË   rß   rá   râ   rã   rä   rà   r   rÓ   r%   rÙ   rå   ræ   r·   r©   r    rQ   r|   zstages.)Znum_chsZ	reductionÚmodulerƒ   Z
FORK_LAST3r´   r[   T)	r   r   r   r   r   r    r!   r%   r$   )Z	pool_typer  )#r2   r3   r  rñ   r  Zfeature_infor…   ÚstemrS   ZlinspaceÚsumÚsplitr:   rÏ   rÞ   rë   Údictr4   ru   Ústagesr*   Úout_indicesÚ	enumerateÚosÚenvironÚgetr5   Z
add_modulerq   r   Ú
final_convr   ÚheadrÀ   rÁ   )#r0   rü   rý   rþ   rÿ   r   r  r  r  r  râ   rã   r  rå   ræ   r·   rñ   r  r  rÙ   r%   r©   r    Zprev_dimr�   Zdprr  ri   rá   ZstageZi_embZi_layerÚlayerZ
layer_nameZfinal_featuresr>   r   r   r3   D  sŒ    
ü"ï
&

÷üzFastVit.__init__rÂ   c                 C   sD   t |tjƒr@t|jdd� t |tjƒr@|jdk	r@tj |jd¡ dS )zInit. for classificationrÄ   rÅ   Nr   )r\   r4   r‘   r
   rF   r)   rÆ   rÇ   rÈ   r   r   r   rÁ   ´  s    zFastVit._init_weightsc                 C   s   t ƒ S r{   )Úset©r0   r   r   r   Úno_weight_decay»  s    zFastVit.no_weight_decayc                 C   s   t d|rdndddgd�S )Nz^stemz^stages\.(\d+))z^stages\.(\d+).downsample©r   )z^stages\.(\d+).pos_embr  )z^stages\.(\d+)\.\w+\.(\d+)N)r
  rî   )r  )r0   Zcoarser   r   r   Úgroup_matcher¿  s    ýþzFastVit.group_matcherTc                 C   s   | j D ]
}||_qd S r{   )r  ré   )r0   ÚenableÚsr   r   r   Úset_grad_checkpointingÊ  s    
zFastVit.set_grad_checkpointingc                 C   s   | j jS r{   )r  Úfcr  r   r   r   Úget_classifierÏ  s    zFastVit.get_classifierc                 C   s   || _ | j ||¡ d S r{   )r  r  Úreset)r0   r  r  r   r   r   Úreset_classifierÓ  s    zFastVit.reset_classifierr@   c                 C   st   |   |¡}g }t| jƒD ]B\}}||ƒ}| jr|| jkrt| d|› �ƒ}||ƒ}| |¡ q| jrf|S |  |¡}|S )Nr´   )r
  r  r  rñ   r  Úgetattrrë   r  )r0   rA   ZoutsÚidxÚblockrÙ   Zx_outr   r   r   Úforward_features×  s    


zFastVit.forward_features)rA   Ú
pre_logitsc                 C   s   |r| j |dd�S |   |¡S )NT)r'  )r  )r0   rA   r'  r   r   r   Úforward_headè  s    zFastVit.forward_headc                 C   s"   |   |¡}| jr|S |  |¡}|S r{   )r&  rñ   r(  rª   r   r   r   rD   ë  s
    

zFastVit.forward)F)T)N)F)rl   rm   rn   rS   r¢   r£   rr   r¤   r4   r8   rp   rq   r   rï   r¥   r   rs   r3   rÁ   Úignorer  r  r  r   r"  rt   r&  r(  rD   rv   r   r   r>   r   rð   =  sz   
é




èp



rð   Ú c                 K   s   | dddddt tdddœ
|–S )	Nrú   )rƒ   rø   rø   )é   r+  gÍÌÌÌÌÌì?Zbicubic)zstem.0.conv_kxk.0.convzstem.0.conv_scale.convzhead.fc)
Úurlr  Z
input_sizeZ	pool_sizeÚcrop_pctÚinterpolationZmeanrj   Z
first_convÚ
classifierr   )r,  Úkwargsr   r   r   Ú_cfgó  s    öõr1  ztimm/)Ú	hf_hub_idgffffffî?)r2  r-  )zfastvit_t8.apple_in1kzfastvit_t12.apple_in1kzfastvit_s12.apple_in1kzfastvit_sa12.apple_in1kzfastvit_sa24.apple_in1kzfastvit_sa36.apple_in1kzfastvit_ma36.apple_in1kzfastvit_t8.apple_dist_in1kzfastvit_t12.apple_dist_in1kzfastvit_s12.apple_dist_in1kzfastvit_sa12.apple_dist_in1kzfastvit_sa24.apple_dist_in1kzfastvit_sa36.apple_dist_in1kzfastvit_ma36.apple_dist_in1kc                 K   s0   |  dd¡}tt| |fdtd|d�i|—Ž}|S )Nr  )r   r   rQ   rƒ   Zfeature_cfgT)Zflatten_sequentialr  )Úpopr   rð   r  )ÚvariantÚ
pretrainedr0  r  Úmodelr   r   r   Ú_create_fastvit,  s    ý
üûr7  c                 K   s*   t ddddd�}tdd| it |f|Ž—ŽS )	z%Instantiate FastViT-T8 model variant.)rQ   rQ   r|   rQ   )é0   é`   éÀ   i€  ©rƒ   rƒ   rƒ   rƒ   rô   ©rý   rÿ   r   rþ   Ú
fastvit_t8r5  )r=  ©r  r7  ©r5  r0  Z
model_argsr   r   r   r=  8  s    ür=  c                 K   s*   t ddddd�}tdd| it |f|Ž—ŽS )	z&Instantiate FastViT-T12 model variant.rò   rõ   r;  rô   r<  Úfastvit_t12r5  )r@  r>  r?  r   r   r   r@  D  s    ür@  c                 K   s*   t ddddd�}tdd| it |f|Ž—ŽS )	z&Instantiate FastViT-S12 model variant.rò   rõ   rù   rô   r<  Úfastvit_s12r5  )rA  r>  r?  r   r   r   rA  P  s    ürA  c                 K   s<   t ddddddttdd�fdd�}tdd
| it |f|Ž—ŽS )z'Instantiate FastViT-SA12 model variant.rò   rõ   rù   NrÊ   ©rÌ   ©rç   rç   rç   rè   ©rý   rÿ   r   r  rþ   Úfastvit_sa12r5  )rE  ©r  r   rÉ   r7  r?  r   r   r   rE  \  s    ûrE  c                 K   s<   t ddddddttdd�fdd�}tdd
| it |f|Ž—ŽS )z'Instantiate FastViT-SA24 model variant.)r|   r|   é   r|   rõ   rù   NrÊ   rB  rC  rD  Úfastvit_sa24r5  )rH  rF  r?  r   r   r   rH  i  s    ûrH  c                 K   s<   t ddddddttdd�fdd�}tdd
| it |f|Ž—ŽS )z'Instantiate FastViT-SA36 model variant.©ró   ró   é   ró   rõ   rù   NrÊ   rB  rC  rD  Úfastvit_sa36r5  )rK  rF  r?  r   r   r   rK  v  s    ûrK  c                 K   s<   t ddddddttdd�fdd�}tdd
| it |f|Ž—ŽS )z'Instantiate FastViT-MA36 model variant.rI  )éL   é˜   i0  i`  rù   NrÊ   rB  rC  rD  Úfastvit_ma36r5  )rN  rF  r?  r   r   r   rN  ƒ  s    ûrN  )r*  )F)F)F)F)F)F)F)F)9r  Ú	functoolsr   Útypingr   r   r   rS   Ztorch.nnr4   Z	timm.datar   r   Ztimm.layersr	   r
   r   r   r   r   r   Z_builderr   Z_manipulater   Ú	_registryr   r   r   rs   r   rw   rp   rq   rr   ru   r…   r†   r¦   r«   r¯   rº   rÉ   rÑ   rØ   rÞ   rð   r1  Zdefault_cfgsr7  r=  r@  rA  rE  rH  rK  rN  r   r   r   r   Ú<module>   sÀ   $	 r üû-D1
p4t:9a 7
ÿÿÿÿÿÿþÿÿÿÿÿÿþÞ)
