o
    پiOK                     @   s&  d Z ddlZddlmZ ddlmZmZmZmZ ddl	Z	ddl
mZ ddlm  mZ ddlmZmZ ddlmZmZmZ ddlmZ dd	lmZmZ dd
lmZ ddlmZ ddlm Z m!Z! dgZ"eedee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'd6de	jj$fddZ(d7ddZ)d8d d!Z*e!e*d"d#e*d"d#e*d"d#e*d"d#e*d"d#e*d"d#e*d"d#e*d"d#d$Z+e d9d%e'fd&d'Z,e d9d%e'fd(d)Z-e d9d%e'fd*d+Z.e d9d%e'fd,d-Z/e d9d%e'fd.d/Z0e d9d%e'fd0d1Z1e d9d%e'fd2d3Z2e d9d%e'fd4d5Z3dS ):z
An implementation of RepGhostNet Model as defined in:
RepGhost: A Hardware-Efficient Ghost Module via Re-parameterization. https://arxiv.org/abs/2211.06088

Original implementation: https://github.com/ChengpengChen/RepGhost
    N)partial)ListOptionalTupleUnionIMAGENET_DEFAULT_MEANIMAGENET_DEFAULT_STD)SelectAdaptivePool2dLinearmake_divisible   )build_model_with_cfg)SqueezeExcite	ConvBnAct)feature_take_indices)checkpoint_seq)register_modelgenerate_default_cfgsRepGhostNethard_sigmoid   )divisor)
gate_layerrd_round_fnc                       sb   e Zd Z					d fdd	Zdd Zdd	 Zed
d ZedddZdd Z	dd Z
  ZS )RepGhostModuler      Tc                    s   t t|   || _|}|}	ttj|||||d ddt||r(tjddnt	 | _
g }
g }|rC|
t	  |t| tj|
 | _tj| | _ttj||	|d|d |ddt|	| _|rptjdd| _d S t	 | _d S )N   FbiasTinplacer   )groupsr   )superr   __init__out_chsnn
SequentialConv2dBatchNorm2dReLUIdentityprimary_convappendfusion_conv	fusion_bncheap_operationrelu)selfin_chsr%   kernel_sizedw_sizestrider1   reparaminit_chsnew_chsr.   r/   	__class__ H/home/ubuntu/.local/lib/python3.10/site-packages/timm/models/repghost.pyr$      s*   
$zRepGhostModule.__init__c                 C   sF   |  |}| |}t| j| jD ]\}}|||| }q| |S N)r,   r0   zipr.   r/   r1   )r2   xx1x2convbnr<   r<   r=   forwardC   s
   


zRepGhostModule.forwardc                 C   sn   |  | jd | jd \}}t| j| jD ]\}}|  |||jd |j\}}|| |7 }||7 }q||fS )Nr   r   )_fuse_bn_tensorr0   r?   r.   r/   shapedevice_pad_1x1_to_3x3_tensor)r2   	kernel3x3bias3x3rC   rD   kernelr   r<   r<   r=   get_equivalent_kernel_biasJ   s   
z)RepGhostModule.get_equivalent_kernel_biasc                 C   s    | d u rdS t jj| g dS )Nr   )r   r   r   r   )torchr&   
functionalpad)	kernel1x1r<   r<   r=   rI   R   s   z%RepGhostModule._pad_1x1_to_3x3_tensorNc                 C   s   |r|n|j jd }|r|n|jj}t| tjr#| j}| jd u s"J nt| tjs+J t	j
|ddd|d}t|tjrf|j }|j}|j}|j}|j}	||	  }
||
 dddd}|| ||| |
  fS t|tjsnJ |t	||jfS )Nr   r   )rH   )running_meanrG   weightrH   
isinstancer&   r(   r   r+   rN   onesr)   running_varepssqrtreshapezerosto)rC   rD   in_channelsrH   rL   rS   rW   gammabetarX   stdtr<   r<   r=   rF   Y   s$   zRepGhostModule._fuse_bn_tensorc              	   C   s   t | jdkrt | jdkrd S |  \}}tj| jd j| jd j| jd j	| jd j
| jd j| jd jdd| _|| jj_|| jj_| d | d g | _g | _d S )Nr   T)r]   out_channelsr4   paddingdilationr"   r   r.   r/   )lenr.   r/   rM   r&   r(   r0   r]   rb   r4   rc   rd   r"   rT   datar   __delattr__)r2   rL   r   r<   r<   r=   switch_to_deployp   s$   










zRepGhostModule.switch_to_deployc                 C   s   |    d S r>   )rh   r2   r<   r<   r=   reparameterize   s   zRepGhostModule.reparameterize)r   r   r   TT)NN)__name__
__module____qualname__r$   rE   rM   staticmethodrI   rF   rh   rj   __classcell__r<   r<   r:   r=   r      s    %
r   c                       s6   e Zd ZdZddejddf fdd	Zdd	 Z  ZS )
RepGhostBottleneckz# RepGhost bottleneck w/ optional SEr   r           Tc	           
         s  t t|   |d uo|dk}	|| _t||d|d| _| jdkr8tj|||||d d |dd| _t	|| _
