o
    hD                     @   s^  d Z ddlZddlZddlmZ ddlmZmZmZ er"ddl	m
Z
 G dd dejZd	eee  d
eee  deee  fddZd	eee  d
eeee ee f  dee fddZd	eee  d
eeee ee f  dee deee ee f fddZG dd dZG dd dZdd Zdededee deeedf  dee f
dd ZdS )!zACollection of utils to be used by backbones and their components.    N)Iterable)TYPE_CHECKINGOptionalUnion   )PretrainedConfigc                   @   s   e Zd ZdZdZdS )BackboneTypetimmtransformersN)__name__
__module____qualname__TIMMTRANSFORMERS r   r   u/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/transformers/utils/backbone_utils.pyr      s    r   out_featuresout_indicesstage_namesc                    s  du rt d durXt tfst dt  tfdd D r0t d d  t tt krAt d    fd	d
D  }krXt d| d  |durt|tsjt dt| tfdd|D }tfdd|D rt d d| t|tt|krd| }|||krd| dnd7 }t ||tt|krdd
 tt	||dd dD }t d| d|  dur|durt t|krt d fdd
|D krt ddS dS dS )zW
    Verify that out_indices and out_features are valid for the given stage_names.
    Nz2Stage_names must be set for transformers backbonesz out_features must be a list got c                 3   s    | ]}| vV  qd S Nr   .0featr   r   r   	<genexpr>,   s    z2verify_out_features_out_indices.<locals>.<genexpr>z.out_features must be a subset of stage_names: z got z2out_features must not contain any duplicates, got c                    s   g | ]}| v r|qS r   r   r   r   r   r   
<listcomp>0   s    z3verify_out_features_out_indices.<locals>.<listcomp>z@out_features must be in the same order as stage_names, expected z out_indices must be a list, got c                 3   s(    | ]}|d k r|t   n|V  qdS )r   Nlenr   idxr   r   r   r   9   s   & c                 3   s$    | ]}|t t vr|V  qd S r   )ranger   r   r   r   r   r   :   s   " z2out_indices must be valid indices for stage_names z, got z1out_indices must not contain any duplicates, got z(equivalent to z)) c                 S   s   g | ]\}}|qS r   r   )r   _r    r   r   r   r   A       c                 S   s   | d S )Nr   r   )xr   r   r   <lambda>A   s    z1verify_out_features_out_indices.<locals>.<lambda>)keyz?out_indices must be in the same order as stage_names, expected zHout_features and out_indices should have the same length if both are setc                       g | ]} | qS r   r   r   r   r   r   r   I   r$   zQout_features and out_indices should correspond to the same stages if both are set)

