o
    پi                     @   s  d Z ddlZddlmZ ddlmZmZ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  mZ ddlmZmZ ddl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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.G dd dej+Z/G dd dej+Z0G dd dej+Z1dee2ej3f dej+d ee2ej3f fd!d"Z4dEd%e2d&e5d'e6d(ed e1f
d)d*Z7dFd,d-Z8e(e8 e8d.d/e8 e8d.d/e8d.d/e8d.d/e8 e8d.d/e8 e8 d0
Z9e'dGd e1fd1d2Z:e'dGd e1fd3d4Z;e'dGd e1fd5d6Z<e'dGd e1fd7d8Z=e'dGd e1fd9d:Z>e'dGd e1fd;d<Z?e'dGd'e6d(ed e1fd=d>Z@e'dGd'e6d(ed e1fd?d@ZAe'dGd'e6d(ed e1fdAdBZBe'dGd'e6d(ed e1fdCdDZCdS )Ha  
An implementation of GhostNet & GhostNetV2 Models as defined in:
GhostNet: More Features from Cheap Operations. https://arxiv.org/abs/1911.11907
GhostNetV2: Enhance Cheap Operation with Long-Range Attention. https://proceedings.neurips.cc/paper_files/paper/2022/file/40b60852a4abdaa696b5a1a78da34635-Paper-Conference.pdf
GhostNetV3: Exploring the Training Strategies for Compact Models. https://arxiv.org/abs/2404.11202

The train script & code of models at:
Original model: https://github.com/huawei-noah/CV-backbones/tree/master/ghostnet_pytorch
Original model: https://github.com/huawei-noah/Efficient-AI-Backbones/blob/master/ghostnetv2_pytorch/model/ghostnetv2_torch.py
Original model: https://github.com/huawei-noah/Efficient-AI-Backbones/blob/master/ghostnetv3_pytorch/ghostnetv3.py
    N)partial)AnyCallableDictListSetOptionalTupleUnionIMAGENET_DEFAULT_MEANIMAGENET_DEFAULT_STD)SelectAdaptivePool2dLinearmake_divisible	LayerTypereparameterize_model   )build_model_with_cfg)SqueezeExcite	ConvBnAct)feature_take_indices)checkpoint_seq)register_modelgenerate_default_cfgsGhostNethard_sigmoid   )divisor)
gate_layerrd_round_fnc                       ^   e Zd Zddddejfdededededed	ed
ef fddZdej	dej	fddZ
  ZS )GhostModuler         in_chsout_chskernel_sizeratiodw_sizestride	act_layerc           
         s   t t|   || _t|| }||d  }	ttj|||||d ddt	||dd| _
ttj||	|d|d |ddt	|	|dd| _d S )Nr   r$   FbiasTinplacegroupsr.   )superr#   __init__r'   mathceilnn
SequentialConv2dBatchNorm2dprimary_convcheap_operation
selfr&   r'   r(   r)   r*   r+   r,   init_chsnew_chs	__class__ H/home/ubuntu/.local/lib/python3.10/site-packages/timm/models/ghostnet.pyr4   $   s   

zGhostModule.__init__xreturnc                 C   sH   |  |}| |}tj||gdd}|d d d | jd d d d f S )Nr   dim)r;   r<   torchcatr'   )r>   rE   x1x2outrC   rC   rD   forward?   s   

"zGhostModule.forward__name__
__module____qualname__r7   ReLUintr   r4   rI   TensorrN   __classcell__rC   rC   rA   rD   r#   #   s,    r#   c                       r"   )GhostModuleV2r   r$   r%   r&   r'   r(   r)   r*   r+   r,   c           
         s  t    t | _|| _t|| }||d  }	ttj	|||||d ddt
