
    RЦiQ)                     2   S r SSKrSSKJr  SSKrSSKJr  SSKJrJ	r	J
r
JrJr  SSKJr  S r\4S	 jrS
 rS rS r " S S5      r/ SQ4S jr/ SS4S jr/ S4S jr/ S4S jrSS\R2                  R4                  S\R2                  R4                  4S jjrg)zLModel / state_dict utils

Hacked together by / Copyright 2020 Ross Wightman
    Ndeepcopy)FrozenBatchNorm2d)BatchNormAct2dSyncBatchNormActFrozenBatchNormAct2dfreeze_batch_norm_2dunfreeze_batch_norm_2d   )ModelEmac                     [        U [        5      (       a  [        U R                  5      $ [	        U S5      (       a  [        U R
                  5      $ [	        U S5      (       a  [        U R                  5      $ U $ )Nmodule	_orig_mod)
isinstancer   unwrap_modelemahasattrr   r   )models    O/var/www/html/ai-image-ml/venv/lib/python3.13/site-packages/timm/utils/model.pyr   r      s[    %""EII&&5(##--UK((00L    c                 .    U" U 5      R                  5       $ N)
state_dict)r   	unwrap_fns     r   get_state_dictr      s    U&&((r   c                 n    [         R                  " UR                  / SQS9S-  5      R                  5       $ )z@calculate average channel square mean of output activations
    r         axisr   )torchmeanitemr   inputoutputs      r   avg_sq_ch_meanr(       s,     ::fkkyk1Q67<<>>r   c                 h    [         R                  " UR                  / SQS95      R                  5       $ z=calculate average channel variance of output activations
    r   r    r"   r#   varr$   r%   s      r   
avg_ch_varr-   &   '     ::fjjij016688r   c                 h    [         R                  " UR                  / SQS95      R                  5       $ r*   r+   r%   s      r   avg_ch_var_residualr0   ,   r.   r   c                   *    \ rS rSrSrS rS rS rSrg)ActivationStatsHook2   a  Iterates through each of `model`'s modules and matches modules using unix pattern 
matching based on `hook_fn_locs` and registers `hook_fn` to the module if there is 
a match. 

Arguments:
    model (nn.Module): model from which we will extract the activation stats
    hook_fn_locs (List[str]): List of `hook_fn` locations based on Unix type string 
        matching with the name of model's modules. 
    hook_fns (List[Callable]): List of hook functions to be registered at every
        module in `layer_names`.

Inspiration from https://docs.fast.ai/callback.hook.html.

Refer to https://gist.github.com/amaarora/6e56942fcb46e67ba203f3009b30d950 for an example 
on how to plot Signal Propagation Plots using `ActivationStatsHook`.
c                     Xl         X l        X0l        [        U5      [        U5      :w  a  [	        S5      e[        S U 5       5      U l        [        X#5       H  u  pEU R                  XE5        M     g )Nz_Please provide `hook_fns` for each `hook_fn_locs`,                 their lengths are different.c              3   <   #    U  H  oR                   / 4v   M     g 7fr   )__name__).0hook_fns     r   	<genexpr>/ActivationStatsHook.__init__.<locals>.<genexpr>K   s     IW++R0s   )	r   hook_fn_locshook_fnslen
ValueErrordictstatszipregister_hook)selfr   r;   r<   hook_fn_locr8   s         r   __init__ActivationStatsHook.__init__D   sh    
( |H- . / /III
$'$? K{4 %@r   c                    ^ ^ UU 4S jnU$ )Nc                 h   > T" XU5      nTR                   TR                     R                  U5        g r   )r@   r6   append)r   r&   r'   outr8   rC   s       r   append_activation_statsAActivationStatsHook._create_hook.<locals>.append_activation_statsP   s,    &0CJJw''(//4r    )rC   r8   rK   s   `` r   _create_hook ActivationStatsHook._create_hookO   s    	5 '&r   c                     U R                   R                  5        HB  u  p4[        R                  " X15      (       d  M"  UR                  U R	                  U5      5        MD     g r   )r   named_modulesfnmatchregister_forward_hookrN   )rC   rD   r8   namer   s        r   rB   !ActivationStatsHook.register_hookV   sF     JJ446LD??455(():):7)CD 7r   )r;   r<   r   r@   N)	r6   
__module____qualname____firstlineno____doc__rE   rN   rB   __static_attributes__rM   r   r   r2   r2   2   s    "	5'Er   r2   )   r      r\   c                 n    [         R                  " SSU5      n[        XUS9nU " U5      nUR                  $ )zExtract average square channel mean and variance of activations during 
    forward pass to plot Signal Propagation Plots (SPP).

Paper: https://arxiv.org/abs/2101.08692

Example Usage: https://gist.github.com/amaarora/6e56942fcb46e67ba203f3009b30d950
g        g      ?)r;   r<   )r"   normalr2   r@   )r   r;   r<   input_shapexhook_s          r   extract_spp_statsrc   ]   s5     	R[)Au(SDaA::r   Tfreezec                    US;   d   S5       e[        U [        R                  R                  R                  R
                  [        R                  R                  R                  R                  [        [        45      (       a  [        S5      e[        U[        5      (       a  U/nUnU Vs/ s H  oPR                  U5      PM     nn[        U5      (       d!  [        [        U R                  5       6 5      u  pA[        XA5       H  u  peUR!                  5        H  nUS:X  a  SOSUl        M     U(       d  M4  S nUS:X  a  [%        U5      n	[        U[        R                  R                  R                  R
                  [        R                  R                  R                  R                  [        [        45      (       a  U" XU	5        M  M  ['        U5      n	[        U[(        [*        45      (       d  M  U" XU	5        M     gs  snf )	a  
Freeze or unfreeze parameters of the specified modules and those of all their hierarchical descendants. This is
    done in place.

Args:
    root_module (nn.Module, optional): Root module relative to which the `submodules` are referenced.
    submodules (list[str]): List of modules for which the parameters will be (un)frozen. They are to be provided as
        named modules relative to the root module (accessible via `root_module.named_modules()`). An empty list
        means that the whole root module will be (un)frozen. Defaults to []
    include_bn_running_stats (bool): Whether to also (un)freeze the running statistics of batch norm 2d layers.
        Defaults to `True`.
    mode (bool): Whether to freeze ("freeze") or unfreeze ("unfreeze"). Defaults to `"freeze"`.
)rd   unfreezez,`mode` must be one of "freeze" or "unfreeze"zYou have provided a batch norm layer as the `root module`. Please use `timm.utils.model.freeze_batch_norm_2d` or `timm.utils.model.unfreeze_batch_norm_2d` instead.rd   FTc                     UR                  SS5      n[        U5      S:  a(  U R                  US   5      R                  US   U5        g U R                  X5        g )N.r   r   )rsplitr=   get_submodule
add_module)r   rT   	submodulesplits       r   _add_submodule(_freeze_unfreeze.<locals>._add_submodule   sN    C+u:>((q2==eAh	R%%d6r   N)r   r"   nnmodules	batchnormBatchNorm2dSyncBatchNormr   r   AssertionErrorstrrj   r=   listrA   named_children
parametersrequires_gradr	   r
   r   r   )
root_module
submodulesinclude_bn_running_statsmoderQ   mnprn   ress
             r   _freeze_unfreezer   o   s    ))Y+YY)+HH&&22HH&&44	    lm 	m *c"" \
M8BC
1++A.
JCz??$(k.H.H.J)K$L!M.A'+x'7eTAO  ##7 x*1- a((22>>((22@@&(	"   #;37 -Q/a"35I!JKK";37? / Ds   ,Hc                     [        XUSS9  g)a:  
Freeze parameters of the specified modules and those of all their hierarchical descendants. This is done in place.

Args:
    root_module (nn.Module): Root module relative to which `submodules` are referenced.
    submodules (list[str]): List of modules for which the parameters will be frozen. They are to be provided as
        named modules relative to the root module (accessible via `root_module.named_modules()`). An empty list
        means that the whole root module will be frozen. Defaults to `[]`.
    include_bn_running_stats (bool): Whether to also freeze the running statistics of `BatchNorm2d` and
        `SyncBatchNorm` layers. These will be converted to `FrozenBatchNorm2d` in place. Hint: During fine tuning,
        it's good practice to freeze batch norm stats. And note that these are different to the affine parameters
        which are just normal PyTorch parameters. Defaults to `True`.

Hint: If you want to freeze batch norm ONLY, use `timm.utils.model.freeze_batch_norm_2d`.

Examples::

    >>> model = timm.create_model('resnet18')
    >>> # Freeze up to and including layer2
    >>> submodules = [n for n, _ in model.named_children()]
    >>> print(submodules)
    ['conv1', 'bn1', 'act1', 'maxpool', 'layer1', 'layer2', 'layer3', 'layer4', 'global_pool', 'fc']
    >>> freeze(model, submodules[:submodules.index('layer2') + 1])
    >>> # Check for yourself that it works as expected
    >>> print(model.layer2[0].conv1.weight.requires_grad)
    False
    >>> print(model.layer3[0].conv1.weight.requires_grad)
    True
    >>> # Unfreeze
    >>> unfreeze(model)
rd   r}   r~   Nr   r{   r|   r}   s      r   rd   rd      s    @ [G_fnor   c                     [        XUSS9  g)a  
Unfreeze parameters of the specified modules and those of all their hierarchical descendants. This is done in place.

Args:
    root_module (nn.Module): Root module relative to which `submodules` are referenced.
    submodules (list[str]): List of submodules for which the parameters will be (un)frozen. They are to be provided
        as named modules relative to the root module (accessible via `root_module.named_modules()`). An empty
        list means that the whole root module will be unfrozen. Defaults to `[]`.
    include_bn_running_stats (bool): Whether to also unfreeze the running statistics of `FrozenBatchNorm2d` layers.
        These will be converted to `BatchNorm2d` in place. Defaults to `True`.

See example in docstring for `freeze`.
rf   r   Nr   r   s      r   rf   rf      s     [G_fpqr   r   returnc                 H   ^ U(       d  [        U 5      n U4S jmT" U 5        U $ )Nc                 &  > U R                  5        H|  u  p[        US5      (       a  [        XUR                  5       5        OC[        US5      (       a  UR	                  5         O![        US5      (       a  UR                  5         T" U5        M~     g )Nfusereparameterizeswitch_to_deploy)rx   r   setattrr   r   r   )r   
child_namechild_fuses      r   r   #reparameterize_model.<locals>._fuse   sq    !"!1!1!3Juf%%uzz|4 011$$& 233&&(%L "4r   r   )r   inplacer   s     @r   reparameterize_modelr      s"     
%LLr   )F)rY   rR   copyr   r"   torchvision.ops.miscr   timm.layersr   r   r   r	   r
   	model_emar   r   r   r(   r-   r0   r2   rc   r   rd   rf   rp   Moduler   rM   r   r   <module>r      s       21 1 	 %1 )?99(E (E^ %	$ .0$U] C8L $&  pF &($ r" 588?? r   