U
    ¯Ê¹jÔ?  ã                   @   s  d Z ddlZddl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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 d4ejjdœdd„Z!d5dd„Z"d6d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d7e d#œd$d%„ƒZ%ed8e d#œd&d'„ƒZ&ed9e d#œd(d)„ƒZ'ed:e d#œd*d+„ƒZ(ed;e d#œd,d-„ƒZ)ed<e d#œd.d/„ƒZ*ed=e d#œd0d1„ƒZ+ed>e d#œd2d3„ƒZ,d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©ÚIMAGENET_DEFAULT_MEANÚIMAGENET_DEFAULT_STD)ÚSelectAdaptivePool2dÚLinearÚmake_divisibleé   )Úbuild_model_with_cfg)ÚSqueezeExciteÚ	ConvBnAct)Úcheckpoint_seq)Úregister_modelÚgenerate_default_cfgsÚRepGhostNetZhard_sigmoidé   )Zdivisor)Z
gate_layerZrd_round_fnc                       sX   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 |¡|rPtjdd�nt 	¡ ¡| _
g }
g }|r†|
 t 	¡ ¡ | t |¡¡ tj|
Ž | _tj|Ž | _t tj||	|d|d |dd�t |	¡¡| _|rÚtjdd�nt 	¡ | _d S )Né   F©ÚbiasT©Z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_sizeZdw_sizeÚstrider'   ÚreparamZinit_chsZnew_chsr$   r%   ©Ú	__class__© úS/var/www/html/bwave/python/venv/lib/python3.8/site-packages/timm/models/repghost.pyr      s*    
ýþzRepGhostModule.__init__c                 C   sF   |   |¡}|  |¡}t| j| jƒD ]\}}||||ƒƒ }q"|  |¡S ©N)r"   r&   Úzipr$   r%   r'   )r(   ÚxÚx1Zx2ÚconvÚbnr/   r/   r0   ÚforwardA   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_tensorr&   r2   r$   r%   ÚshapeÚdeviceÚ_pad_1x1_to_3x3_tensor)r(   Z	kernel3x3Zbias3x3r5   r6   Úkernelr   r/   r/   r0   Úget_equivalent_kernel_biasH   s    
z)RepGhostModule.get_equivalent_kernel_biasc                 C   s(   | d krdS t jj | ddddg¡S d S r8   )Útorchr   Ú
functionalÚpad)Z	kernel1x1r/   r/   r0   r<   P   s    z%RepGhostModule._pad_1x1_to_3x3_tensorNc                 C   sò   |r|n
|j jd }|r|n|jj}t| tjƒrF| j}| jd ksjt‚n$t| tj	ƒsVt‚t
j|ddd|d�}t|tjƒrÌ|j }|j}|j}|j}|j}	||	  ¡ }
||
  dddd¡}|| ||| |
  fS t|tj	ƒsÜt‚|t
 |¡ |j¡fS )Nr   r	   )r;   éÿÿÿÿ)Úrunning_meanr:   Úweightr;   Ú
