o
    پiM                     @   sL  d Z ddlmZ ddlmZ ddlmZmZmZ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 dd	lmZ dd
lmZ ddlmZ ddlm Z m!Z! ddl"m#Z#m$Z$ dgZ%eeej&dZ'G dd dej(Z)						dQde*de*de+de+de*de+dee
e+e*e+e*f  fddZ,			 	!	dRd"ee
e+e*e+e*f  d#e+de*de+d$e+d%e-d&e-d'e*de
eej( eee-ef  f fd(d)Z.G d*d dej(Z/d+e-d,e0de/fd-d.Z1dSd0e-dee-ef fd1d2Z2e#e2d3d4e2d3d4e2d3d4e2d3d4e2d3d4e2 e2 e2 e2d3d5dd6d7d8e2d3d5dd6d7d8e2d3d9d5dd6d7d:e2d3d9d5dd6d7d:d;Z3e$dTd,e0de/fd=d>Z4e$dTd,e0de/fd?d@Z5e$dTd,e0de/fdAdBZ6e$dTd,e0de/fdCdDZ7e$dTd,e0de/fdEdFZ8e$dTd,e0de/fdGdHZ9e$dTd,e0de/fdIdJZ:e$dTd,e0de/fdKdLZ;e$dTd,e0de/fdMdNZ<e$dTd,e0de/fdOdPZ=dS )Ua   ReXNet

A PyTorch impl of `ReXNet: Diminishing Representational Bottleneck on Convolutional Neural Network` -
https://arxiv.org/abs/2007.00992

Adapted from original impl at https://github.com/clovaai/rexnet
Copyright (c) 2020-present NAVER Corp. MIT license

Changes for timm, feature extraction, and rounded channel variant hacked together by Ross Wightman
Copyright 2020 Ross Wightman
    )partialceil)AnyDictListOptionalTupleUnionNIMAGENET_DEFAULT_MEANIMAGENET_DEFAULT_STD)ClassifierHeadcreate_act_layerConvNormActDropPathmake_divisibleSEModule   )build_model_with_cfg)efficientnet_init_weights)feature_take_indices)
checkpointcheckpoint_seq)generate_default_cfgsregister_modelRexNet)
norm_layerc                       s   e Zd ZdZ							dd	ed
ededeeef dedededededee	j
 f fddZddedefddZdejdejfddZ  ZS )LinearBottleneckzLinear bottleneck block for ReXNet.

    A mobile inverted residual bottleneck block as used in MobileNetV2 and subsequent models.
    r   r         ?        r   swishrelu6Nin_chsout_chsstridedilation	exp_ratiose_ratioch_div	act_layerdw_act_layer	drop_pathc              	      s   t t|   |dko|d |d ko||k| _|| _|| _|dkr5tt|| |d}t|||d| _	n|}d| _	t||d||d |dd	| _
|dkr[t|tt|| |d
| _nd| _t|	| _t||ddd| _|
| _dS )a  Initialize LinearBottleneck.

        Args:
            in_chs: Number of input channels.
            out_chs: Number of output channels.
            stride: Stride for depthwise conv.
            dilation: Dilation rates.
            exp_ratio: Expansion ratio.
            se_ratio: Squeeze-excitation ratio.
            ch_div: Channel divisor.
            act_layer: Activation layer for expansion.
            dw_act_layer: Activation layer for depthwise.
            drop_path: Drop path module.
        r   r   r    divisorr+   N   F)kernel_sizer&   r'   groups	apply_act)rd_channels)r4   )superr   __init__use_shortcutin_channelsout_channelsr   roundr   conv_expconv_dw
SEWithNormintser   act_dwconv_pwlr-   )selfr$   r%   r&   r'   r(   r)   r*   r+   r,   r-   dw_chs	__class__ F/home/ubuntu/.local/lib/python3.10/site-packages/timm/models/rexnet.pyr7   (   s0   "	

zLinearBottleneck.__init__Fexpreturnc                 C   s   |r| j jS | jS )zGet feature channel count.

        Args:
            exp: Return expanded channels if True.

        Returns:
            Number of feature channels.
        )r=   r:   )rC   rI   rG   rG   rH   feat_channelsa   s   	zLinearBottleneck.feat_channelsxc                 C   s   |}| j dur|  |}| |}| jdur| |}| |}| |}| jrO| jdur2| |}tj|ddd| j	f | |dd| j	df gdd}|S )zoForward pass.

        Args:
            x: Input tensor.

        Returns:
            Output tensor.
        Nr   r   )dim)