||dd| _ttj	||	|d|d |ddt
|	|dd| _ttj	|||||d ddt
|tj	||ddd	|dd
t
|tj	||ddd|dd
t
|| _d S )Nr   r$   Fr-   Tr/   r1   r      r   r$   r(   r+   paddingr2   r.   rY   r   r$   r   )r3   r4   r7   Sigmoidgate_fnr'   r5   r6   r8   r9   r:   r;   r<   
short_convr=   rA   rC   rD   r4   G   s.   



zGhostModuleV2.__init__rE   rF   c                 C   s   |  tj|ddd}| |}| |}tj||gdd}|d d d | jd d d d f tj| 	||j
d |j
d fdd S )	Nr$   r(   r+   r   rG   nearestsizemode)ra   F
avg_pool2dr;   r<   rI   rJ   r'   interpolater`   shape)r>   rE   resrK   rL   rM   rC   rC   rD   rN   i   s   

$zGhostModuleV2.forwardrO   rC   rC   rA   rD   rW   F   s,    "rW   c                       s~   e Zd Zddddejdfdedededed	ed
ededef fddZdd Z	dd Z
dd Zdd Zdd Zdd Z  ZS )GhostModuleV3r   r$   r%   originalr&   r'   r(   r)   r*   r+   r,   rh   c	           	         s  t t|   t | _|| _t|| |d  || _	d| _
d| _| js2t | _t | _d | _d | _tfddt| j
D | _|dd| _t| _t fddt| j
D | _tddd	dd d
| _|dd| _| j	dv rttj|d ddt|tj||ddd|ddt|tj||ddd|ddt|nt | _| _| _ | _ d S )Nr   r%   Fc              
      s$   g | ]}t  d  ddqS )r$   N)pad_typer,   r   .0_)r&   r?   r(   r+   rC   rD   
<listcomp>   s
    
z*GhostModuleV3.__init__.<locals>.<listcomp>Tr/   c                    s&   g | ]}t  d  d d ddqS r   r$   Nrp   
group_sizer,   rq   rr   )r*   r?   r@   rC   rD   ru      s
    
r   rw   shortcutr$   r-   rX   rZ   r[   r]   r^   )!r3   rn   r4   r7   r_   r`   r'   r5   r6   rh   num_conv_branches
infer_modeIdentityr;   r<   primary_rpr_skipprimary_rpr_scale
ModuleListrangeprimary_rpr_convprimary_activationr:   cheap_rpr_skipcheap_rpr_convr   cheap_rpr_scalecheap_activationr8   r9   ra   in_channelsr2   r(   )	r>   r&   r'   r(   r)   r*   r+   r,   rh   rA   )r*   r&   r?   r(   r@   r+   rD   r4   s   sR   



		
zGhostModuleV3.__init__c                 C   s   | j r| |}| |}n.d}| jD ]}|||7 }q| |}| || | }| jD ]}|||7 }q.| |}t	j
||gdd}| jdvrL|S | tj|ddd}|d d d | jd d d d f tj| ||jd |jd fd	d
 S )Nr   r   rG   ry   r$   rb   rc   rd   re   rf   )r|   r;   r<   r   r   r   r   r   r   rI   rJ   rh   ra   ri   rj   r'   rk   r`   rl   )r>   rE   rK   rL   r   r   rM   rm   rC   rC   rD   rN      s$   





