Ë
    éÓ^jQ)  ã                   ó$  — 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j2                  j4                  dej2                  j4                  fd„Zy)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    ú[/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/timm/utils/model.pyr   r      sR   € Ü�%œÔ"Ü˜EŸI™IÓ&Ð&ä�5˜(Ô#Ü §¡Ó-Ð-Ü�U˜KÔ(Ü §¡Ó0Ð0àˆLó    c                 ó.   —  || «      j                  «       S ©N)Ú
state_dict)r   Ú	unwrap_fns     r   Úget_state_dictr      s   € Ù�UÓ×&Ñ&Ó(Ð(r   c                 ór   — t        j                  |j                  g d¢¬«      dz  «      j                  «       S )zA calculate average channel square mean of output activations
    ©r   é   é   ©Úaxisr   )ÚtorchÚmeanÚitem©r   ÚinputÚoutputs      r   Úavg_sq_ch_meanr(       s,   € ô �:‰:�f—k‘k¢y�kÓ1°QÑ6Ó7×<Ñ<Ó>Ð>r   c                 ól   — t        j                  |j                  g d¢¬«      «      j                  «       S ©z> calculate average channel variance of output activations
    r   r    ©r"   r#   Úvarr$   r%   s      r   Ú
avg_ch_varr-   &   ó'   € ô �:‰:�f—j‘j¢i�jÓ0Ó1×6Ñ6Ó8Ð8r   c                 ól   — t        j                  |j                  g d¢¬«      «      j                  «       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y)Ú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 Propagation Plots using `ActivationStatsHook`.
    c                 óì   — || _         || _        || _        t        |«      t        |«      k7  rt	        d«      ‚t        d„ |D «       «      | _        t        ||«      D ]  \  }}| j                  ||«       Œ y )Nz_Please provide `hook_fns` for each `hook_fn_locs`,                 their lengths are different.c              3   ó8   K  — | ]  }|j                   g f–— Œ y ­wr   )Ú__name__)Ú.0Úhook_fns     r   ú	<genexpr>z/ActivationStatsHook.__init__.<locals>.<genexpr>K   s   è ø€ ÒI°W˜7×+Ñ+¨RÔ0ÑIùs   ‚)	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   sx   € ØˆŒ
Ø(ˆÔØ ˆŒÜˆ|Ó¤ H£Ò-Üð .ó /ð /äÑIÀÔIÓIˆŒ
Ü$'¨°hÓ$?ò 	5Ñ ˆK˜Ø×Ñ˜{¨GÕ4ñ	5r   c                 ó   ‡ ‡— ˆˆ fd„}|S )Nc                 ój   •—  ‰| ||«      }‰j                   ‰j                     j                  |«       y r   )r>   r5   Úappend)r   r&   r'   Úoutr7   rA   s       €€r   Úappend_activation_statszAActivationStatsHook._create_hook.<locals>.append_activation_statsP   s.   ø€ Ù˜& %¨Ó0ˆCØ�J‰J�w×'Ñ'Ñ(×/Ñ/°Õ4r   © )rA   r7   rH   s   `` r   Ú_create_hookz ActivationStatsHook._create_hookO   s   ù€ õ	5ð 'Ð&r   c                 ó¶   — | j                   j                  «       D ]<  \  }}t        j                  ||«      sŒ|j                  | j	                  |«      «       Œ> y r   )r   Únamed_modulesÚfnmatchÚregister_forward_hookrJ   )rA   rB   r7   Únamer   s        r   r@   z!ActivationStatsHook.register_hookV   sN   € Ø ŸJ™J×4Ñ4Ó6ò 	E‰LˆD�&Ü—?‘? 4¨Ô5ØØ×(Ñ(¨×):Ñ):¸7Ó)CÕDñ	Er   N)r5   Ú
__module__Ú__qualname__Ú__doc__rC   rJ   r@   rI   r   r   r2   r2   2   s   „ ñò"	5ò'óEr   r2   )é   r   éà   rT   c                 ót   — t        j                  dd|«      }t        | ||¬«      } | |«      }|j                  S )a  Extract 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      ð?)r9   r:   )r"   Únormalr2   r>   )r   r9   r:   Úinput_shapeÚxÚhookÚ_s          r   Úextract_spp_statsr[   ]   s7   € ô 	�‰�R˜˜[Ó)€AÜ˜u°<È(ÔS€DÙˆ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}|}|D �cg c]  }| j                  |«      ‘Œ }}t        |«      s"t        t        | j                  «       Ž «      \  }}t        ||«      D ]æ  \  }}|j!                  «       D ]  }|dk(  rdnd|_        Œ |sŒ,d„ }|dk(  r‡t%        |«      }	t        |t        j                  j                  j                  j
                  t        j                  j                  j                  j                  t        t        f«      sŒ° || ||	«       Œ»t'        |«      }	t        |t(        t*        f«      sŒÝ || ||	«       Œè yc c}w )	a9  
    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"z£You 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.r\   FTc                 ó¸   — |j                  dd«      }t        |«      dkD  r(| j                  |d   «      j                  |d   |«       y | j                  ||«       y )Nú.r   r   )Úrsplitr;   Úget_submoduleÚ
