Ë
    éÓ^jÊ  ã                   óÐ   — d Z ddlmZmZmZ ddlZddlmZ ddlmc m	Z
 ddlmZmZ ddlmZ ddlmZ dee   fd	„Z G d
„ dej(                  «      Z G d„ dej(                  «      Zy)aP   Bottleneck Self Attention (Bottleneck Transformers)

Paper: `Bottleneck Transformers for Visual Recognition` - https://arxiv.org/abs/2101.11605

@misc{2101.11605,
Author = {Aravind Srinivas and Tsung-Yi Lin and Niki Parmar and Jonathon Shlens and Pieter Abbeel and Ashish Vaswani},
Title = {Bottleneck Transformers for Visual Recognition},
Year = {2021},
}

Based on ref gist at: https://gist.github.com/aravindsrinivas/56359b79f0ce4449bcb04ab4b56a57a2

This impl is a WIP but given that it is based on the ref gist likely not too far off.

Hacked together by / Copyright 2021 Ross Wightman
é    )ÚListÚOptionalÚTupleNé   )Ú	to_2tupleÚmake_divisible)Útrunc_normal_)Ú_assertÚpermute_maskc                 óÐ  — | j                   \  }}}}| |j                  dd«      z  }|j                  d|d|z  dz
  «      }t        j                  |ddg«      j                  d«      }t        j                  |d|dz
  g«      }|j                  d|dz   d|z  dz
  «      }|dd…d|…|dz
  d…f   }|j                  ||d||«      j                  dd|dd«      }|j                  |«      S )a„   Compute relative logits along one dimension

    As per: https://gist.github.com/aravindsrinivas/56359b79f0ce4449bcb04ab4b56a57a2
    Originally from: `Attention Augmented Convolutional Networks` - https://arxiv.org/abs/1904.09925

    Args:
        q: (batch, heads, height, width, dim)
        rel_k: (2 * width - 1, dim)
        permute_mask: permute output dim according to this
    éÿÿÿÿéþÿÿÿé   r   r   N)ÚshapeÚ	transposeÚreshapeÚFÚpadÚflattenÚexpandÚpermute)	ÚqÚrel_kr   ÚBÚHÚWÚdimÚxÚx_pads	            úf/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/timm/layers/bottleneck_attn.pyÚrel_logits_1dr!      sñ   € ð —7‘7�L€A€qˆ!ˆSØ	
ˆU�_‰_˜R Ó$Ñ	$€AØ	�	‰	�"�a˜˜Q™ ™Ó"€Aô �E‰E�!�a˜�VÓ×$Ñ$ QÓ'€EÜ�E‰E�%˜!˜Q ™U˜Ó$€Eð �M‰M˜"˜a !™e Q¨¡U¨Q¡YÓ/€EØŠa��!��Q˜‘U‘VˆmÑ€Að 	
�	‰	�!�Q˜˜1˜aÓ ×'Ñ'¨¨B°°2°rÓ:€AØ�9‰9�\Ó"Ð"ó    c                   óL   ‡ — e Zd ZdZ	 	 ddeeef   dedefˆ fd„Zd„ Zd„ Z	ˆ xZ
S )	ÚPosEmbedRelzÛ Relative Position Embedding
    As per: https://gist.github.com/aravindsrinivas/56359b79f0ce4449bcb04ab4b56a57a2
    Originally from: `Attention Augmented Convolutional Networks` - https://arxiv.org/abs/1904.09925
    Ú	feat_sizeÚdim_headÚscalec                 ó”  •— ||dœ}t         ‰| �  «        t        |«      \  | _        | _        || _        || _        t        j                  t        j                  | j                  dz  dz
  |fi |¤Ž«      | _        t        j                  t        j                  | j                  dz  dz
  |fi |¤Ž«      | _        | j                  «        y )N©ÚdeviceÚdtyper   r   )ÚsuperÚ__init__r   ÚheightÚwidthr&   r'   ÚnnÚ	ParameterÚtorchÚemptyÚ