$zGhostModuleV3.forwardc                 C      d}d}| j d ur | | j \}}| jd }t|||||g}d}d}| jd ur1| | j\}}d}d}t| jD ]}| | j| \}	}
||	7 }||
7 }q:|| | }|| | }||fS Nr   r$   )	r   _fuse_bn_tensorr(   ri   padr~   r   r{   r   r>   kernel_scale
bias_scaler   kernel_identitybias_identitykernel_conv	bias_convix_kernel_biaskernel_final
bias_finalrC   rC   rD   _get_kernel_bias_primary   &   



z&GhostModuleV3._get_kernel_bias_primaryc                 C   r   r   )	r   r   r(   ri   r   r   r   r{   r   r   rC   rC   rD   _get_kernel_bias_cheap   r   z$GhostModuleV3._get_kernel_bias_cheapc                 C     t |tr|jj}|jj}|jj}|jj}|jj}|jj}nSt |t	j
s&J 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< qI|	| _| j}|j}|j}|j}|j}|j}||  }|| dddd}|| ||| |  fS N	id_tensor)dtypedevicer   r$   rd   
isinstancer   convweightbn1running_meanrunning_varr.   epsr7   r:   hasattrr   r2   rI   zerosr(   r   r   r   r   sqrtreshaper>   branchkernelr   r   gammabetar   	input_dimkernel_valueistdtrC   rC   rD   r      >   



zGhostModuleV3._fuse_bn_tensorc              
   C   s  | j rd S |  \}}tj| jd jj| jd jj| jd jj| jd jj	| jd jj
| jd jj| jd jjdd| _|| jj_|| jj_t| j| jd urR| jnt | _|  \}}tj| jd jj| jd jj| jd jj| jd jj	| jd jj
| jd jj| jd jjdd| _|| jj_|| jj_t| j| jd ur| jnt | _|  D ]}|  qt| dr| d t| dr| d t| dr| d t| dr| d t| dr| d t| d	r| d	 d| _ d S )
Nr   Tr   out_channelsr(   r+   r\   dilationr2   r.   r   r   r~   r   r   r   )r|   r   r7   r9   r   r   r   r   r(   r+   r\   r   r2   r;   r   datar.   r8   r   r   r   r<   r   
parametersdetach_r   __delattr__)r>   primary_kernelprimary_biascheap_kernel
cheap_biaspararC   rC   rD   switch_to_deploy  sf   



















zGhostModuleV3.switch_to_deployc                 C      |    d S Nr   r>   rC   rC   rD   reparameterizeJ     zGhostModuleV3.reparameterize)rP   rQ   rR   r7   rS   rT   r   strr4   rN   r   r   r   r   r   rV   rC   rC   rA   rD   rn   r   s<    	5 ;rn   c                       sf   e Zd ZdZddejddfdededed	ed
ededede	f fddZ
dejdejfddZ  ZS )GhostBottleneckz% GhostV1/V2 bottleneck w/ optional SEr%   r           ro   r&   mid_chsr'   dw_kernel_sizer+   r,   se_ratiorh   c	           
         s,  t t|   |d uo|dk}	|| _|dkrt|||d| _nt|||d| _| jdkrDtj|||||d d |dd| _	t
|| _nd | _	d | _|	rRt||dnd | _t||tjd| _||krn| jdkrnt | _d S ttj|||||d d |ddt
|tj||ddd	dd
t
|| _d S )Nr   ro   )r,   r   r$   Fr+   r\   r2   r.   rd_ratior   r+   r\   r.   )r3   r   r4   r+   r#   ghost1rW   r7   r9   conv_dwr:   bn_dw	_SE_LAYERser}   ghost2r8   rz   
r>   r&   r   r'   r   r+   r,   r   rh   has_serA   rC   rD   r4   Q  s6   

zGhostBottleneck.__init__rE   rF   c                 C   s\   |}|  |}| jd ur| |}| |}| jd ur | |}| |}|| |7 }|S r   )r   r   r   r   r   rz   )r>   rE   rz   rC   rC   rD   rN     s   






zGhostBottleneck.forward)rP   rQ   rR   __doc__r7   rS   rT   r   floatr   r4   rI   rU   rN   rV   rC   rC   rA   rD   r   N  s2    	2r   c                       s   e Zd ZdZddejddfdededed	ed
ededede	f fddZ
dejdejfddZdd Zdd Zdd Zdd Z  ZS )GhostBottleneckV3z" GhostV3 bottleneck w/ optional SEr%   r   r   ro   r&   r   r'   r   r+   r,   r   rh   c	           
         sh  t t|   |d uo|dk}	| _d| _d| _| js%t | _t | _	t