isinstancer   r   r   ÚAssertionErrorr!   r?   Zonesr   Úrunning_varÚepsÚsqrtZreshapeZzerosÚto)r5   r6   Úin_channelsr;   r=   rC   rG   ÚgammaÚbetarH   ÚstdÚtr/   r/   r0   r9   W   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)rK   Úout_channelsr*   ÚpaddingÚdilationr   r   r$   r%   )Úlenr$   r%   r>   r   r   r&   rK   rP   r*   rQ   rR   r   rD   Údatar   Ú__delattr__)r(   r=   r   r/   r/   r0   Úswitch_to_deployn   s$    





ù



zRepGhostModule.switch_to_deployc                 C   s   |   ¡  d S r1   )rV   ©r(   r/   r/   r0   Úreparameterize�   s    zRepGhostModule.reparameterize)r	   r   r	   TT)NN)Ú__name__Ú
__module__Ú__qualname__r   r7   r>   Ústaticmethodr<   r9   rV   rX   Ú__classcell__r/   r/   r-   r0   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 k	o|dk}	|| _t||d|d�| _| jdkrptj|||||d d |dd�| _t 	|¡| _
nd | _d | _
|	rŒt||d�nd | _t||d|d�| _||krÂ| jdkrÂt ¡ | _nLt tj|||||d d |dd�t 	|¡tj||ddd	dd
�t 	|¡¡| _d S )Nr_   T)r'   r,   r	   r   F)r+   rQ   r   r   )Zrd_ratior   )r+   rQ   r   )r   r^   r   r+   r   Úghost1r   r   Úconv_dwr   Úbn_dwÚ	_SE_LAYERÚseÚghost2r   Úshortcut)
r(   r)   Úmid_chsr   Zdw_kernel_sizer+   Z	act_layerÚse_ratior,   Zhas_ser-   r/   r0   r   ˆ   sF    
   
  þ   
  þúzRepGhostBottleneck.__init__c                 C   s\   |}|   |¡}| jd k	r,|  |¡}|  |¡}| jd k	r@|  |¡}|  |¡}||  |¡7 }|S r1   )r`   ra   rb   rd   re   rf   )r(   r3   rf   r/   r/   r0   r7   ·   s    






zRepGhostBottleneck.forward)	rY   rZ   r[   Ú__doc__r   r    r   r7   r]   r/   r/   r-   r0   r^   …   s   ÷/r^   c                       s|   e Zd Zd‡ f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
dd„ Zdd„ Zdd„ Zdd„ Z‡  ZS )r   éè  ç      ð?r   é    Úavgçš™™™™™É?Tc	                    s  t t| ƒ ¡  |dkst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 ]¢}g }d}|D ]J\}}}}}t	|| dƒ}t	|| dƒ}| ||
||||||d�¡ |}
qÂ|dk�r<|d9 }| j t|
|d|› �d�¡ | t
j|Ž ¡ |d7 }q²t	|| d 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!||ƒnt
 ¡ | _"d S )Nrl   z7only output_stride==32 is valid, dilation not supportedFé   r   r   r   r	   r   Ú	conv_stem)Znum_chsZ	reductionÚmoduleTr   r   )rh   r,   zblocks.i   ©Z	pool_type)#r   r   r   rF   ÚcfgsÚnum_classesÚ	drop_rateÚgrad_checkpointingZfeature_infor   r   r   rp   r#   Údictr   Úbn1r    Úact1Z
ModuleListr^   r   r   Zpool_dimÚblocksÚnum_featuresr   Úglobal_poolÚ	conv_headÚact2ÚFlattenr!   Úflattenr   Ú
classifier)r(   rs   rt   ÚwidthZin_chansZoutput_strider|   ru   r,   Zstem_chsZprev_chsZstagesÚblockZ	stage_idxZ
net_strideÚcfgZlayersÚsÚkZexp_sizeÚcrh   r   rg   r-   r/   r0   r   Î   sX    


  ÿ


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Ÿ† )Ústemrz   )rw   )r(   ZcoarseZmatcherr/   r/   r0   Úgroup_matcher  s    þþzRepGhostNet.group_matcherc                 C   s
   || _ d S r1   )rv   )r(   Úenabler/   r/   r0   Úset_grad_checkpointing  s    z"RepGhostNet.set_grad_checkpointingc                 C   s   | j S r1   )r�   rW   r/   r/   r0   Úget_classifier  s    zRepGhostNet.get_classifierc                 C   sL   || _ t|d�| _|r t d¡nt ¡ | _|dkr>t| j|ƒnt ¡ | _	d S )Nrr   r	   r   )
rt   r   r|   r   r   r!   r€   r   r{   r�   )r(   rt   r|   r/   r/   r0   Úreset_classifier  s    zRepGhostNet.reset_classifierc                 C   sN   |   |¡}|  |¡}|  |¡}| jr@tj ¡ s@t| j|dd�}n
|  |¡}|S )NT)r€   )	rp   rx   ry   rv   r?   ÚjitZis_scriptingr   rz   ©r(   r3   r/   r/   r0   Úforward_features&  s    



zRepGhostNet.forward_featuresc                 C   sT   |   |¡}|  |¡}|  |¡}|  |¡}| jdkrFtj|| j| jd�}|  |¡}|S )Nr_   )ÚpÚtraining)	r|   r}   r~   r€   ru   ÚFZdropoutr’   r�   r�   r/   r/   r0   Úforward_head0  s    





zRepGhostNet.forward_headc                 C   s   |   |¡}|  |¡}|S r1   )r�   r”   r�   r/   r/   r0   r7   :  s    

zRepGhostNet.forwardc                 C   s   t | dd� d S )NF)Údo_copy)Úrepghost_model_convertrW   r/   r/   r0   Úconvert_to_deploy?  s    zRepGhostNet.convert_to_deploy)rj   rk   r   rl   rm   rn   T)F)T)rm   )rY   rZ   r[   r   r?   rŽ   Úignorer‰   r‹   rŒ   r�   r�   r”   r7   r—   r]   r/   r/   r-   r0   r   Í   s&          ÷>




T)Úmodelc                 C   sJ   |rt  | ¡} |  ¡ D ]}t|dƒr| ¡  q|dk	rFt |  ¡ |¡ | S )zQ
    taken from from https://github.com/DingXiaoH/RepVGG/blob/main/repvgg.py
    rV   N)ÚcopyÚdeepcopyÚmodulesÚhasattrrV   r?   ÚsaveZ
state_dict)r™   Z	save_pathr•   rq   r/   r/   r0   r–   C  s    


r–   rk   Fc                 K   s  dddddggdddddggdddddggd	dd
ddggd	dd
ddggdddddggdddddgdddddgdddddgdddddgdddddggd	ddddggd	ddddgd	ddddgd	ddddgd	ddddggg	}t f ||dœ|—Ž}tt| |fdt dd�i|—ŽS )z(
    Constructs a RepGhostNet model
    r   é   ro   r   r	   é   r   é$   é   é(   g      Ð?é<   éx   éP   éd   éð   ép   iP  é    ià  )rs   r‚   Zfeature_cfgT)Zflatten_sequential)rw   r
   r   )Úvariantr‚   Ú
pretrainedÚkwargsrs   Zmodel_kwargsr/   r/   r0   Ú_create_repghostnetQ  sD    üýìþýýüûr®   Ú c                 K   s   | dddddt tdddœ
|–S )	Nrj   )r   éà   r°   )é   r±   g      ì?Zbicubicrp   r�   )
Úurlrt   Z
input_sizeZ	pool_sizeZcrop_pctÚinterpolationZmeanrN   Z
first_convr�   r   )r²   r­   r/   r/   r0   Ú_cfg}  s          üûr´   ztimm/)Z	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.in1k)Úreturnc                 K   s   t dd| dœ|—Ž}|S )z RepGhostNet-0.5x Úrepghostnet_050g      à?©r‚   r¬   )r¶   ©r®   ©r¬   r­   r™   r/   r/   r0   r¶   «  s    r¶   c                 K   s   t dd| dœ|—Ž}|S )z RepGhostNet-0.58x Úrepghostnet_058g�Âõ(\�â?r·   )rº   r¸   r¹   r/   r/   r0   rº   ²  s    rº   c                 K   s   t dd| dœ|—Ž}|S )z RepGhostNet-0.8x Úrepghostnet_080gš™™™™™é?r·   )r»   r¸   r¹   r/   r/   r0   r»   ¹  s    r»   c                 K   s   t dd| dœ|—Ž}|S )z RepGhostNet-1.0x Úrepghostnet_100rk   r·   )r¼   r¸   r¹   r/   r/   r0   r¼   À  s    r¼   c                 K   s   t dd| dœ|—Ž}|S )z RepGhostNet-1.11x Úrepghostnet_111gÃõ(\�Âñ?r·   )r½   r¸   r¹   r/   r/   r0   r½   Ç  s    r½   c                 K   s   t dd| dœ|—Ž}|S )z RepGhostNet-1.3x Úrepghostnet_130gÍÌÌÌÌÌô?r·   )r¾   r¸   r¹   r/   r/   r0   r¾   Í  s    r¾   c                 K   s   t dd| dœ|—Ž}|S )z RepGhostNet-1.5x Úrepghostnet_150g      ø?r·   )r¿   r¸   r¹   r/   r/   r0   r¿   Ô  s    r¿   c                 K   s   t dd| dœ|—Ž}|S )z RepGhostNet-2.0x Úrepghostnet_200g       @r·   )rÀ   r¸   r¹   r/   r/   r0   rÀ   Û  s    rÀ   )NT)rk   F)r¯   )F)F)F)F)F)F)F)F)-ri   rš   Ú	functoolsr   r?   Ztorch.nnr   Ztorch.nn.functionalr@   r“   Z	timm.datar   r   Ztimm.layersr   r   r   Z_builderr
   Z_efficientnet_blocksr   r   Z_manipulater   Ú	_registryr   r   Ú__all__rc   ÚModuler   r^   r   r–   r®   r´   Zdefault_cfgsr¶   rº   r»   r¼   r½   r¾   r¿   rÀ   r/   r/   r/   r0   Ú<module>   sz   jHv
,

ÿÿÿÿÿÿÿÿã$