height_relÚ	width_relÚreset_parameters)Úselfr%   r&   r'   r*   r+   ÚddÚ	__class__s          €r    r-   zPosEmbedRel.__init__=   s£   ø€ ð ¨Ñ/ˆÜ‰ÑÔÜ"+¨IÓ"6ÑˆŒ�T”ZØ ˆŒØˆŒ
äŸ,™,¤u§{¡{°4·;±;À±?ÀQÑ3FÈÑ'WÐTVÑ'WÓXˆŒÜŸ™¤e§k¡k°$·*±*¸q±.À1Ñ2DÀhÑ&UÐRTÑ&UÓVˆŒà×ÑÕr"   c                 ó   — t         j                  j                  j                  | j                  | j
                  ¬«       t         j                  j                  j                  | j                  | j
                  ¬«       y )N©Ústd)r2   r0   ÚinitÚnormal_r4   r'   r5   ©r7   s    r    r6   zPosEmbedRel.reset_parametersP   sH   € Ü�‰�‰×Ñ˜dŸo™o°4·:±:ÐÔ>Ü�‰�‰×Ñ˜dŸn™n°$·*±*ÐÕ=r"   c                 ó*  — |j                   \  }}}|j                  || j                  | j                  d«      }t	        || j
                  d¬«      }|j                  dd«      }t	        || j                  d¬«      }||z   }|j                  |||«      }|S )Nr   )r   r   é   r   é   )r   r   r   )r   rA   r   rB   r   )r   r   r.   r/   r!   r5   r   r4   )r7   r   r   ÚHWÚ_Úrel_logits_wÚrel_logits_hÚ
rel_logitss           r    ÚforwardzPosEmbedRel.forwardT   s‰   € Ø—7‘7‰ˆˆ2ˆqð �I‰I�a˜Ÿ™ d§j¡j°"Ó5ˆÜ$ Q¨¯©À_ÔUˆð �K‰K˜˜1ÓˆÜ$ Q¨¯©ÀoÔVˆà! LÑ0ˆ
Ø×'Ñ'¨¨2¨rÓ2ˆ
ØÐr"   )NN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ÚintÚfloatr-   r6   rH   Ú__classcell__©r9   s   @r    r$   r$   8   sC   ø„ ñð Øñ à˜S #˜X‘ð ð ð ð õ	 ò&>ör"   r$   c                   ó†   ‡ — e Zd ZdZ	 	 	 	 	 	 	 	 	 	 ddedee   deeeef      dededee   ded	ed
efˆ fd„Z	d„ Z
d„ Zˆ xZS )ÚBottleneckAttna†   Bottleneck Attention
    Paper: `Bottleneck Transformers for Visual Recognition` - https://arxiv.org/abs/2101.11605

    The internal dimensions of the attention module are controlled by the interaction of several arguments.
      * the output dimension of the module is specified by dim_out, which falls back to input dim if not set
      * the value (v) dimension is set to dim_out // num_heads, the v projection determines the output dim
      * the query and key (qk) dimensions are determined by
        * num_heads * dim_head if dim_head is not None
        * num_heads * (dim_out * attn_ratio // num_heads) if dim_head is None
      * as seen above, attn_ratio determines the ratio of q and k relative to the output if dim_head not used

    Args:
        dim (int): input dimension to the module
        dim_out (int): output dimension of the module, same as dim if not set
        stride (int): output stride of the module, avg pool used if stride == 2 (default: 1).
        num_heads (int): parallel attention heads (default: 4)
        dim_head (int): dimension of query and key heads, calculated from dim_out * attn_ratio // num_heads if not set
        qk_ratio (float): ratio of q and k dimensions to output dimension when dim_head not set. (default: 1.0)
        qkv_bias (bool): add bias to q, k, and v projections
        scale_pos_embed (bool): scale the position embedding as well as Q @ K
    r   Údim_outr%   ÚstrideÚ	num_headsr&   Úqk_ratioÚqkv_biasÚscale_pos_embedc                 óœ  •— |
|dœ}t         ‰| �  «        |€J d«       ‚|xs |}||z  dk(  sJ ‚|| _        |xs t        ||z  d¬«      |z  | _        || j                  z  | _        || j                  z  | _        || j
                  z  | _        | j                  dz  | _        |	| _	        t        j                  || j                  dz  | j                  z   dfd	|i|¤Ž| _        t        |f| j                  | j                  d
œ|¤Ž| _        |dk(  rt        j                  dd«      nt        j                   «       | _        | j%                  «        y )Nr)   zBA concrete feature size matching expected input (H, W) is requiredr   é   )Údivisorç      à¿r   r   Úbias)r&   r'   )r,   r-   rU   r   Údim_head_qkÚ
dim_head_vÚ
dim_out_qkÚ	dim_out_vr'   rX   r0   ÚConv2dÚqkvr$   Ú	pos_embedÚ	AvgPool2dÚIdentityÚpoolr6   )r7   r   rS   r%   rT   rU   r&   rV   rW   rX   r*   r+   r8   r9   s                €r    r-   zBottleneckAttn.__init__z   sA  ø€ ð ¨Ñ/ˆÜ‰ÑÔØÐ$ÐjÐ&jÓjÐ$Ø’.˜SˆØ˜Ñ" aÒ'Ð'Ð'Ø"ˆŒØ#Òa¤~°gÀÑ6HÐRSÔ'TÐXaÑ'aˆÔØ! T§^¡^Ñ3ˆŒØ# d×&6Ñ&6Ñ6ˆŒØ" T§_¡_Ñ4ˆŒØ×%Ñ%¨Ñ-ˆŒ
Ø.ˆÔä—9‘9˜S $§/¡/°AÑ"5¸¿¹Ñ"FÈÑ_ÐPXÐ_Ð\^Ñ_ˆŒô % YÐb¸×9IÑ9IÐQU×Q[ÑQ[ÑbÐ_aÑbˆŒà*0°Aª+”B—L‘L  AÔ&¼2¿;¹;»=ˆŒ	à×ÑÕr"   c                 ó:  — t        | j                  j                  | j                  j                  j                  d   dz  ¬«       t        | j                  j
                  | j                  ¬«       t        | j                  j                  | j                  ¬«       y )Nr   r\   r;   )r	   rc   Úweightr   rd   r4   r'   r5   r?   s    r    r6   zBottleneckAttn.reset_parametersž   s\   € Ü�d—h‘h—o‘o¨4¯8©8¯?©?×+@Ñ+@ÀÑ+CÀtÑ+KÕLÜ�d—n‘n×/Ñ/°T·Z±ZÕ@Ü�d—n‘n×.Ñ.°D·J±JÖ?r"   c                 óÞ  — |j                   \  }}}}t        || j                  j                  k(  d«       t        || j                  j                  k(  d«       | j                  |«      }t        j                  || j                  | j                  | j                  gd¬«      \  }}}|j                  || j                  z  | j                  d«      j                  dd«      }|j                  || j                  z  | j                  d«      }|j                  || j                  z  | j                  d«      j                  dd«      }| j                  r%||z  | j                  |«      z   | j                   z  }	n$||z  | j                   z  | j                  |«      z   }	|	j#                  d¬«      }	|	|z  j                  dd«      j                  || j                  ||«      }