nd | _d | _
|	rFt||dnd | _t||d|d| _||krb| jdkrbt | _d S ttj|||||d d |ddt	|tj||ddd	dd
t	|| _d S )Nrq   T)r1   r7   r   r   F)r6   rc   r"   r   )rd_ratior   )r6   rc   r   )r#   rp   r$   r6   r   ghost1r&   r(   conv_dwr)   bn_dw	_SE_LAYERseghost2r'   shortcut)
r2   r3   mid_chsr%   dw_kernel_sizer6   	act_layerse_ratior7   has_ser:   r<   r=   r$      s2   

zRepGhostBottleneck.__init__c                 C   s\   |}|  |}| jd ur| |}| |}| jd ur | |}| |}|| |7 }|S r>   )rs   rt   ru   rw   rx   ry   )r2   r@   ry   r<   r<   r=   rE      s   






zRepGhostBottleneck.forward)	rk   rl   rm   __doc__r&   r*   r$   rE   ro   r<   r<   r:   r=   rp      s    /rp   c                       s4  e Zd Z							d. fdd		Zejjd/ddZejjd0ddZejjde	j
fddZd1dedee fddZ		
	
		
d2dejdeeeee f  dededededeeej eejeej f f fddZ	 	
	d3deeee f d!ed"efd#d$Zd%d& Zd/d'efd(d)Zd*d+ Zd,d- Z  ZS )4r           ?r       avg皙?Tc	                    s  t t|   |dksJ d|| _|| _|| _d| _g | _td| d}	t	j
||	ddddd	| _| jt|	dd
d t	|	| _t	jdd| _|	}
t	g }t}d}d}| jD ]P}g }d}|D ]%\}}}}}t|| d}t|| d}|||
||||||d |}
qa|dkr|d9 }| jt|
|d| d |t	j|  |d7 }qYt|| d d}|t	t|
|d | | _}
t	j| | _|
| _d | _}t|d| _t	j
|
|ddddd	| _t	jdd| _|rt	dnt	 | _ |dkrt!||| _"d S t	 | _"d S )Nr   z7only output_stride==32 is valid, dilation not supportedF   r   r   r   r   r   	conv_stem)num_chs	reductionmoduleTr    r   )r}   r7   zblocks.i   	pool_type)#r#   r   r$   cfgsnum_classes	drop_rategrad_checkpointingfeature_infor   r&   r(   r   r-   dictr)   bn1r*   act1
ModuleListrp   r'   r   pool_dimblocksnum_featureshead_hidden_sizer
   global_pool	conv_headact2Flattenr+   flattenr   
classifier)r2   r   r   widthin_chansoutput_strider   r   r7   stem_chsprev_chsstagesblock	stage_idx
net_stridecfglayersskexp_sizecr}   r%   rz   r:   r<   r=   r$      sV   




(zRepGhostNet.__init__Fc                 C   s    t d|rdndd fdgd}|S )Nz^conv_stem|bn1z^blocks\.(\d+)z^blocks\.(\d+)\.(\d+))r   )i )stemr   )r   )r2   coarsematcherr<   r<   r=   group_matcher  s   zRepGhostNet.group_matcherc                 C   s
   || _ d S r>   )r   )r2   enabler<   r<   r=   set_grad_checkpointing  s   
z"RepGhostNet.set_grad_checkpointingreturnc                 C   s   | j S r>   )r   ri   r<   r<   r=   get_classifier  s   zRepGhostNet.get_classifierNr   r   c                 C   sZ   || _ |d urt|d| _|rtdnt | _|dkr&t| j|| _	d S t | _	d S )Nr   r   r   )
r   r
   r   r&   r   r+   r   r   r   r   )r2   r   r   r<   r<   r=   reset_classifier"  s
   (zRepGhostNet.reset_classifierNCHWr@   indicesnorm
stop_early
output_fmtintermediates_onlyc                    s  |dv sJ dg }dgdd | j dd D   tt |\}}	 fdd|D } |	 }	d	}
| |}|
|v r?|| | |}| |}tj	 sP|sT| j
}n	| j
d|	d  }t|dd
D ]\}
}| jrutj	 sut||}n||}|
|v r|| qc|r|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.rR   c                 S   "   g | ]}t |d  dd qS r   .rR   intsplit.0infor<   r<   r=   
<listcomp>A     " z5RepGhostNet.forward_intermediates.<locals>.<listcomp>r   Nc                    s   g | ]} | d  qS )r   r<   )r   i
stage_endsr<   r=   r   C  s    r   )start)r   r   re   r   r-   r   r   rN   jitis_scriptingr   	enumerater   r   )r2   r@   r   r   r   r   r   intermediatestake_indices	max_indexfeat_idxr   stager<   r   r=   forward_intermediates*  s2   




