o
    پiM                     @   s  d 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	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mZmZ ddlmZ zddlmZ W n ey_   ddlmZ Y nw d+ddZG dd dejZ G dd dej!Z"d,ddZ#G dd dejj$Z%dd Z&dd Z'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Z/G d)d* d*eZ0dS )-aw   Normalization + Activation Layers

Provides Norm+Act fns for standard PyTorch norm layers such as
* BatchNorm
* GroupNorm
* LayerNorm

This allows swapping with alternative layers that are natively both norm + act such as
* EvoNorm (evo_norm.py)
* FilterResponseNorm (filter_response_norm.py)
* InplaceABN (inplace_abn.py)

Hacked together by / Copyright 2022 Ross Wightman
    )UnionListOptionalAnyN)nn)
functional)FrozenBatchNorm2d   )create_act_layer)is_fast_normfast_group_normfast_layer_normfast_rms_norm
rms_norm2dfast_rms_norm2d)RmsNorm	RmsNorm2d)_assert)rms_normFTc                 C   s@   |pi }| d| d }|rt| fi |}|d u rt S |S )Ninplace)
setdefaultr
   r   Identity)	act_layer
act_kwargsr   	apply_actact r   H/home/ubuntu/.local/lib/python3.10/site-packages/timm/layers/norm_act.py_create_act!   s   r   c                       sB   e Zd ZdZdddddejdddddf fdd	Zdd	 Z  ZS )
BatchNormAct2dzBatchNorm + Activation

    This module performs BatchNorm + Activation in a manner that will remain backwards
    compatible with weights trained with separate bn, act. This is why we inherit from BN
    instead of composing it as a .bn member.
    h㈵>g?TNc              
      s   z||d}t t| j|f||||d| W n ty.   t t| j|||||d Y nw |
d ur6|
 nt | _t|||	|d| _d S )N)devicedtype)epsmomentumaffinetrack_running_statsr   r   r   )	superr   __init__	TypeErrorr   r   dropr   r   )selfnum_featuresr#   r$   r%   r&   r   r   r   r   
drop_layerr!   r"   factory_kwargs	__class__r   r   r)   1   s.   




	zBatchNormAct2d.__init__c              
   C   s   t |jdkd|j d | jd u rd}n| j}| jr9| jr9| jd ur9| jd | jd u r6dt| j }n| j}	 | jr@d}n
| jd u oI| j	d u }	 t
|| jrT| jrW| jnd | jr^| jra| j	nd | j| j||| j}| |}| |}|S )N   zexpected 4D input (got zD input)g        r	   g      ?T)r   ndimr$   trainingr&   num_batches_trackedadd_floatrunning_meanrunning_varF
batch_normweightbiasr#   r+   r   )r,   xexponential_average_factorbn_trainingr   r   r   forwardV   s8   




zBatchNormAct2d.forward)	__name__
__module____qualname____doc__r   ReLUr)   rA   __classcell__r   r   r0   r   r   *   s    	%r   c                       s*   e Zd Zdejdejf fddZ  ZS )SyncBatchNormActr>   returnc                    s8   t  |}t| dr| |}t| dr| |}|S )Nr+   r   )r(   rA   hasattrr+   r   r,   r>   r0   r   r   rA      s   



zSyncBatchNormAct.forward)rB   rC   rD   torchTensorrA   rG   r   r   r0   r   rH      s    "rH   c                 C   s
  | }t | tjjjjrpt | tr(t| j| j	| j
| j| j|d}| j|_| j|_ntj| j| j	| j
| j| j|}| jrWt  | j|_| j|_W d    n1 sRw   Y  | j|_| j|_| j|_| j|_t| drp| j|_|  D ]\}}||t|| qt~ |S )N)process_groupqconfig)
isinstancerL   r   modules	batchnorm
_BatchNormr   rH   r-   r#   r$   r%   r&   r   r+   SyncBatchNormno_gradr<   r=   r8   r9   r5   r4   rJ   rO   named_children
add_moduleconvert_sync_batchnorm)modulerN   module_outputnamechildr   r   r   rX      sH   
	



rX   c                       s   e Zd ZdZddejdddfdedef fddZd	e	d
e
de	dedee
 dee
 dee
 f fddZdejdejfddZde