|||d| _| jdkrXt fddt| jD | _tddd	dd d
| _ | _| _n
t | _t | _d | _|	rmt|dnt | _t
|tjdd| _||kr| jdkrt | _d S ttj||  d d |ddt|tj||ddd	ddt|| _d S )Nr   r%   F)r,   rh   r   c                    s*   g | ]}t   d  d d ddqS rv   rq   rr   r   r   r+   rC   rD   ru     s
    
z.GhostBottleneckV3.__init__.<locals>.<listcomp>r$   r   rw   r   ro   r   r   )r3   r   r4   r+   r{   r|   r7   r}   r   r   rn   r   r   r   dw_rpr_convr   dw_rpr_scaler(   r   dw_rpr_skipr   r   r   rz   r8   r9   r:   r   rA   r   rD   r4     sD   





zGhostBottleneckV3.__init__rE   rF   c                 C   s   |}|  |}| jdkr-| jr| |}| |}n| |}| jD ]}|||7 }q"|}| |}| |}|| 	|7 }|S )Nr   )
r   r+   r|   r   r   r   r   r   r   rz   )r>   rE   rz   rK   r   rC   rC   rD   rN     s   






zGhostBottleneckV3.forwardc                 C   r   r   )	r   r   r(   ri   r   r   r   r{   r   r   rC   rC   rD   _get_kernel_bias_dw  r   z%GhostBottleneckV3._get_kernel_bias_dwc                 C   r   r   r   r   rC   rC   rD   r     r   z!GhostBottleneckV3._fuse_bn_tensorc              
   C   s   | j s| jdkr
d S |  \}}tj| jd jj| jd jj| jd jj	| jd jj| jd jj
| jd jj| jd jjdd| _|| jj_|| jj_t | _|  D ]}|  qTt| dre| d t| dro| d t| dry| d d| _ d S )Nr   r   Tr   r   r   r   )r|   r+   r   r7   r9   r   r   r   r   r(   r\   r   r2   r   r   r   r.   r}   r   r   r   r   r   )r>   	dw_kerneldw_biasr   rC   rC   rD   r   (  s2   











z"GhostBottleneckV3.switch_to_deployc                 C   r   r   r   r   rC   rC   rD   r   F  r   z GhostBottleneckV3.reparameterize)rP   rQ   rR   r   r7   rS   rT   r   r   r   r4   rI   rU   rN   r   r   r   r   rV   rC   rC   rA   rD   r     s:    	: r   c                       s  e Zd Z							d8ded	ed
ededededef fddZejj	de
fddZejj	d9dedeeef fddZejj	d:defddZejj	dejfddZd;dedefddZ	 			!	d<d"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	*		d=d#eeee f d+ed,efd-d.Zd"ejdejfd/d0Zd9d"ejd1edejfd2d3Zd"ejdejfd4d5Zd6d7 Z  Z S )>r           ?r%       avg皙?v1num_classeswidthin_chansoutput_strideglobal_pool	drop_rateversionc	              
      sf  t t|   |dksJ d|| _|| _|| _d| _g | _|dkr$tnt	}	t
d| d}
tj||
ddd	dd
| _| jt|
ddd t|
| _tjdd| _|
}tg }d}d}d}| jD ]q}g }d	}|D ]F\}}}}}t
|| d}t
|| d}i }|dkr|d	krd|d< |dkr|d	krd|d< ||	|||||fd|i| |}|d	7 }qi|d	kr|d9 }| jt||d| d |tj|  |d	7 }qat
|| d}|tt||d	 | | _}tj| | _|| _d | _}t|d| _tj||d	d	ddd
| _tjdd| _|rtd	nt  | _!|dkr,t"||| _#d S t  | _#d S )Nr   z7only output_stride==32 is valid, dilation not supportedFv3   r   r%   r$   r   r-   	conv_stem)num_chs	reductionmoduleTr/   r   v2attnrh   rz   r   zblocks.i   	pool_type)$r3   r   r4   cfgsr   r   grad_checkpointingfeature_infor   r   r   r7   r9   r   appenddictr:   r   rS   act1r   r8   r   pool_dimblocksnum_featureshead_hidden_sizer   r   	conv_headact2Flattenr}   flattenr   
classifier)r>   r   r   r   r   r   r   r   r   
Bottleneckstem_chsprev_chsstages	stage_idx	layer_idx
net_stridecfglayersskexp_sizecr   r'   r   layer_kwargsrA   rC   rD   r4   K  sd   