| j%                  |
«      }
|
S )NÚ r   )r   r   r   )r   r
   rd   r.   r/   rc   r2   Úsplitr`   ra   r   rU   r^   r   r_   rX   r'   Úsoftmaxrg   )r7   r   r   ÚCr   r   r   ÚkÚvÚattnÚouts              r    rH   zBottleneckAttn.forward£   s‘  € Ø—W‘W‰
ˆˆ1ˆa�Ü��T—^‘^×*Ñ*Ñ*¨BÔ/Ü��T—^‘^×)Ñ)Ñ)¨2Ô.à�H‰H�Q‹Kˆô —+‘+˜a $§/¡/°4·?±?ÀDÇNÁNÐ!SÐYZÔ[‰ˆˆ1ˆaØ�I‰I�a˜$Ÿ.™.Ñ(¨$×*:Ñ*:¸BÓ?×IÑIÈ"ÈbÓQˆØ�I‰I�a˜$Ÿ.™.Ñ(¨$×*:Ñ*:¸BÓ?ˆØ�I‰I�a˜$Ÿ.™.Ñ(¨$¯/©/¸2Ó>×HÑHÈÈRÓPˆà×ÒØ˜‘E˜DŸN™N¨1Ó-Ñ-°·±Ñ;‰Dà˜‘E˜TŸZ™ZÑ'¨$¯.©.¸Ó*;Ñ;ˆDØ�|‰| ˆ|Ó#ˆà�a‰x×"Ñ" 2 rÓ*×2Ñ2°1°d·n±nÀaÈÓKˆØ�i‰i˜‹nˆØˆ
r"   )
NNr   rB   Ng      ð?FFNN)rI   rJ   rK   rL   rM   r   r   rN   Úboolr-   r6   rH   rO   rP   s   @r    rR   rR   d   s¦   ø„ ñð0 &*Ø37ØØØ&*Ø!Ø"Ø$)ØØñ" àð" ð ˜c‘]ð" ð    c¨3 h¡Ñ0ð	" ð
 ð" ð ð" ð ˜s‘mð" ð ð" ð ð" ð "õ" òH@ö
r"   rR   )rL   Útypingr   r   r   r2   Útorch.nnr0   Útorch.nn.functionalÚ
functionalr   Úhelpersr   r   Úweight_initr	   Útrace_utilsr
   rM   r!   ÚModuler$   rR   © r"   r    ú<module>r}      sZ   ðñ÷  )Ñ (ã Ý ß Ð ç .Ý &Ý  ð#¨$¨s©)ó #ô8)�"—)‘)ô )ôXU�R—Y‘Yõ Ur"   