r<   r=   r@   rA   rB   r8   r-   torchcatr9   )rC   rL   shortcutrG   rG   rH   forwardl   s   	








:zLinearBottleneck.forward)r   r    r!   r   r"   r#   NF)__name__
__module____qualname____doc__r?   r	   floatstrr   nnModuler7   boolrK   rN   TensorrQ   __classcell__rG   rG   rE   rH   r   "   s@    

	
9r   r          r!   
width_mult
depth_multinitial_chs	final_chsr)   r*   rJ   c                    s  g dg d} fddD t fddt|D g }dgd  dgt dd	   }t d	d	 d
 }| dk rC||  n|}	g }
t|d
 D ]}|
tt|	|  |d |	||d
 d  7 }	qMdgd d   |gt dd	   }tt|
|||S )as  Generate ReXNet block configuration.

    Args:
        width_mult: Width multiplier.
        depth_mult: Depth multiplier.
        initial_chs: Initial channel count.
        final_chs: Final channel count.
        se_ratio: Squeeze-excitation ratio.
        ch_div: Channel divisor.

    Returns:
        List of tuples (out_channels, exp_ratio, stride, se_ratio).
    )r      rd   r1   r1      )r   rd   rd   rd   r   rd   c                    s   g | ]}t |  qS rG   r   ).0element)ra   rG   rH   
<listcomp>   s    z_block_cfg.<locals>.<listcomp>c                    s(   g | ]\}}|gd g | d    qS )r   rG   )rf   idxrg   )layersrG   rH   rh      s   ( r   r      Nr1   r    r.   r!   rd   )sum	enumeraterangeappendr   r;   listzip)r`   ra   rb   rc   r)   r*   strides
exp_ratiosdepthbase_chsout_chs_listi	se_ratiosrG   )ra   rj   rH   
_block_cfg   s   $,ry       r"   r#   	block_cfgprev_chsoutput_strider+   r,   drop_path_ratec                 C   sH  |g}g }	d}
d}g }t | }t| D ]g\}\}}}}|}|dkrD|dkr'dnd|d  }|	t|d |
|dg7 }	|
|krD|| }d}|| |d  }|dkrTt|nd	}|t||||||f|||||d

 |
|9 }
|}|}||d  g7 }qtd| |d}|	t|d |
dt |d  dg7 }	|t|||d ||	fS )a  Build ReXNet blocks from configuration.

    Args:
        block_cfg: Block configuration list.
        prev_chs: Previous channel count.
        width_mult: Width multiplier.
        ch_div: Channel divisor.
        output_stride: Target output stride.
        act_layer: Activation layer name.
        dw_act_layer: Depthwise activation layer name.
        drop_path_rate: Drop path rate.

    Returns:
        Tuple of (features list, feature_info list).
    rd   r   r   stemz	features.)num_chs	reductionmoduler!   N)
r$   r%   r(   r&   r'   r)   r*   r+   r,   r-   i   r.   r0   )	lenrm   dictr   ro   r   rK   r   r   )r{   r|   r`   r*   r}   r+   r,   r~   feat_chsfeature_infocurr_strider'   features
num_blocks	block_idxchsr(   r&   r)   next_dilationfname	block_dprr-   pen_chsrG   rG   rH   _build_blocks   sH   &r   c                       s  e Zd ZdZ											
				dAdedededededededededededededef fddZej	j
dBd ed!eeef fd"d#Zej	j
dCd%ed!d&fd'd(Zej	j
d!ejfd)d*ZdDdedee d!d&fd+d,Z	&			-	dEd.ejd/eeeee f  d0ed1ed2ed3ed!eeej eejeej f f fd4d5Z	
		$dFd/eeee f d6ed7ed!ee fd8d9Zd.ejd!ejfd:d;ZdBd.ejd<ed!ejfd=d>Zd.ejd!ejfd?d@Z  ZS )Gr   zReXNet model architecture.

    Based on `ReXNet: Diminishing Representational Bottleneck on Convolutional Neural Network`
    - https://arxiv.org/abs/2007.00992
    r1     avgrz   r^   r_   r    UUUUUU?r   r"   r#   皙?r!   in_chansnum_classesglobal_poolr}   rb   rc   r`   ra   r)   r*   r+   r,   	drop_rater~   c              	      s   t t|   || _|| _d| _|dv sJ |dk rd| nd}tt|| |