ValueError
isinstancelisttypeanyr   settuplesortedzip)r   r   r   sorted_featspositive_indicesmsgsorted_negativer   )r   r   r   verify_out_features_out_indices    sF   

 r6   c                    s   |du r| du rt  d g} d g} | |fS |du r-| dur- fdd| D }| |fS | du r>|dur> fdd|D } | |fS )a  
    Finds the corresponding `out_features` and `out_indices` for the given `stage_names`.

    The logic is as follows:
        - `out_features` not set, `out_indices` set: `out_features` is set to the `out_features` corresponding to the
        `out_indices`.
        - `out_indices` not set, `out_features` set: `out_indices` is set to the `out_indices` corresponding to the
        `out_features`.
        - `out_indices` and `out_features` not set: `out_indices` and `out_features` are set to the last stage.
        - `out_indices` and `out_features` set: input `out_indices` and `out_features` are returned.

    Args:
        out_features (`List[str]`): The names of the features for the backbone to output.
        out_indices (`List[int]` or `Tuple[int]`): The indices of the features for the backbone to output.
        stage_names (`List[str]`): The names of the stages of the backbone.
    N   c                    s   g | ]}  |qS r   )index)r   layerr   r   r   r   f       z9_align_output_features_output_indices.<locals>.<listcomp>c                    r(   r   r   r   r   r   r   r   h   r$   r   r   r   r   r   r   r   %_align_output_features_output_indicesM   s   
r=   returnc                 C   sJ   |durt |nd}t| ||d t| ||d\}}t|||d ||fS )a`  
    Get the `out_features` and `out_indices` so that they are aligned.

    The logic is as follows:
        - `out_features` not set, `out_indices` set: `out_features` is set to the `out_features` corresponding to the
        `out_indices`.
        - `out_indices` not set, `out_features` set: `out_indices` is set to the `out_indices` corresponding to the
        `out_features`.
        - `out_indices` and `out_features` not set: `out_indices` and `out_features` are set to the last stage.
        - `out_indices` and `out_features` set: they are verified to be aligned.

    Args:
        out_features (`List[str]`): The names of the features for the backbone to output.
        out_indices (`List[int]` or `Tuple[int]`): The indices of the features for the backbone to output.
        stage_names (`List[str]`): The names of the stages of the backbone.
    Nr<   )r+   r6   r=   )r   r   r   output_featuresoutput_indicesr   r   r   *get_aligned_output_features_output_indicesl   s   
rA   c                       s   e Zd ZU dZee ed< dddZdddZddd	Z	e
d
d Zejdee fddZe
dd Zejdeee ee f fddZe
dd Ze
dd Zdd Z			d dee dee dee fddZ fddZ  ZS )!BackboneMixinNbackbone_typer>   c                 C   s   t | dddu rtddd | jjjD | _dd | jjjD | _t| jjj}| jj	 }t
||| jd ||| _| _dS )zo
        Initialize the backbone model from timm The backbone must already be loaded to self._backbone
        	_backboneNz=self._backbone must be set before calling _init_timm_backbonec                 S      g | ]}|d  qS )moduler   r   stager   r   r   r      r$   z5BackboneMixin._init_timm_backbone.<locals>.<listcomp>c                 S   rE   )num_chsr   rG   r   r   r   r      r$   r<   )getattrr)   rD   feature_infoinfor   num_featuresr+   r   module_namer6   _out_features_out_indices)selfconfigr   r   r   r   r   _init_timm_backbone   s   z!BackboneMixin._init_timm_backbonec                 C   sH   t |d}t |dd }t |dd }|| _t|||d\| _| _d | _d S )Nr   r   r   r<   )rJ   r   rA   rO   rP   rM   )rQ   rR   r   r   r   r   r   r   _init_transformers_backbone   s   

z)BackboneMixin._init_transformers_backbonec                 C   sn   || _ t|dd| _| jrtjntj| _| jtjkr!| | dS | jtjkr.| | dS t	d| j d)z
        Method to initialize the backbone. This method is called by the constructor of the base class after the
        pretrained model weights have been loaded.
        use_timm_backboneFzbackbone_type z not supported.N)
rR   rJ   rU   r   r   r   rC   rS   rT   r)   )rQ   rR   r   r   r   _init_backbone   s   zBackboneMixin._init_backbonec                 C      | j S r   rO   rQ   r   r   r   r         zBackboneMixin.out_featuresr   c                 C      t |d| jd\| _| _dS z
        Set the out_features attribute. This will also update the out_indices attribute to match the new out_features.
        Nr<   rA   r   rO   rP   rQ   r   r   r   r   r         c                 C   rW   r   rP   rY   r   r   r   r      rZ   zBackboneMixin.out_indicesr   c                 C      t d|| jd\| _| _dS z
        Set the out_indices attribute. This will also update the out_features attribute to match the new out_indices.
        Nr<   r]   rQ   r   r   r   r   r      r_   c                    s    fddt  jD S )Nc                    s   i | ]
\}}| j | qS r   )rM   )r   irH   rY   r   r   
<dictcomp>   s    z6BackboneMixin.out_feature_channels.<locals>.<dictcomp>)	enumerater   rY   r   rY   r   out_feature_channels   s   z"BackboneMixin.out_feature_channelsc                    s    fdd j D S )Nc                    s   g | ]} j | qS r   )rg   )r   namerY   r   r   r      r;   z*BackboneMixin.channels.<locals>.<listcomp>r   rY   r   rY   r   channels   s   zBackboneMixin.channelsc                    s6   t t| jj  fdd| D }| |i |S )Nc                    s   i | ]\}}| v r||qS r   r   )r   kv	signaturer   r   re      s    z>BackboneMixin.forward_with_filtered_kwargs.<locals>.<dictcomp>)dictinspectrm   forward
parametersitems)rQ   argskwargsfiltered_kwargsr   rl   r   forward_with_filtered_kwargs   s   z*BackboneMixin.forward_with_filtered_kwargsoutput_hidden_statesoutput_attentionsreturn_dictc                 C   s   t d)Nz7This method should be implemented by the derived class.)NotImplementedError)rQ   pixel_valuesrw   rx   ry   r   r   r   rp      s   zBackboneMixin.forwardc                    *   t   }|d|d< |d|d< |S z
        Serializes this instance to a Python dictionary. Override the default `to_dict()` from `PretrainedConfig` to
        include the `out_features` and `out_indices` attributes.
        rO   r   rP   r   superto_dictpoprQ   output	__class__r   r   r         
zBackboneMixin.to_dict)r>   N)NNN)r   r   r   rC   r   r   __annotations__rS   rT   rV   propertyr   setterr+   strr   r   r/   intrg   ri   rv   boolrp   r   __classcell__r   r   r   r   rB      s:   
 




 


	rB   c                       st   e Zd ZdZedd Zejdee fddZedd Z	e	jde
ee ee f fd	dZ	 fd
dZ  ZS )BackboneConfigMixinzv
    A Mixin to support handling the `out_features` and `out_indices` attributes for the backbone configurations.
    c                 C   rW   r   rX   rY   r   r   r   r     rZ   z BackboneConfigMixin.out_featuresr   c                 C   r[   r\   r]   r^   r   r   r   r   
  r_   c                 C   rW   r   r`   rY   r   r   r   r     rZ   zBackboneConfigMixin.out_indicesr   c                 C   ra   rb   r]   rc   r   r   r   r     r_   c                    r|   r}   r~   r   r   r   r   r      r   zBackboneConfigMixin.to_dict)r   r   r   __doc__r   r   r   r+   r   r   r   r/   r   r   r   r   r   r   r   r     s    

 r   c           	      C   s`  ddl m}m} t| dd}t| dd}t| dd}t| dd}t| dd}|du r,i n|}|r8|dur8td	|durH|durH|durHtd
|du rb|du rb|du rb|du rb|jdd| i|S |rz|du rltd|j|f||d|}|S |r|du rtd|j|fi |}|S |du r|du rtd|du r|j|fi |}|j|d}|S )a>  
    Loads the backbone model from a config object.

    If the config is from the backbone model itself, then we return a backbone model with randomly initialized
    weights.

    If the config is from the parent model of the backbone model itself, then we load the pretrained backbone weights
    if specified.
    r   )AutoBackbone
AutoConfigbackbone_configNrU   use_pretrained_backbonebackbonebackbone_kwargs?You can't specify both `backbone_kwargs` and `backbone_config`.z>Cannot specify both config.backbone_config and config.backbonerR   z8config.backbone must be set if use_timm_backbone is True)rU   r   z>config.backbone must be set if use_pretrained_backbone is Truez<Either config.backbone_config or config.backbone must be set)rR   r   )r
   r   r   rJ   r)   from_configfrom_pretrained)	rR   r   r   r   rU   r   backbone_checkpointr   r   r   r   r   load_backbone+  sN   
r   rU   r   r   r   r   r   c                 C   sT   |dur|durt d|dur| rt d|dur$|r&|dur(t ddS dS dS )zR
    Verify that the config arguments to be passed to load_backbone are valid
    Nz8You can't specify both `backbone` and `backbone_config`.zAYou can't specify both `backbone_config` and `use_timm_backbone`.r   )r)   )rU   r   r   r   r   r   r   r    verify_backbone_config_argumentsh  s   
r   )r   enumro   collections.abcr   typingr   r   r   configuration_utilsr   Enumr   r   r   r6   r+   r/   r=   rA   rB   r   r   r   rn   r   r   r   r   r   <module>   sZ   



-



 u*=