
    NgLM                     ,   d Z ddlmZ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ZddlmZ ddlmZ ddlmZmZ g d	Z	 	 d#dedeeee
e         f                  dedee
e         ef         fdZdeeeedf         f         deedf         fdZeeeedf         f         Z G d d          Z G d d          Zd$dZdefdZ d Z! G d dej"                  Z# G d de#          Z$ G d d ej"                  Z% G d! d"ej"                  Z&dS )%a   PyTorch Feature Extraction Helpers

A collection of classes, functions, modules to help extract features from models
and provide a common interface for describing them.

The return_layers, module re-writing idea inspired by torchvision IntermediateLayerGetter
https://github.com/pytorch/vision/blob/d88d8961ae51507d0cb680329d985b1488b1b76b/torchvision/models/_utils.py

Hacked together by / Copyright 2020 Ross Wightman
    )OrderedDictdefaultdict)deepcopy)partial)DictListOptionalSequenceTupleUnionN)
checkpoint)Format_assert)FeatureInfoFeatureHooksFeatureDictNetFeatureListNetFeatureHookNetFeatureGetterNetfeature_take_indicesFnum_featuresindicesas_setreturnc           	           t          t                    rBt          dcxk     o k    nc d d  d            fdt                    D             }nQg }D ]L}|dk     r |z   n|}t          d|cxk    o k     nc d| d d	z
   d           |                    |           Mt
          j                                        s |rt          |          t          |          fS |t          |          fS )
aB   Determine the absolute feature indices to 'take' from.

    Note: This function can be called in forwar() so must be torchscript compatible,
    which requires some incomplete typing and workaround hacks.

    Args:
        num_features: total number of features to select from
        indices: indices to select,
          None -> select all
          int -> select last n
          list/tuple of int -> return specified (-ve indices specify from end)
        as_set: return as a set

    Returns:
        List (or set) of absolute (from beginning) indices, Maximum index
    Nr   zlast-n (z) is out of range (1 to )c                      g | ]
}z
  |z   S  r   ).0ir   r   s     Q/var/www/html/ai-engine/env/lib/python3.11/site-packages/timm/models/_features.py
<listcomp>z(feature_take_indices.<locals>.<listcomp>8   s#    KKKqw.2KKK    zfeature index z is out of range (0 to    )

isinstanceintr   rangeappendtorchjitis_scriptingsetmax)r   r   r   take_indicesr    idxs   ``    r!   r   r      s[   * '3 	%G++++|++++-h-h-hYe-h-h-hiiiKKKKKE'NNKKK"$ 	% 	%A&'!ee,""CA++++|++++-mc-m-mZfijZj-m-m-mnnn$$$$9!!## 4 4<  #l"3"333\****r#   x.c                     t          | t                    rt          t          |  d                    S t          |           S )Nr   )r%   r&   tupler'   )r0   s    r!   _out_indices_as_tupler3   F   s7    !S #UA2q\\"""88Or#   c            	       p   e Zd Zdee         defdZdefdZddede	e
eee         f                  fdZdd	e	ee                  de	e
eee         f                  fd
Zdde	e
eee         f                  fdZdde	e
eee         f                  fdZdde	e
eee         f                  fdZd Zd ZdS )r   feature_infoout_indicesc                     t          |          }d}t          |          D ]M\  }}d|v r|d         dk    sJ d|v r|d         |k    sJ |d         }d|v sJ |                    d|           N|| _        || _        d S )Nr$   num_chsr   	reductionmoduleindex)r3   	enumerate
setdefaultr6   info)selfr5   r6   prev_reductionr    fis         r!   __init__zFeatureInfo.__init__R   s    
 ,K88|,, 	& 	&EAr??r)}q'8'8'8'8"$$KN)J)J)J)J_Nr>>>>MM'1%%%%& 			r#   c                 d    t          |          }t          t          | j                  |          S N)r3   r   r   r>   )r?   r6   s     r!   