fddZ  ZS )FrozenBatchNormAct2da$  
    BatchNormAct2d where the batch statistics and the affine parameters are fixed

    Args:
        num_features (int): Number of features ``C`` from an expected input of size ``(N, C, H, W)``
        eps (float): a value added to the denominator for numerical stability. Default: 1e-5
    r    TNr-   r#   c                    s   t    || _| dt| | dt| | dt| | dt| |d ur3| nt | _	t
||||d| _d S )Nr<   r=   r8   r9   r'   )r(   r)   r#   register_bufferrL   oneszerosr   r   r+   r   r   )r,   r-   r#   r   r   r   r   r.   r0   r   r   r)      s   

zFrozenBatchNormAct2d.__init__
state_dictprefixlocal_metadatastrictmissing_keysunexpected_keys
error_msgsc           	   	      s2   |d }||v r||= t  ||||||| d S )Nr5   )r(   _load_from_state_dict)	r,   ra   rb   rc   rd   re   rf   rg   num_batches_tracked_keyr0   r   r   rh      s   
z*FrozenBatchNormAct2d._load_from_state_dictr>   rI   c                 C   s   | j dddd}| jdddd}| jdddd}| jdddd}||| j   }|||  }|| | }| | |}|S )Nr	   )	r<   reshaper=   r9   r8   r#   rsqrtr   r+   )r,   r>   wbrvrmscaler=   r   r   r   rA      s   zFrozenBatchNormAct2d.forwardc                 C   s,   | j j d| jjd  d| j d| j dS )N(r   z, eps=z, act=))r1   rB   r<   shaper#   r   )r,   r   r   r   __repr__   s   ,zFrozenBatchNormAct2d.__repr__)rB   rC   rD   rE   r   rF   intr7   r)   dictstrboolr   rh   rL   rM   rA   ru   rG   r   r   r0   r   r]      s<    r]   c                 C   sJ  | }t | ttfrGt| j}| j|_| j|_| jr-| jj 	 |j_| j
j 	 |j
_| jj|j_| jj|j_| j|_| j|_| j|_|S t | tjjjjtjjjjfrt| j}| j|_| j|_| jrz| jj 	 |j_| j
j 	 |j
_| jj|j_| jj|j_| j|_|S |  D ]\}}t|}||ur||| q|S )a  
    Converts all `BatchNorm2d` and `SyncBatchNorm` or `BatchNormAct2d` and `SyncBatchNormAct2d` layers
    of provided module into `FrozenBatchNorm2d` or `FrozenBatchNormAct2d` respectively.

    Args:
        module (torch.nn.Module): Any PyTorch module.

    Returns:
        torch.nn.Module: Resulting module

    Inspired by https://github.com/pytorch/pytorch/blob/a5895f85be0f10212791145bfedc0261d364f103/torch/nn/modules/batchnorm.py#L762
    )rP   r   rH   r]   r-   r%   r<   dataclonedetachr=   r8   r9   r#   r+   r   rL   r   rQ   rR   BatchNorm2drT   r   rV   freeze_batch_norm_2drW   rY   resr[   r\   	new_childr   r   r   r~     s>   

r~   c                 C   s  | }t | tr=t| j}| jr#| jj  |j_| j	j  |j	_| j
j|j
_| jj|j_| j|_| j|_| j|_|S t | trrtj| j}| jr`| jj  |j_| j	j  |j	_| j
j|j
_| jj|j_| j|_|S |  D ]\}}t|}||ur||| qv|S )a  
    Converts all `FrozenBatchNorm2d` layers of provided module into `BatchNorm2d`. If `module` is itself and instance
    of `FrozenBatchNorm2d`, it is converted into `BatchNorm2d` and returned. Otherwise, the module is walked
    recursively and submodules are converted in place.

    Args:
        module (torch.nn.Module): Any PyTorch module.

    Returns:
        torch.nn.Module: Resulting module

    Inspired by https://github.com/pytorch/pytorch/blob/a5895f85be0f10212791145bfedc0261d364f103/torch/nn/modules/batchnorm.py#L762
    )rP   r]   r   r-   r%   r<   rz   r{   r|   r=   r8   r9   r#   r+   r   r   rL   r   r}   rV   unfreeze_batch_norm_2drW   r   r   r   r   r   .  s6   


r   c                 C   s    |r| | dks
J | | S |S )Nr   r   )num_channels
num_groups
group_sizer   r   r   _num_groupsW  s   r   c                	       s:   e Zd Zdddddejdddf	 fdd	Zdd Z  ZS )	GroupNormAct    r    TNc                    sV   t t| jt||||||d |
d ur|
 nt | _t|||	|d| _t	 | _
d S )Nr#   r%   r'   )r(   r   r)   r   r   r   r+   r   r   r   
_fast_norm)r,   r   r   r#   r%   r   r   r   r   r   r.   r0   r   r   r)   `  s   