"



(zGhostNet.__init__rF   c                 C   s   t  S r   )setr   rC   rC   rD   no_weight_decay     zGhostNet.no_weight_decayFcoarsec                 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  )r>   r  matcherrC   rC   rD   group_matcher  s   zGhostNet.group_matcherTenablec                 C   s
   || _ d S r   )r   )r>   r"  rC   rC   rD   set_grad_checkpointing  s   
zGhostNet.set_grad_checkpointingc                 C   s   | j S r   )r  r   rC   rC   rD   get_classifier  r  zGhostNet.get_classifierc                 C   sR   || _ t|d| _|rtdnt | _|dkr"t| j|| _	d S t | _	d S )Nr   r   r   )
r   r   r   r7   r
  r}   r  r   r  r  )r>   r   r   rC   rC   rD   reset_classifier  s   (zGhostNet.reset_classifierNNCHWrE   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.rd   c                 S   "   g | ]}t |d  dd qS r   .rd   rT   splitrs   inforC   rC   rD   ru        " z2GhostNet.forward_intermediates.<locals>.<listcomp>r   Nc                    s   g | ]} | d  qS )r   rC   )rs   r   
stage_endsrC   rD   ru     s    r   )start)r   r   lenr   r  r   r  rI   jitis_scriptingr  	enumerater   r   )r>   rE   r'  r(  r)  r*  r+  intermediatestake_indices	max_indexfeat_idxr  stagerC   r4  rD   forward_intermediates  s2   




zGhostNet.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.
        rd   c                 S   r,  r-  r/  r1  rC   rC   rD   ru     r3  z6GhostNet.prune_intermediate_layers.<locals>.<listcomp>r   Nr    )r   r   r7  r  r%  )r>   r'  rA  rB  r5  r<  r=  rC   rC   rD   prune_intermediate_layers  s   z"GhostNet.prune_intermediate_layersc                 C   sP   |  |}| |}| |}| jr!tj s!t| j|dd}|S | |}|S )NT)r  )	r   r   r  r   rI   r8  r9  r   r  r>   rE   rC   rC   rD   forward_features  s   



zGhostNet.forward_features
pre_logitsc                 C   sX   |  |}| |}| |}| |}| jdkr#tj|| j| jd}|r'|S | |S )Nr   )ptraining)	r   r  r	  r  r   ri   dropoutrI  r  )r>   rE   rG  rC   rC   rD   forward_head   s   




zGhostNet.forward_headc                 C   s   |  |}| |}|S r   )rF  rK  rE  rC   rC   rD   rN   	  s   

zGhostNet.forwardc                 C   s   t | dd d S )NFr/   r   r   rC   rC   rD   convert_to_deploy  s   zGhostNet.convert_to_deploy)r   r   r%   r   r   r   r   F)T)r   )NFFr&  F)r   FT)!rP   rQ   rR   rT   r   r   r4   rI   r8  ignorer   r  boolr   r   r!  r#  r7   Moduler$  r%  rU   r   r
   r   r	   r@  rD  rF  rK  rN   rL  rV   rC   rC   rA   rD   r   J  s    	H

 
