
    NgF)                        d Z ddlZddlmZ ddlZddlmZ ddlmZm	Z	m
Z
mZmZ ddlmZ d Zefd	Zd
 Zd Zd Z G d d          Zg dfdZg ddfdZg dfdZg dfdZddej        j        dej        j        fdZdS )zM Model / 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                     t          | t                    rt          | j                  S t	          | d          rt          | j                  S t	          | d          rt          | j                  S | S )Nmodule	_orig_mod)
isinstancer   unwrap_modelemahasattrr   r   )models    L/var/www/html/ai-engine/env/lib/python3.11/site-packages/timm/utils/model.pyr   r      sm    %"" EI&&&5(## 	---UK(( 	000L    c                 <     ||                                            S N)
state_dict)r   	unwrap_fns     r   get_state_dictr      s    9U&&(((r   c                     t          j        |                    g d          dz                                            S )zA calculate average channel square mean of output activations
    r         axisr   )torchmeanitemr   inputoutputs      r   avg_sq_ch_meanr(       s7     :fkkyyyk11Q677<<>>>r   c                 z    t          j        |                    g d                                                    S z> calculate average channel variance of output activations
    r   r    r"   r#   varr$   r%   s      r   
avg_ch_varr-   &   2     :fjjiiij001166888r   c                 z    t          j        |                    g d                                                    S r*   r+   r%   s      r   avg_ch_var_residualr0   ,   r.   r   c                   $    e Zd ZdZd Zd Zd ZdS )ActivationStatsHooka  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 Propogation Plots using `ActivationStatsHook`.
    c                 "   || _         || _        || _        t          |          t          |          k    rt	          d          t          d |D                       | _        t          ||          D ]\  }}|                     ||           d S )Nz_Please provide `hook_fns` for each `hook_fn_locs`,                 their lengths are different.c              3   (   K   | ]}|j         g fV  d S r   )__name__).0hook_fns     r   	<genexpr>z/ActivationStatsHook.__init__.<locals>.<genexpr>K   s*      IIW7+R0IIIIIIr   )	r   hook_fn_locshook_fnslen
ValueErrordictstatszipregister_hook)selfr   r9   r:   hook_fn_locr7   s         r   __init__zActivationStatsHook.__init__D   s    
( |H-- . / / /IIIIIII
$'h$?$? 	5 	5 K{G4444	5 	5r   c                       fd}|S )Nc                 l     | ||          }j         j                                     |           d S r   )r>   r5   append)r   r&   r'   outr7   rA   s       r   append_activation_statszAActivationStatsHook._create_hook.<locals>.append_activation_statsP   s:    '&%00CJw'(//44444r    )rA   r7   rH   s   `` r   _create_hookz ActivationStatsHook._create_hookO   s*    	5 	5 	5 	5 	5 	5 '&r   c                     | j                                         D ]C\  }}t          j        ||          s|                    |                     |                     Dd S r   )r   named_modulesfnmatchregister_forward_hookrJ   )rA   rB   r7   namer   s        r   r@   z!ActivationStatsHook.register_hookV   sm     J4466 	E 	ELD&?455 (():):7)C)CDDDD	E 	Er   N)r5   
__module____qualname____doc__rC   rJ   r@   rI   r   r   r2   r2   2   sP         "	5 	5 	5' ' 'E E E E Er   r2   )   r      rT   c                 v    t          j        dd|          }t          | ||          } | |          }|j        S )a  Extract average square channel mean and variance of activations during 
    forward pass to plot Signal Propogation Plots (SPP).
    
    Paper: https://arxiv.org/abs/2101.08692

    Example Usage: https://gist.github.com/amaarora/6e56942fcb46e67ba203f3009b30d950
    g        g      ?)r9   r:   )r"   normalr2   r>   )r   r9   r:   input_shapexhook_s          r   extract_spp_statsr[   ]   s@     	R[))Au<(SSSDaA:r   Tfreezec                 ~    |dv s
J d            t           t          j        j        j        j        t          j        j        j        j        t          t          f          rt          d          t          |t                    r|g}|} fd|D             }t          |          s+t          t                                                      \  }}t          ||          D ]\  }}|                                D ]}|dk    rdnd|_        |rd }|dk    rmt#          |          }	t          |t          j        j        j        j        t          j        j        j        j        t          t          f          r | ||	           t%          |          }	t          |t&          t(          f          r | ||	           d	S )
a4  
    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"`.
    )r\   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.c                 :    g | ]}                     |          S rI   )get_submodule)r6   mroot_modules     r   
<listcomp>z$_freeze_unfreeze.<locals>.<listcomp>   s'    CCC1+++A..CCCr   r\   FTc                     |                     dd          }t          |          dk    r7|                     |d                                       |d         |           d S |                     ||           d S )N.r   r   )rsplitr;   r`   
add_module)r   rO   	submodulesplits       r   _add_submodulez(_freeze_unfreeze.<locals>._add_submodule   sr    C++u::>>((q22==eAh	RRRRR%%dI66666r   N)r   r"   nnmodules	batchnormBatchNorm2dSyncBatchNormr   r   AssertionErrorstrr;   listr?   named_children
parametersrequires_gradr	   r
   r   r   )
rb   
submodulesinclude_bn_running_statsmoderL   nra   prj   ress
   `         r   _freeze_unfreezer|   o   s    ))))+Y)))+H&2H&4	    	m lm m 	m *c"" " \
MCCCC
CCCJz?? M$(k.H.H.J.J)K$L$L!zM:.. 8 81 	B 	BA'+x'7'7eeTAOO# 	87 7 7 x*1-- a(2>(2@&(	"   8 #N;3777 -Q//a"35I!JKK 8"N;3777?8 8r   c                 ,    t          | ||d           dS )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)
    r\   rw   rx   Nr|   rb   rv   rw   s      r   r\   r\      s#    > [*G_fnoooooor   c                 ,    t          | ||d           dS )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`.
    r^   r~   Nr   r   s      r   r^   r^      s#     [*G_fpqqqqqqr   Fr   returnc                 J    |st          |           } fd |            | S )Nc                 L   |                                  D ]\  }}t          |d          r$t          | ||                                           nIt          |d          r|                                 n$t          |d          r|                                  |           d S )Nfusereparameterizeswitch_to_deploy)rs   r   setattrr   r   r   )ra   
child_namechild_fuses      r   r   z#reparameterize_model.<locals>._fuse   s    !"!1!1!3!3 	 	Juf%% ):uzz||4444 011 )$$&&&& 233 )&&(((E%LLLL	 	r   r   )r   inplacer   s     @r   reparameterize_modelr      sC           
E%LLLLr   )F)rR   rM   copyr   r"   torchvision.ops.miscr   timm.layersr   r   r   r	   r
   	model_emar   r   r   r(   r-   r0   r2   r[   r|   r\   r^   rk   Moduler   rI   r   r   <module>r      s            2 2 2 2 2 21 1 1 1 1 1 1 1 1 1 1 1 1 1      	 	 	 %1 ) ) ) )? ? ?9 9 99 9 9(E (E (E (E (E (E (E (E^ %$$	   $ .0$U] B8 B8 B8 B8J $& p p p pD &($ r r r r   58?      r   