from_otherzFeatureInfo.from_otherc   s)    +K888DI..<<<r#   Nkeyr/   c                      | fd j         D             S t          |t          t          f          r fd|D             S  j        |                  S )a:   Get value by key at specified index (indices)
        if idx == None, returns value for key at each output index
        if idx is an integer, return value for that feature module index (ignoring output indices)
        if idx is a list/tuple, return value for each module index (ignoring output indices)
        Nc                 6    g | ]}j         |                  S r   r>   r   r    rF   r?   s     r!   r"   z#FeatureInfo.get.<locals>.<listcomp>n   s$    @@@!DIaL%@@@r#   c                 6    g | ]}j         |                  S r   rI   rJ   s     r!   r"   z#FeatureInfo.get.<locals>.<listcomp>p   s$    333!DIaL%333r#   r6   r%   r2   listr>   )r?   rF   r/   s   `` r!   getzFeatureInfo.getg   so     ;@@@@@t/?@@@@cE4=)) 	'33333s33339S>#&&r#   keysc                      ) fd j         D             S  fd j         D             S t          t          t          f          r fdD             S  j                 n fdD             S )zm return info dicts for specified keys (or all if None) at specified indices (or out_indices if None)
        Nc                 *    g | ]}j         |         S r   rI   )r   r    r?   s     r!   r"   z)FeatureInfo.get_dicts.<locals>.<listcomp>y   s    ???	!???r#   c                 0    g | ]fd D             S )c                 8    i | ]}|j                  |         S r   rI   r   kr    r?   s     r!   