zGroupNormAct.__init__c                 C   R   | j rt|| j| j| j| j}nt|| j| j| j| j}| |}| 	|}|S N
r   r   r   r<   r=   r#   r:   
group_normr+   r   rK   r   r   r   rA   x     

zGroupNormAct.forwardrB   rC   rD   r   rF   r)   rA   rG   r   r   r0   r   r   ^  s    r   c                       6   e Zd Zdddejdddf fdd	Zdd Z  ZS )GroupNorm1Actr    TNc	           	         sN   t t| jd|||d |d ur| nt | _t||||d| _t | _	d S )Nr	   r   r'   )
r(   r   r)   r   r   r+   r   r   r   r   	r,   r   r#   r%   r   r   r   r   r.   r0   r   r   r)     s   zGroupNorm1Act.__init__c                 C   r   r   r   rK   r   r   r   rA     r   zGroupNorm1Act.forwardr   r   r   r0   r   r     s    r   c                       sL   e Zd Zdddejdddfdeeee ej	f f fddZ
dd Z  ZS )	LayerNormActr    TNnormalization_shapec	           	         L   t t| j|||d |d ur| nt | _t||||d| _t | _	d S N)r#   elementwise_affiner'   )
r(   r   r)   r   r   r+   r   r   r   r   )	r,   r   r#   r%   r   r   r   r   r.   r0   r   r   r)     s   zLayerNormAct.__init__c                 C   r   r   )
r   r   normalized_shaper<   r=   r#   r:   
layer_normr+   r   rK   r   r   r   rA     r   zLayerNormAct.forward)rB   rC   rD   r   rF   r   rv   r   rL   Sizer)   rA   rG   r   r   r0   r   r     s    r   c                       r   )LayerNormAct2dr    TNc	           	         r   r   )
r(   r   r)   r   r   r+   r   r   r   r   r   r0   r   r   r)     s   zLayerNormAct2d.__init__c                 C   sr   | dddd}| jrt|| j| j| j| j}nt|| j| j| j| j}| dddd}| 	|}| 
|}|S )Nr         r	   )permuter   r   r   r<   r=   r#   r:   r   r+   r   rK   r   r   r   rA     s   

zLayerNormAct2d.forwardr   r   r   r0   r   r     s    r   c                       H   e Zd ZdZdddejdddf fdd	Zdejdejfd	d
Z	  Z
S )
RmsNormAct*   RMSNorm + Activation for '2D' NCHW tensors

    NOTE: It's currently (2025-05-10) faster to use an eager 2d kernel that does reduction
    on dim=1 than to permute and use internal PyTorch F.rms_norm, this may change if something
    like https://github.com/pytorch/pytorch/pull/150576 lands.
    ư>TNc	           	         H   t  j|||d |d ur| nt | _t||||d| _t | _d S N)channelsr#   r%   r'   	r(   r)   r   r   r+   r   r   r   r   r   r0   r   r   r)        zRmsNormAct.__init__r>   rI   c                 C   H   | j rt|| j| j| j}n
t|| j| j| j}| |}| |}|S r   )r   r   r   r<   r#   r   r+   r   rK   r   r   r   rA        

zRmsNormAct.forwardrB   rC   rD   rE   r   rF   r)   rL   rM   rA   rG   r   r   r0   r   r         	r   c                       r   )RmsNormAct2dr   r   TNc	           	         r   r   r   r   r0   r   r   r)     r   zRmsNormAct2d.__init__r>   rI   c                 C   r   r   )r   r   r   r<   r#   r   r+   r   rK   r   r   r   rA     r   zRmsNormAct2d.forwardr   r   r   r0   r   r     r   r   )NFTr   )1rE   typingr   r   r   r   rL   r   torch.nnr   r:   torchvision.ops.miscr   
create_actr
   	fast_normr   r   r   r   r   r   normr   r   trace_utilsr   torch.nn.functionalr   ImportErrorr   r}   r   rT   rH   rX   Moduler]   r~   r   r   	GroupNormr   r   	LayerNormr   r   r   r   r   r   r   r   <module>   s:     
	_
+@,)$!