d}t||dd|d| _	t
|||||	|
}t||||
||||\}| _|d	 j | _| _tj| | _t| j|||| _t|  d
S )a  Initialize ReXNet.

        Args:
            in_chans: Number of input channels.
            num_classes: Number of classes for classification.
            global_pool: Global pooling type.
            output_stride: Output stride.
            initial_chs: Initial channel count.
            final_chs: Final channel count.
            width_mult: Width multiplier.
            depth_mult: Depth multiplier.
            se_ratio: Squeeze-excitation ratio.
            ch_div: Channel divisor.
            act_layer: Activation layer name.
            dw_act_layer: Depthwise activation layer name.
            drop_rate: Dropout rate.
            drop_path_rate: Drop path rate.
        F)rz   r^      r    rz   r.   r1   rd   )r&   r+   r   N)r6   r   r7   r   r   grad_checkpointingr   r;   r   r   ry   r   r   r:   num_featureshead_hidden_sizerY   
Sequentialr   r   headr   )rC   r   r   r   r}   rb   rc   r`   ra   r)   r*   r+   r,   r   r~   stem_base_chsstem_chsr{   r   rE   rG   rH   r7      s.   #

zRexNet.__init__FcoarserJ   c                 C   s   t ddd}|S )zGroup matcher for parameter groups.

        Args:
            coarse: Whether to use coarse grouping.

        Returns:
            Dictionary of grouped parameters.
        z^stemz^features\.(\d+))r   blocks)r   )rC   r   matcherrG   rG   rH   group_matcher1  s
   
zRexNet.group_matcherTenableNc                 C   s
   || _ dS )zEnable or disable gradient checkpointing.

        Args:
            enable: Whether to enable gradient checkpointing.
        N)r   )rC   r   rG   rG   rH   set_grad_checkpointingA  s   
zRexNet.set_grad_checkpointingc                 C   s   | j jS )zTGet the classifier module.

        Returns:
            Classifier module.
        )r   fc)rC   rG   rG   rH   get_classifierJ  s   zRexNet.get_classifierc                 C   s   || _ | j|| dS )zReset the classifier.

        Args:
            num_classes: Number of classes for new classifier.
            global_pool: Global pooling type.
        N)r   r   reset)rC   r   r   rG   rG   rH   reset_classifierS  s   zRexNet.reset_classifierNCHWrL   indicesnorm
stop_early
output_fmtintermediates_onlyc                    s   |dv sJ dg }dd | j D  tt |\}}	 fdd|D } |	 }	| |}tj s4|s8| j}
n	| jd|	d  }
t|
D ]\}}| j	rWtj sWt
||}n||}||v rd|| qE|ri|S ||fS )a   Forward features that returns intermediates.

        Args:
            x: Input image tensor
            indices: Take last n blocks if int, all if None, select matching indices if sequence
            norm: Apply norm layer to compatible intermediates
            stop_early: Stop iterating over blocks when last desired intermediate hit
            output_fmt: Shape of intermediate feature outputs
            intermediates_only: Only return intermediate features
        Returns:

        )r   zOutput shape must be NCHW.c                 S   "   g | ]}t |d  dd qS r   .r   r?   splitrf   inforG   rG   rH   rh   t     " z0RexNet.forward_intermediates.<locals>.<listcomp>c                    s   g | ]} | qS rG   rG   )rf   rw   
stage_endsrG   rH   rh   v  s    Nr   )r   r   r   r   rN   jitis_scriptingr   rm   r   r   ro   )rC   rL   r   r   r   r   r   intermediatestake_indices	max_indexstagesfeat_idxstagerG   r   rH   forward_intermediates]  s(   

zRexNet.forward_intermediates
prune_norm
prune_headc                 C   sR   dd | j D }tt||\}}|| }| jd|d  | _|r'| dd |S )aE  Prune layers not required for specified intermediates.

        Args:
            indices: Indices of intermediate layers to keep.
            prune_norm: Whether to prune normalization layer.
            prune_head: Whether to prune the classifier head.

        Returns:
            List of indices that were kept.
        c                 S   r   r   r   r   rG   rG   rH   rh     r   z4RexNet.prune_intermediate_layers.<locals>.<listcomp>Nr   r    )r   r   r   r   r   )rC   r   r   r   r   r   r   rG   rG   rH   prune_intermediate_layers  s   z RexNet.prune_intermediate_layersc                 C   s8   |  |}| jrtj st| j|}|S | |}|S )zForward pass through feature extraction layers.

        Args:
            x: Input tensor.

        Returns:
            Feature tensor.
        )r   r   rN   r   r   r   r   rC   rL   rG   rG   rH   forward_features  s   
	
zRexNet.forward_features
pre_logitsc                 C   s   |r	| j ||dS |  |S )zForward pass through head.

        Args:
            x: Input features.
            pre_logits: Return features before final linear layer.

        Returns:
            Classification logits or features.
        )r   )r   )rC   rL   r   rG   rG   rH   forward_head  s   
zRexNet.forward_headc                 C   s   |  |}| |}|S )zoForward pass.

        Args:
            x: Input tensor.

        Returns:
            Output logits.
        )r   r   r   rG   rG   rH   rQ     s   
	
zRexNet.forward)r1   r   r   rz   r^   r_   r    r    r   r   r"   r#   r   r!   rR   )T)N)NFFr   F)r   FT)rS   rT   rU   rV   r?   rX   rW   r7   rN   r   ignorer[   r   r   r   r   rY   rZ   r   r   r   r\   r
   r   r	   r   r   r   r   rQ   r]   rG   rG   rE   rH   r      s    	
? 
2
variant
pretrainedc                 K   s"   t dd}tt| |fd|i|S )zCreate a ReXNet model.

    Args:
        variant: Model variant name.
        pretrained: Load pretrained weights.
        **kwargs: Additional model arguments.

    Returns:
        ReXNet model instance.
    T)flatten_sequentialfeature_cfg)r   r   r   )r   r   kwargsr   rG   rG   rH   _create_rexnet  s   
r   r   urlc                 K   s    | dddddt tdddd	|S )
zCreate default configuration dictionary.

    Args:
        url: Model weight URL.
        **kwargs: Additional configuration options.

    Returns:
        Configuration dictionary.
    r   )r1      r   )   r   g      ?bicubicz	stem.convzhead.fcmit)r   r   
input_size	pool_sizecrop_pctinterpolationmeanstd
first_conv
classifierlicenser   )r   r   rG   rG   rH   _cfg  s   r   ztimm/)	hf_hub_idgffffff?)r1      r   z
apache-2.0)r   r   test_crop_pcttest_input_sizer   i-.  )r   r   r   r   r   r   )zrexnet_100.nav_in1kzrexnet_130.nav_in1kzrexnet_150.nav_in1kzrexnet_200.nav_in1kzrexnet_300.nav_in1kzrexnetr_100.untrainedzrexnetr_130.untrainedzrexnetr_150.untrainedzrexnetr_200.sw_in12k_ft_in1kzrexnetr_300.sw_in12k_ft_in1kzrexnetr_200.sw_in12kzrexnetr_300.sw_in12kFc                 K   s   t d| fi |S )zReXNet V1 1.0x
rexnet_100r   r   r   rG   rG   rH   r     s   r   c                 K      t d| fddi|S )zReXNet V1 1.3x
rexnet_130r`   ?r   r   rG   rG   rH   r        r   c                 K   r   )zReXNet V1 1.5x
rexnet_150r`         ?r   r   rG   rG   rH   r     r   r   c                 K   r   )zReXNet V1 2.0x
rexnet_200r`          @r   r   rG   rG   rH   r   #  r   r   c                 K   r   )zReXNet V1 3.0x
rexnet_300r`         @r   r   rG   rG   rH   r   )  r   r   c                 K   r   )z*ReXNet V1 1.0x w/ rounded (mod 8) channelsrexnetr_100r*   r   r   r   rG   rG   rH   r   /  r   r   c                 K      t d| fddd|S )z*ReXNet V1 1.3x w/ rounded (mod 8) channelsrexnetr_130r   r   r`   r*   r   r   rG   rG   rH   r   5     r   c                 K   r   )z*ReXNet V1 1.5x w/ rounded (mod 8) channelsrexnetr_150r   r   r   r   r   rG   rG   rH   r   ;  r   r   c                 K   r   )z*ReXNet V1 2.0x w/ rounded (mod 8) channelsrexnetr_200r   r   r   r   r   rG   rG   rH   r   A  r   r   c                 K   r   )z+ReXNet V1 3.0x w/ rounded (mod 16) channelsrexnetr_300r   r^   r   r   r   rG   rG   rH   r   G  r   r   )r    r    r^   r_   r!   r   )r   rz   r"   r#   r!   )r   rR   )>rV   	functoolsr   mathr   typingr   r   r   r   r	   r
   rN   torch.nnrY   	timm.datar   r   timm.layersr   r   r   r   r   r   _builderr   _efficientnet_builderr   	_featuresr   _manipulater   r   	_registryr   r   __all__BatchNorm2dr>   rZ   r   rW   r?   ry   rX   r   r   r[   r   r   default_cfgsr   r   r   r   r   r   r   r   r   r   rG   rG   rG   rH   <module>   s      c
,	
? e