<dictcomp>z4FeatureInfo.get_dicts.<locals>.<listcomp>.<dictcomp>{   s%    :::DIaLO:::r#   r   r   r    rO   r?   s    @r!   r"   z)FeatureInfo.get_dicts.<locals>.<listcomp>{   s2    UUUq:::::T:::UUUr#   c                 N    g | ] j                  nfdD             !S )Nc                 8    i | ]}|j                  |         S r   rI   rT   s     r!   rV   z4FeatureInfo.get_dicts.<locals>.<listcomp>.<dictcomp>}   s%    6X6X6Xaq$)A,q/6X6X6Xr#   rI   rW   s    @r!   r"   z)FeatureInfo.get_dicts.<locals>.<listcomp>}   sB    fff]^DLDIaLL6X6X6X6X6XSW6X6X6Xfffr#   c                 8    i | ]}|j                  |         S r   rI   )r   rU   r/   r?   s     r!   rV   z)FeatureInfo.get_dicts.<locals>.<dictcomp>   s'    7[7[7[QR49S>!;L7[7[7[r#   rL   )r?   rO   r/   s   ```r!   	get_dictszFeatureInfo.get_dictst   s     ;|????d.>????UUUUUDDTUUUUcE4=)) 	\fffffbeffff%)\49S>>7[7[7[7[7[VZ7[7[7[[r#   c                 .    |                      d|          S )z# feature channels accessor
        r8   rN   r?   r/   s     r!   channelszFeatureInfo.channels   s     xx	3'''r#   c                 .    |                      d|          S )z4 feature reduction (output stride) accessor
        r9   r]   r^   s     r!   r9   zFeatureInfo.reduction   s     xxS)))r#   c                 .    |                      d|          S )z& feature module name accessor
        r:   r]   r^   s     r!   module_namezFeatureInfo.module_name   s     xx#&&&r#   c                     | j         |         S rD   rI   )r?   items     r!   __getitem__zFeatureInfo.__getitem__   s    yr#   c                 *    t          | j                  S rD   )lenr>   )r?   s    r!   __len__zFeatureInfo.__len__   s    49~~r#   rD   )NN)__name__
__module____qualname__r   r   OutIndicesTrB   rE   strr	   r   r&   rN   r[   r_   r9   rb   re   rh   r   r#   r!   r   r   P   s       !t*! %! ! ! !"=k = = = =' 's '%T#Y*?!@ ' ' ' '\ \htCy1 \xcSWX[S\nH]?^ \ \ \ \( (HU3S	>%:; ( ( ( (
* *XeCcN&;< * * * *
' 'xc49n(=> ' ' ' '
      r#   r   c            
           e Zd ZdZ	 	 ddeeeef                  dedeee	ef                  defdZ
d	 Zd
eeej        f         fdZdS )r   z Feature Hook Helper

    This module helps with the setup and extraction of hooks for extracting features from
    internal nodes in a model by node name.

    FIXME This works well in eager Python but needs redesign for torchscript.
    Nforwardhooksnamed_modulesout_mapdefault_hook_typec                 *   t          t                    | _        g | _        d |D             }t	          |          D ]\  }}t          |t                    r|n|d         }||         }	|r||         n|}
t          | j        |
          }|}t          |t                    r|
                    d|          }|dk    r|	                    |          }n&|dk    r|	                    |          }n
J d            | j                            |           d S )Nc                     i | ]\  }}||	S r   r   )r   rU   vs      r!   rV   z)FeatureHooks.__init__.<locals>.<dictcomp>   s    222DAq1a222r#   r:   	hook_typeforward_prero   FzUnsupported hook type)r   r   _feature_outputs_handlesr<   r%   rm   r   _collect_output_hookdictrN   register_forward_pre_hookregister_forward_hookr(   )r?   rp   rq   rr   rs   modulesr    h	hook_namemhook_idhook_fnrw   handles                 r!   rB   zFeatureHooks.__init__   s1    !,K 8 822M222e$$ 	) 	)DAq'3//@Qx[I	"A$+:gajjGd7AAG)I!T"" BEE+/@AA	M))44W==i''009955555M  ((((	) 	)r#   c                 z    |d         }t          |t                    r|d         }|| j        |j                 |<   d S )Nr   )r%   r2   ry   device)r?   r   argsr0   s       r!   r{   z!FeatureHooks._collect_output_hook   s@    Ha 	!A34ah'000r#   r   c                 L    | j         |         }t                      | j         |<   |S rD   )ry   r   )r?   r   outputs      r!   
get_outputzFeatureHooks.get_output   s%    &v.(3f%r#   )Nro   )ri   rj   rk   __doc__r
   r   rm   r   r|   r&   rB   r{   r)   tensorr   r   r#   r!   r   r      s          26%.) )E#t),-)  ) eCHo.	)
  #) ) ) )65 5 5Del):$;      r#   r   c                 `   g }|                                  D ]\  }} |rwt          | t          j                  r]|                                  D ]G\  }}||g}|                    d                    |          d                    |          |f           H~|                    ||| f           |S )N_.)named_childrenr%   nn
Sequentialr(   join)r:   flatten_sequentialmlname
child_namechild_modulecombineds          r!   _module_listr      s    	B--// , ,f 	,*VR]"C"C 	,,2,A,A,C,C R R(
L *-		388H--sxx/A/A<PQQQQR IItT6*++++Ir#   r6   c                     t          | d          }t          |t                    r|                    |          S t          |t          t
          f          rt          | j        |          S J d            )Nr5   Fz"Provided feature_info is not valid)getattrr%   r   rE   rM   r2   r5   )netr6   r5   s      r!   _get_feature_infor      so    3//L,,, ;&&{333	L4-	0	0 ;3+[999:::::r#   c                     |                                  }i }t          |          D ]\  }}|||         n| j        |         ||<    |S rD   )rb   r<   r6   )r5   rr   module_namesreturn_layersr    r   s         r!   _get_return_layersr      s^    ++--LM\** a a4,3,?gajj\E]^_E`dr#   c                        e Zd ZdZ	 	 	 	 	 ddej        dedeee	e
f                  d	e
d
edef fdZddefdZdee
ej        f         fdZdee
ej        f         fdZ xZS )r   a9   Feature extractor with OrderedDict return

    Wrap a model and extract features as specified by the out indices, the network is
    partially re-built from contained modules.

    There is a strong assumption that the modules have been registered into the model in the same
    order as they are used. There should be no reuse of the same nn.Module more than once, including
    trivial modules like `self.relu = nn.ReLU`.

    Only submodules that are directly assigned to the model class (`model.feature1`) or at most
    one Sequential container deep (`model.features.1`, with flatten_sequent=True) can be captured.
    All Sequential containers that are directly assigned to the original model will have their
    modules assigned to this module with the name `model.features.1` being changed to `model.features_1`
    r   r$            NNCHWFmodelr6   rr   
output_fmtfeature_concatr   c                    t          t          |                                            t          ||          | _        t          |          | _        || _        d| _        i | _	        t          | j        |          }t          ||          }t          |                                          }	t                      }
|D ]E\  }}}||
|<   ||	v r2t          ||                   | j	        |<   |	                    |           |	s nF|	s%t#          | j	                  t#          |          k    sJ d|	 d            |                     |
           dS )a  
        Args:
            model: Model from which to extract features.
            out_indices: Output indices of the model features to extract.
            out_map: Return id mapping for each output index, otherwise str(index) is used.
            feature_concat: Concatenate intermediate features that are lists or tuples instead of selecting
                first element e.g. `x[0]`
            flatten_sequential: Flatten first two-levels of sequential modules in model (re-writes model modules)
        Fr   Return layers () are not present in modelN)superr   rB   r   r5   r   r   concatgrad_checkpointingr   r   r   r,   rO   r   rm   removerg   update)r?   r   r6   rr   r   r   r   r   r   	remaininglayersnew_nameold_namer:   	__class__s                 r!   rB   zFeatureDictNet.__init__   sf   $ 	nd##,,...-e[AA ,,$"'*4+<gFFu9KLLL**,,--	*1 	 	&Hh%F89$$/2=3J/K/K"8,  ***  	DT%7!8!8C<N<N!N!N!NCiCCC "O!N!NFr#   Tenablec                     || _         d S rD   r   r?   r   s     r!   set_grad_checkpointingz%FeatureDictNet.set_grad_checkpointing      "(r#   r   c                 $   t                      }t          |                                           D ]\  }\  }}| j        rft          j                                        sH|dk    p#|t          t          |           dz
  d          k    }|r ||          nt          ||          }n ||          }|| j
        v rV| j
        |         }t          |t          t          f          r(| j        rt	          j        |d          n|d         ||<   |||<   |S Nr   r$   )r   r<   itemsr   r)   r*   r+   r-   rg   r   r   r%   r2   rM   r   cat)r?   r0   outr    r   r:   first_or_last_moduleout_ids           r!   _collectzFeatureDictNet._collect"  s   mm!*4::<<!8!8 	$ 	$A~f& uy/E/E/G/G  ()Av'Kc#d))a-6K6K1K$!5PFF1III:fa;P;PF1IIt)))+D1a%// $ 6:["J%)Aq///adCKK"#CK
r#   c                 ,    |                      |          S rD   )r   r?   r0   s     r!   ro   zFeatureDictNet.forward8  s    }}Qr#   )r   Nr   FFT)ri   rj   rk   r   r   Modulerl   r
   r   r&   rm   boolrB   r   r   r)   Tensorr   ro   __classcell__r   s   @r!   r   r      s        " (715$#(',' '9' %' eCHo.	'
 ' !' !%' ' ' ' ' 'R) )T ) ) ) )d3#45    , Del!23                r#   r   c                   n     e Zd ZdZ	 	 	 	 ddej        dededed	ef
 fd
Z	de
ej                 fdZ xZS )r   z Feature extractor with list return

    A specialization of FeatureDictNet that always returns features as a list (values() of dict).
    r   r   Fr   r6   r   r   r   c                 T    t                                          |||||           dS )a  
        Args:
            model: Model from which to extract features.
            out_indices: Output indices of the model features to extract.
            feature_concat: Concatenate intermediate features that are lists or tuples instead of selecting
                first element e.g. `x[0]`
            flatten_sequential: Flatten first two-levels of sequential modules in model (re-writes model modules)
        )r6   r   r   r   N)r   rB   )r?   r   r6   r   r   r   r   s         r!   rB   zFeatureListNet.__init__A  s?      	#!)1 	 	
 	
 	
 	
 	
r#   r   c                 j    t          |                     |                                                    S rD   )rM   r   valuesr   s     r!   ro   zFeatureListNet.forwardY  s(    DMM!$$++--...r#   )r   r   FF)ri   rj   rk   r   r   r   rl   rm   r   rB   r   r)   r   ro   r   r   s   @r!   r   r   <  s          (7$#(',
 
9
 %
 	

 !
 !%
 
 
 
 
 
0/T%,/ / / / / / / / /r#   r   c                        e Zd ZdZ	 	 	 	 	 	 	 ddej        ded	eee	e
ef                           d
ededee         dedef fdZddefdZd Z xZS )r   a   FeatureHookNet

    Wrap a model and extract features specified by the out indices using forward/forward-pre hooks.

    If `no_rewrite` is True, features are extracted via hooks without modifying the underlying
    network in any way.

    If `no_rewrite` is False, the model will be re-written as in the
    FeatureList/FeatureDict case by folding first to second (Sequential only) level modules into this one.

    FIXME this does not currently work with Torchscript, see FeatureHooks class
    r   NFr   ro   r   r6   rr   return_dictr   
no_rewriter   rs   c	           	         t                                                       t          j                                        rJ t          ||          | _        || _        t          |          | _	        d| _
        || }t                      }	g }
|r[|rJ t          |d          r|                    d           ||	d<   |
                    | j                                                   nt!          ||          }fd| j                                        D             }|D ]\\  }}}||	|<   |                    |          D ]6\  }}||v r-|
                    t'          |||         	                     ||= 7|s n]|rJ d
| d            |                     |	           t+          |
|                                |          | _        dS )a  

        Args:
            model: Model from which to extract features.
            out_indices: Output indices of the model features to extract.
            out_map: Return id mapping for each output index, otherwise str(index) is used.
            return_dict: Output features as a dict.
            no_rewrite: Enforce that model is not re-written if True, ie no modules are removed / changed.
                flatten_sequential arg must also be False if this is set True.
            flatten_sequential: Re-write modules by flattening first two levels of nn.Sequential containers.
            default_hook_type: The default hook type to use if not specified in model.feature_info.
        FNreset_classifierr   bodyr   c                 :    i | ]}|d          d|v r|d         nS r:   rw   r   )r   frs   s     r!   rV   z+FeatureHookNet.__init__.<locals>.<dictcomp>  sB        ({a/?/?Q{^^EV  r#   )prefixr   r   r   )rr   )r   rB   r)   r*   r+   r   r5   r   r   r   r   r   hasattrr   extendr[   r   rq   r(   r|   r   r   rp   )r?   r   r6   rr   r   r   r   r   rs   r   rp   r   r   r   r   r:   fnfmr   s           `         r!   rB   zFeatureHookNet.__init__j  s   . 	9))+++++-e[AA& ,,"'//J 	Z))))u011 *&&q)))"F6NLL*44667777"5=OPPPG   *4466  I /6  *(F#)x $22(2CC * *FBYTy}%M%M%MNNN%bM  E YY"YI"Y"Y"YYYYF!%)<)<)>)>PPP


r#   Tr   c                     || _         d S rD   r   r   s     r!   r   z%FeatureHookNet.set_grad_checkpointing  r   r#   c                    t          |                                           D ]\  }\  }}| j        rft          j                                        sH|dk    p#|t          t          |           dz
  d          k    }|r ||          nt          ||          }u ||          }| j	        
                    |j                  }| j        r|n t          |                                          S r   )r<   r   r   r)   r*   r+   r-   rg   r   rp   r   r   r   rM   r   )r?   r0   r    r   r:   r   r   s          r!   ro   zFeatureHookNet.forward  s    !*4::<<!8!8 	 	A~f& uy/E/E/G/G  ()Av'Kc#d))a-6K6K1K$!5PFF1III:fa;P;PF1IIj##AH--&>ssD,>,>>r#   )r   NFr   NFro   r   )ri   rj   rk   r   r   r   rl   r	   r
   r   r&   rm   r   rB   r   ro   r   r   s   @r!   r   r   ]  s         (7;? %$)-',%.7Q 7Q97Q %7Q huS#X78	7Q
 7Q 7Q !7Q !%7Q  #7Q 7Q 7Q 7Q 7Q 7Qr) )T ) ) ) )? ? ? ? ? ? ?r#   r   c                        e Zd ZdZ	 	 	 	 	 	 ddej        ded	eee	e
ef                           d
edededef fdZd Z xZS )r   ze FeatureGetterNet

    Wrap models with a feature getter method, like 'get_intermediate_layers'

    r   NFr   Tr   r6   rr   r   r   normprunec                 4   t                                                       |r(t          |d          r|                    ||           }t	          ||          | _        || _        || _        || _        || _	        t          |          | _        || _        dS )an  

        Args:
            model: Model to wrap.
            out_indices: Indices of features to extract.
            out_map: Remap feature names for dict output (WIP, not supported).
            return_dict: Return features as dictionary instead of list (WIP, not supported).
            norm: Apply final model norm to all output features (if possible).
        prune_intermediate_layers)
prune_normN)r   rB   r   r   r   r5   r   r6   rr   r   r   r   r   )	r?   r   r6   rr   r   r   r   r   r   s	           r!   rB   zFeatureGetterNet.__init__  s    & 	 	WU$?@@ 	99#8 :  K .e[AA
&& ,,			r#   c                 b    | j                             || j        | j        | j        d          }|S )NT)r   r   r   intermediates_only)r   forward_intermediatesr6   r   r   )r?   r0   featuress      r!   ro   zFeatureGetterNet.forward  s;    :33$# 4 
 
 r#   )r   NFr   FT)ri   rj   rk   r   r   r   rl   r	   r
   r   r&   rm   r   rB   ro   r   r   s   @r!   r   r     s          ();? %$   9  %  huS#X78	 
                  D      r#   r   )NF)F)'r   collectionsr   r   copyr   	functoolsr   typingr   r   r	   r
   r   r   r)   torch.nnr   torch.utils.checkpointr   timm.layersr   r   __all__r&   r   r   r3   rl   r   r   r   r   r   
ModuleDictr   r   r   r   r   r#   r!   <module>r      s  	 	 1 0 0 0 0 0 0 0             ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?        - - - - - - ' ' ' ' ' ' ' '   48&+ &+&+%T#Y/0&+ &+ 49c>	&+ &+ &+ &+RU3c3h#78 U38_     CsCx()D D D D D D D DN- - - - - - - -`   ; ; ; ; ;  R  R  R  R  R R] R  R  R j/ / / / /^ / / /BT? T? T? T? T?R] T? T? T?n0 0 0 0 0r} 0 0 0 0 0r#   