add_module)r   rO   Ú	submoduleÚsplits       r   Ú_add_submodulez(_freeze_unfreeze.<locals>._add_submodule™   sP   € ØŸ™ C¨Ó+�Ü�u“: ’>Ø×(Ñ(¨¨q©Ó2×=Ñ=¸eÀA¹hÈ	ÕRà×%Ñ% d¨IÕ6r   N)r   r"   ÚnnÚmodulesÚ	batchnormÚBatchNorm2dÚSyncBatchNormr   r   ÚAssertionErrorÚstrrb   r;   Úlistr?   Únamed_childrenÚ
parametersÚrequires_gradr	   r
   r   r   )
Úroot_moduleÚ
submodulesÚinclude_bn_running_statsÚmoderL   ÚmÚnÚprf   Úress
             r   Ú_freeze_unfreezerz   o   s´  € ð Ð)Ñ)ÐYÐ+YÓYÐ)ä�+Ü�H‰H×Ñ×&Ñ&×2Ñ2Ü�H‰H×Ñ×&Ñ&×4Ñ4ÜÜð	 ô ô ðlómð 	mô �*œcÔ"Ø �\ˆ
à€MØ8BÖC°1�+×+Ñ+¨AÕ.ÐC€JÐCäˆzŒ?Ü$(¬¨k×.HÑ.HÓ.JÐ)KÓ$LÑ!ˆ�zä�M :Ó.ò 8‰ˆˆ1à—‘“ò 	BˆAØ'+¨xÒ'7™e¸TˆA�Oð	Bâ#ò7ð �xÒÜ*¨1Ó-�ô ˜aÜŸ™×(Ñ(×2Ñ2×>Ñ>ÜŸ™×(Ñ(×2Ñ2×@Ñ@Ü&Ü(ð	"õ ñ # ;°°3Õ7ô -¨QÓ/�ä˜aÔ"3Ô5IÐ!JÕKÙ" ;°°3Õ7ñ?8ùò Ds   Â Gc                 ó"   — t        | ||d¬«       y)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\   ©rt   ru   N©rz   ©rr   rs   rt   s      r   r\   r\   µ   s   € ô@ �[ *ÐG_ÐfnÖor   c                 ó"   — t        | ||d¬«       y)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Öqr   r   Úreturnc                 ó<   ‡— |st        | «      } ˆfd„Š ‰| «       | S )Nc                 ó  •— | j                  «       D ]n  \  }}t        |d«      rt        | ||j                  «       «       n9t        |d«      r|j	                  «        nt        |d«      r|j                  «         ‰|«       Œp y )NÚfuseÚreparameterizeÚswitch_to_deploy)ro   r   Úsetattrrƒ   r„   r…   )rv   Ú
child_nameÚchildÚ_fuses      €r   r‰   z#reparameterize_model.<locals>._fuseí   sq   ø€ Ø!"×!1Ñ!1Ó!3ò 	ÑˆJ˜Ü�u˜fÔ%Ü˜˜: u§z¡z£|Õ4Ü˜Ð 0Ô1Ø×$Ñ$Õ&Ü˜Ð 2Ô3Ø×&Ñ&Ô(Ù�%�Lñ	r   r   )r   Úinplacer‰   s     @r   Úreparameterize_modelr‹   é   s"   ø€ ÙÜ˜“ˆôñ 
ˆ%„LØ€Lr   )F)rR   rM   Úcopyr   r"   Útorchvision.ops.miscr   Útimm.layersr   r   r   r	   r
   Ú	model_emar   r   r   r(   r-   r0   r2   r[   rz   r\   r^   rg   ÚModuler‹   rI   r   r   ú<module>r‘      s©   ðñó Ý ã Ý 2÷1õ 1å ò	ð %1ó )ò?ò9ò9÷(Eñ (Eò^ %ó	ð$ .0È$ÐU]ó C8ðL $&Àó  pðF &(À$ó rñ" §¡§¡ð À5Ç8Á8Ç?Á?ô r   