U
    ¯Ê¹jF  ã                   @   sx   d Z ddl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 ddlmZ G dd	„ d	ejƒZG d
d„ dejƒZdS )a:   Attention Pool 2D

Implementations of 2D spatial feature pooling using multi-head attention instead of average pool.

Based on idea in CLIP by OpenAI, licensed Apache 2.0
https://github.com/openai/CLIP/blob/3b473b0e682c091a9e53623eebc1ca1657385717/clip/model.py

Hacked together by / Copyright 2021 Ross Wightman
é    )ÚUnionÚTupleNé   )Ú	to_2tuple)Úapply_rot_embedÚRotaryEmbedding)Útrunc_normal_c                       s8   e Zd ZdZd
eeeeedœ‡ fdd„Zdd	„ Z‡  ZS )ÚRotAttentionPool2daB   Attention based 2D feature pooling w/ rotary (relative) pos embedding.
    This is a multi-head attention based replacement for (spatial) average pooling in NN architectures.

    Adapted from the AttentionPool2d in CLIP w/ rotary embedding instead of learned embed.
    https://github.com/openai/CLIP/blob/3b473b0e682c091a9e53623eebc1ca1657385717/clip/model.py

    NOTE: While this impl does not require a fixed feature size, performance at differeing resolutions from
    train varies widely and falls off dramatically. I'm not sure if there is a way around this... -RW
    Né   T)Úin_featuresÚout_featuresÚ	embed_dimÚ	num_headsÚqkv_biasc                    sž   t ƒ  ¡  |p|}|p|}tj||d |d�| _t ||¡| _|| _|| dksTt‚|| | _| jd | _	t
| jƒ| _t| jj|d d� tj | jj¡ d S )Né   ©Úbiasr   ç      à¿©Zstd)ÚsuperÚ__init__ÚnnÚLinearÚqkvÚprojr   ÚAssertionErrorÚhead_dimÚscaler   Ú	pos_embedr   ÚweightÚinitÚzeros_r   )Úselfr   r   r   r   r   ©Ú	__class__© ú[/var/www/html/bwave/python/venv/lib/python3.8/site-packages/timm/layers/attention_pool2d.pyr      s    

zRotAttentionPool2d.__init__c                 C   sª  |j \}}}}|| }| |d|¡ ddd¡}tj|jddd�|gdd�}|  |¡ ||d d| j| j¡ ddddd	¡}|d |d |d   }}}	|d d …d d …d d…f |d d …d d …dd …f  }
}| j	 
||f¡\}}t|||ƒ}tj|
|gdd�}|d d …d d …d d…f |d d …d d …dd …f  }}t|||ƒ}tj||gdd�}|| d
d¡ | j }|jdd�}||	  dd¡ ||d d¡}|  |¡}|d d …df S )Néÿÿÿÿr   é   r   T©Zkeepdim©Údimr   r
   éþÿÿÿ)ÚshapeÚreshapeÚpermuteÚtorchÚcatÚmeanr   r   r   r   Z	get_embedr   Ú	transposer   Úsoftmaxr   )r"   ÚxÚBÚ_ÚHÚWÚNÚqÚkÚvZqcZsin_embZcos_embÚkcÚattnr%   r%   r&   Úforward4   s$    .66
zRotAttentionPool2d.forward)NNr
   T)	Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚintÚboolr   r@   Ú__classcell__r%   r%   r#   r&   r	      s       úúr	   c                       sJ   e Zd ZdZd
eeeeeef f eeeedœ‡ fdd„Zdd	„ Z	‡  Z
S )ÚAttentionPool2da©   Attention based 2D feature pooling w/ learned (absolute) pos embedding.
    This is a multi-head attention based replacement for (spatial) average pooling in NN architectures.

    It was based on impl in CLIP by OpenAI
    https://github.com/openai/CLIP/blob/3b473b0e682c091a9e53623eebc1ca1657385717/clip/model.py

    NOTE: This requires feature size upon construction and well prevent adaptive sizing of the network.
    Nr
   T)r   Ú	feat_sizer   r   r   r   c                    sÚ   t ƒ  ¡  |p|}|p|}|| dks*t‚t|ƒ| _tj||d |d�| _t ||¡| _|| _	|| | _
| j
d | _| jd | jd  }t t |d |¡¡| _t| j|d d� t| jj|d d� tj | jj¡ d S )Nr   r   r   r   r   r   )r   r   r   r   rI   r   r   r   r   r   r   r   Ú	Parameterr0   Zzerosr   r   r   r    r!   r   )r"   r   rI   r   r   r   r   Zspatial_dimr#   r%   r&   r   X   s    	


zAttentionPool2d.__init__c                 C   s*  |j \}}}}|| }| jd |ks(t‚| jd |ks:t‚| |d|¡ ddd¡}tj|jddd�|gdd�}|| j 	d¡ 
|j¡ }|  |¡ ||d d| j| j¡ ddddd	¡}|d |d |d   }}}	|| d
d¡ | j }
|
jdd�}
|
|	  dd¡ ||d d¡}|  |¡}|d d …df S )Nr   r   r'   r(   Tr)   r*   r   r
   r,   )r-   rI   r   r.   r/   r0   r1   r2   r   Z	unsqueezeÚtoZdtyper   r   r   r3   r   r4   r   )r"   r5   r6   r7   r8   r9   r:   r;   r<   r=   r?   r%   r%   r&   r@   s   s    .
zAttentionPool2d.forward)NNr
   T)rA   rB   rC   rD   rE   r   r   rF   r   r@   rG   r%   r%   r#   r&   rH   O   s       ùùrH   )rD   Útypingr   r   r0   Ztorch.nnr   Zhelpersr   Zpos_embed_sincosr   r   Zweight_initr   ÚModuler	   rH   r%   r%   r%   r&   Ú<module>   s   	;