Ë
    éÓ^j7  ã                   ób   — d Z ddlZddlmZ  G d„ dej                  j                  «      Zdd„Zy)a=   Split BatchNorm

A PyTorch BatchNorm layer that splits input batch into N equal parts and passes each through
a separate BN layer. The first split is passed through the parent BN layers with weight/bias
keys the same as the original BN. All other splits pass through BN sub-layers under the '.aux_bn'
namespace.

This allows easily removing the auxiliary BN layers after training to efficiently
achieve the 'Auxiliary BatchNorm' as described in the AdvProp Paper, section 4.2,
'Disentangled Learning via An Auxiliary BN'

Hacked together by / Copyright 2020 Ross Wightman
é    Nc                   óR   ‡ — e Zd Z	 	 	 	 	 	 	 dˆ fd„	Zdej
                  fˆ fd„Zˆ xZS )ÚSplitBatchNorm2dc	                 óþ   •— ||dœ}	t         ‰| �  |||||«       |dkD  sJ d«       ‚|| _        t        j                  t        |dz
  «      D �
cg c]  }
t        j                  |||||fi |	¤Ž‘Œ c}
«      | _        y c c}
w )N)ÚdeviceÚdtypeé   z=Should have at least one aux BN layer (num_splits at least 2))ÚsuperÚ__init__Ú
num_splitsÚnnÚ
ModuleListÚrangeÚBatchNorm2dÚaux_bn)ÚselfÚnum_featuresÚepsÚmomentumÚaffineÚtrack_running_statsr   r   r   ÚddÚ_Ú	__class__s              €úf/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/timm/layers/split_batchnorm.pyr
   zSplitBatchNorm2d.__init__   sŠ   ø€ ð ¨Ñ/ˆÜ‰Ñ˜ s¨H°fÐ>QÔRØ˜AŠ~Ð^Ð^Ó^ˆ~Ø$ˆŒÜ—m‘mä˜:¨™>Ó*ö%
àô �N‰N˜<¨¨h¸Ð@SÑZÐWYÓZò%
ó ˆ�ùò %
s   Á!A:Úinputc                 ó¨  •— | j                   r·|j                  d   | j                  z  }|j                  d   || j                  z  k(  sJ d«       ‚|j                  |«      }t        ‰| �  |d   «      g}t        | j                  «      D ]"  \  }}|j                   |||dz      «      «       Œ$ t        j                  |d¬«      S t        ‰| �  |«      S )Nr   z1batch size must be evenly divisible by num_splitsr   )Údim)ÚtrainingÚshaper   Úsplitr	   ÚforwardÚ	enumerater   ÚappendÚtorchÚcat)r   r   Ú
split_sizeÚsplit_inputÚxÚiÚar   s          €r   r!   zSplitBatchNorm2d.forward(   s¾   ø€ Ø�=Š=ØŸ™ Q™¨4¯?©?Ñ:ˆJØ—;‘;˜q‘> Z°$·/±/Ñ%AÒAÐvÐCvÓvÐAØŸ+™+ jÓ1ˆKÜ‘‘ ¨Q¡Ó0Ð1ˆAÜ! $§+¡+Ó.ò 0‘��1Ø—‘™˜; q¨1¡uÑ-Ó.Õ/ð0ä—9‘9˜Q AÔ&Ð&ä‘7‘? 5Ó)Ð)ó    )gñhãˆµøä>gš™™™™™¹?TTé   NN)Ú__name__Ú
__module__Ú__qualname__r
   r$   ÚTensorr!   Ú__classcell__)r   s   @r   r   r      s4   ø„ ð
 ØØØ $ØØØõð(
*˜UŸ\™\÷ 
*ñ 
*r+   r   c                 ó^  — | }t        | t        j                  j                  j                  j
                  «      r| S t        | t        j                  j                  j                  j                  «      �rt        | j                  | j                  | j                  | j                  | j                  |¬«      }| j                  |_        | j                  |_        | j                   |_        | j                  r‚| j"                  j$                  j'                  «       j)                  «       |j"                  _        | j*                  j$                  j'                  «       j)                  «       |j*                  _        |j,                  D ]î  }| j                  j'                  «       |_        | j                  j'                  «       |_        | j                   j'                  «       |_        | j                  sŒm| j"                  j$                  j'                  «       j)                  «       |j"                  _        | j*                  j$                  j'                  «       j)                  «       |j*                  _        Œð | j/                  «       D ]"  \  }}|j1                  |t3        ||¬«      «       Œ$ ~ |S )a¯  
    Recursively traverse module and its children to replace all instances of
    ``torch.nn.modules.batchnorm._BatchNorm`` with `SplitBatchnorm2d`.
    Args:
        module (torch.nn.Module): input module
        num_splits: number of separate batchnorm layers to split input across
    Example::
        >>> # model is an instance of torch.nn.Module
        >>> model = timm.models.convert_splitbn_model(model, num_splits=2)
    )r   )Ú
isinstancer$   r   ÚmodulesÚinstancenormÚ_InstanceNormÚ	batchnormÚ
_BatchNormr   r   r   r   r   r   Úrunning_meanÚrunning_varÚnum_batches_trackedÚweightÚdataÚcloneÚdetachÚbiasr   Únamed_childrenÚ
add_moduleÚconvert_splitbn_model)Úmoduler   ÚmodÚauxÚnameÚchilds         r   rC   rC   5   sê  € ð €CÜ�&œ%Ÿ(™(×*Ñ*×7Ñ7×EÑEÔFØˆÜ�&œ%Ÿ(™(×*Ñ*×4Ñ4×?Ñ?Õ@ÜØ×Ñ §¡¨V¯_©_¸f¿m¹mØ×&Ñ&°:ô?ˆð "×.Ñ.ˆÔØ ×,Ñ,ˆŒØ"(×"<Ñ"<ˆÔØ�=Š=Ø$Ÿm™m×0Ñ0×6Ñ6Ó8×?Ñ?ÓAˆC�J‰JŒOØ"ŸK™K×,Ñ,×2Ñ2Ó4×;Ñ;Ó=ˆC�H‰HŒMØ—:‘:ò 	BˆCØ%×2Ñ2×8Ñ8Ó:ˆCÔØ$×0Ñ0×6Ñ6Ó8ˆCŒOØ&,×&@Ñ&@×&FÑ&FÓ&HˆCÔ#Ø�}‹}Ø"(§-¡-×"4Ñ"4×":Ñ":Ó"<×"CÑ"CÓ"E�—
‘
”Ø &§¡× 0Ñ 0× 6Ñ 6Ó 8× ?Ñ ?Ó A�—‘•ð	Bð ×,Ñ,Ó.ò R‰ˆˆeØ�‰�tÔ2°5ÀZÔPÕQðRàØ€Jr+   )r,   )Ú__doc__r$   Útorch.nnr   r   r   rC   © r+   r   ú<module>rL      s.   ðñó Ý ô *�u—x‘x×+Ñ+ô  *ôF"r+   