z!RepGhostNet.forward_intermediatesr   
prune_norm
prune_headc                 C   s`   dgdd | j dd D  }tt||\}}|| }| jd|d  | _|r.| dd |S )z@ Prune layers not required for specified intermediates.
        rR   c                 S   r   r   r   r   r<   r<   r=   r   g  r   z9RepGhostNet.prune_intermediate_layers.<locals>.<listcomp>r   Nr    )r   r   re   r   r   )r2   r   r   r   r   r   r   r<   r<   r=   prune_intermediate_layers_  s   z%RepGhostNet.prune_intermediate_layersc                 C   sP   |  |}| |}| |}| jr!tj s!t| j|dd}|S | |}|S )NT)r   )	r   r   r   r   rN   r   r   r   r   r2   r@   r<   r<   r=   forward_featureso  s   



zRepGhostNet.forward_features
pre_logitsc                 C   sX   |  |}| |}| |}| |}| jdkr#tj|| j| jd}|r'|S | |S )Nrq   )ptraining)	r   r   r   r   r   Fdropoutr   r   )r2   r@   r   r<   r<   r=   forward_heady  s   




zRepGhostNet.forward_headc                 C   s   |  |}| |}|S r>   )r   r   r   r<   r<   r=   rE     s   

zRepGhostNet.forwardc                 C   s   t | dd d S )NF)do_copy)repghost_model_convertri   r<   r<   r=   convert_to_deploy  s   zRepGhostNet.convert_to_deploy)r   r   r   r   r   r   TF)Tr>   )NFFr   F)r   FT)rk   rl   rm   r$   rN   r   ignorer   r   r&   Moduler   r   r   strr   Tensorr   r   boolr   r   r   r   r   rE   r   ro   r<   r<   r:   r=   r      sd    ?
 
7

	Tmodelc                 C   sJ   |rt | } |  D ]}t|dr|  q|dur#t|  | | S )zQ
    taken from from https://github.com/DingXiaoH/RepVGG/blob/main/repvgg.py
    rh   N)copydeepcopymoduleshasattrrh   rN   save
state_dict)r   	save_pathr   r   r<   r<   r=   r     s   

r   r   Fc                 K   s   g dgg dgg dgg dgg dgg dgg dg dg dg d	g d
gg dgg dg dg dg dgg	}t d||d|}tt| |fdt ddi|S )z(
    Constructs a RepGhostNet model
    )r      r   r   r   )r      r   r   r   )r   $   r   r   r   )   r   (         ?r   )r   <   r   r   r   )r   x   P   r   r   )r   d   r   r   r   )r   r   r   r   r   )r      p   r   r   )r   P  r   r   r   )r   r      r   r   )r     r   r   r   )r   r   r   r   r   )r   r   feature_cfgT)flatten_sequentialNr<   )r   r   r   )variantr   
pretrainedkwargsr   model_kwargsr<   r<   r=   _create_repghostnet  sD   r  r   c                 K   s   | dddddt tddd
|S )	Nr   )r      r  )   r	  g      ?bicubicr   r   )
urlr   
input_size	pool_sizecrop_pctinterpolationmeanr`   
first_convr   r   )r  r  r<   r<   r=   _cfg  s   r  ztimm/)	hf_hub_id)zrepghostnet_050.in1kzrepghostnet_058.in1kzrepghostnet_080.in1kzrepghostnet_100.in1kzrepghostnet_111.in1kzrepghostnet_130.in1kzrepghostnet_150.in1kzrepghostnet_200.in1kr   c                 K      t dd| d|}|S )z RepGhostNet-0.5x repghostnet_050g      ?r   r  N)r  r  r  r  r   r<   r<   r=   r       r  c                 K   r  )z RepGhostNet-0.58x repghostnet_058g(\?r  N)r  r  r  r<   r<   r=   r    r  r  c                 K   r  )z RepGhostNet-0.8x repghostnet_080g?r  N)r  r  r  r<   r<   r=   r    r  r  c                 K   r  )z RepGhostNet-1.0x repghostnet_100r   r  N)r  r  r  r<   r<   r=   r    r  r  c                 K   r  )z RepGhostNet-1.11x repghostnet_111g(\?r  N)r  r  r  r<   r<   r=   r    r  r  c                 K   r  )z RepGhostNet-1.3x repghostnet_130g?r  N)r  r  r  r<   r<   r=   r    r  r  c                 K   r  )z RepGhostNet-1.5x repghostnet_150g      ?r  N)r  r  r  r<   r<   r=   r    r  r  c                 K   r  )z RepGhostNet-2.0x repghostnet_200g       @r  N)r   r  r  r<   r<   r=   r   #  r  r   )NT)r   F)r   r   )4r   r   	functoolsr   typingr   r   r   r   rN   torch.nnr&   torch.nn.functionalrO   r   	timm.datar   r	   timm.layersr
   r   r   _builderr   _efficientnet_blocksr   r   	_featuresr   _manipulater   	_registryr   r   __all__rv   r   r   rp   r   r   r  r  default_cfgsr  r  r  r  r  r  r  r   r<   r<   r<   r=   <module>   s    jH =

,
$