7

	
state_dictmodelrF   c                 C   st   d| v r| d } i }|   D ])\}}d|v r d|v r |dd}d|v r.d|v r.|dd}d|v r3q|||< q|S )NrQ  zbn.z.ghostzbn1.z.dw_rpr_total)itemsreplace)rQ  rR  out_dictr  vrC   rC   rD   checkpoint_filter_fn  s   
rX  r   Fvariantr   
pretrainedkwargsc                 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tt ddd|S )z%
    Constructs a GhostNet model
    )r%   r   r   r   r   )r%   0      r   r$   )r%   H   r]  r   r   )rY   r^  (         ?r$   )rY   x   r_  r`  r   )r%      P   r   r$   )r%      rc  r   r   )r%      rc  r   r   )r%   i  p   r`  r   )r%     rf  r`  r   )rY   rg     r`  r$   )rY     rh  r   r   )rY   ri  rh  r`  r   )r   r   T)flatten_sequential)pretrained_filter_fnfeature_cfgNrC   )r  r   r   rX  )rY  r   rZ  r[  r   model_kwargsrC   rC   rD   _create_ghostnet"  sF   rn  rC  c                 K   s   | dddddt tddd
|S )	Nr   )r%      ro  )   rp  g      ?bicubicr   r  )
urlr   
input_size	pool_sizecrop_pctinterpolationmeanr   
first_convr  r   )rr  r[  rC   rC   rD   _cfgO  s   ry  ztimm/)	hf_hub_id)
zghostnet_050.untrainedzghostnet_100.in1kzghostnet_130.untrainedzghostnetv2_100.in1kzghostnetv2_130.in1kzghostnetv2_160.in1kzghostnetv3_050.untrainedzghostnetv3_100.in1kzghostnetv3_130.untrainedzghostnetv3_160.untrainedc                 K      t dd| d|}|S )z GhostNet-0.5x ghostnet_050      ?r   rZ  N)r|  rn  rZ  r[  rR  rC   rC   rD   r|  v     r|  c                 K   r{  )z GhostNet-1.0x ghostnet_100r   r~  N)r  r  r  rC   rC   rD   r  }  r  r  c                 K   r{  )z GhostNet-1.3x ghostnet_130?r~  N)r  r  r  rC   rC   rD   r    r  r  c                 K      t dd| dd|}|S )z GhostNetV2-1.0x ghostnetv2_100r   r   r   rZ  r   N)r  r  r  rC   rC   rD   r       r  c                 K   r  )z GhostNetV2-1.3x ghostnetv2_130r  r   r  N)r  r  r  rC   rC   rD   r    r  r  c                 K   r  )z GhostNetV2-1.6x ghostnetv2_160皙?r   r  N)r  r  r  rC   rC   rD   r    r  r  c                 K   r  )z GhostNetV3-0.5x ghostnetv3_050r}  r   r  N)r  r  r  rC   rC   rD   r    r  r  c                 K   r  )z GhostNetV3-1.0x ghostnetv3_100r   r   r  N)r  r  r  rC   rC   rD   r    r  r  c                 K   r  )z GhostNetV3-1.3x ghostnetv3_130r  r   r  N)r  r  r  rC   rC   rD   r    r  r  c                 K   r  )z GhostNetV3-1.6x ghostnetv3_160r  r   r  N)r  r  r  rC   rC   rD   r    r  r  )r   F)rC  rM  )Dr   r5   	functoolsr   typingr   r   r   r   r   r   r	   r
   rI   torch.nnr7   torch.nn.functional
functionalri   	timm.datar   r   timm.layersr   r   r   r   timm.utils.modelr   _builderr   _efficientnet_blocksr   r   	_featuresr   _manipulater   	_registryr   r   __all__r   rP  r#   rW   rn   r   r   r   r   rU   rX  r   rO  rn  ry  default_cfgsr|  r  r  r  r  r  r  r  r  r  rC   rC   rC   rD   <module>   s    (#, ]K 2 ,I 
-
