o
    پiJ                     @   s   d Z ddlZddlmZ ddlmZ ddlmZ ddlm	Z	 ddl
mZ G d	d
 d
ejZG dd dejZG dd dejZdS )aw   Bilinear-Attention-Transform and Non-Local Attention

Paper: `Non-Local Neural Networks With Grouped Bilinear Attentional Transforms`
    - https://openaccess.thecvf.com/content_CVPR_2020/html/Chi_Non-Local_Neural_Networks_With_Grouped_Bilinear_Attentional_Transforms_CVPR_2020_paper.html
Adapted from original code: https://github.com/BA-Transform/BAT-Image-Classification
    N)nn)
functional   )ConvNormAct)make_divisible)_assertc                       s2   e Zd ZdZd fdd	Zdd	 Zd
d Z  ZS )NonLocalAttnzSpatial NL block for image classification.

    This was adapted from https://github.com/BA-Transform/BAT-Image-Classification
    Their NonLocal impl inspired by https://github.com/facebookresearch/video-nonlocal-net.
    T      ?N   c                    s   t t|   |d u rt|| |d}|r|d nd| _tj||dddd| _tj||dddd| _tj||dddd| _	tj||dddd| _
t|| _|   d S )Ndivisorg      g      ?r   T)kernel_sizestridebias)superr   __init__r   scaler   Conv2dtpgzBatchNorm2dnormreset_parameters)selfin_channels	use_scalerd_ratiord_channels
rd_divisorkwargs	__class__ N/home/ubuntu/.local/lib/python3.10/site-packages/timm/layers/non_local_attn.pyr      s   zNonLocalAttn.__init__c                 C   s   |}|  |}| |}| |}| \}}}}	|||dddd}|||d}|||dddd}t||| j }
t	j
|
dd}
t|
|}|ddd||||	}| |}| || }|S )Nr      r   dim)r   r   r   sizeviewpermutetorchbmmr   Fsoftmaxreshaper   r   )r   xshortcutr   r   r   BCHWattr$   r$   r%   forward#   s   



zNonLocalAttn.forwardc                 C   s   |   D ]T\}}t|tjr+tjj|jddd tt|	 dkr*tj
|jd qt|tjrBtj
|jd tj
|jd qt|tjrXtj
|jd tj
|jd qd S )Nfan_outrelu)modenonlinearityr   g        r   )named_modules
isinstancer   r   initkaiming_normal_weightlenlist
parameters	constant_r   r   	GroupNorm)r   namemr$   r$   r%   r   9   s    zNonLocalAttn.reset_parameters)Tr	   Nr
   )__name__
__module____qualname____doc__r   r9   r   __classcell__r$   r$   r"   r%   r      s
    r   c                       s<   e Zd Zejejf fdd	ZdefddZdd Z	  Z
S )BilinearAttnTransformc                    s   t t|   t||d||d| _tj||| | |dfd| _tj||| | d|fd| _t||d||d| _	|| _
|| _|| _d S )Nr   	act_layer
norm_layer)r   )r   rO   r   r   conv1r   r   conv_pconv_qconv2
block_sizegroupsr   )r   r   rW   rX   rQ   rR   r"   r$   r%   r   J   s   
zBilinearAttnTransform.__init__r   c                 C   s   |j \}}}}t||kd |dkr|S ||| ddd}|tj|||j|jd }||| ||||}tjtj|ddddd}tjtj|ddddd}||||| || }|S )	N r   r&   )dtypedevicer(      r'      )	shaper   r+   r-   eyerZ   r[   catsplit)r   r2   r   r4   r5   rW   block_size1r$   r$   r%   
resize_matU   s   z BilinearAttnTransform.resize_matc                 C   s  t |jd | j dkd t |jd | j dkd |j\}}}}| |}t|| jdf}t|d| jf}| ||| j| j| j	 }	| 
||| j| j| j	 }
|	|	jddd }	|
|
jd	dd }
|	|| jd| j| j|d| j|| j | j| j }	|	||| j| j}	|
|| jd| j| j|d| j|| j | j| j }
|
||| j| j}
| |	|| j }	| |
|| j }
|	|}||
}| |}|S )
Nr&   r   rY   r   r\   T)r)   keepdimr'   )r   r^   rW   rS   r/   adaptive_max_pool2drT   r+   rX   sigmoidrU   sumexpandr*   
contiguousrc   matmulrV   )r   r2   r4   r5   r6   r7   outrpcpr   qyr$   r$   r%   r9   b   s@   
  


zBilinearAttnTransform.forward)rJ   rK   rL   r   ReLUr   r   intrc   r9   rN   r$   r$   r"   r%   rO   H   s    rO   c                       s>   e Zd ZdZddddddejejf fdd		Zd
d Z  Z	S )BatNonLocalAttnzT BAT
    Adapted from: https://github.com/BA-Transform/BAT-Image-Classification
       r'   g      ?Nr
   g?c
                    sp   t    |d u rt|| |d}t||d||	d| _t|||||	d| _t||d||	d| _tj	|d| _
d S )Nr   r   rP   )r   )r   r   r   r   rS   rO   barV   r   	Dropout2ddropout)r   r   rW   rX   r   r   r    	drop_raterQ   rR   _r"   r$   r%   r      s   
zBatNonLocalAttn.__init__c                 C   s0   |  |}| |}| |}| |}|| S )N)rS   ru   rV   rw   )r   r2   xlrp   r$   r$   r%   r9      s
   



zBatNonLocalAttn.forward)
rJ   rK   rL   rM   r   rq   r   r   r9   rN   r$   r$   r"   r%   rs   |   s    

rs   )rM   r-   r   torch.nnr   r/   conv_bn_actr   helpersr   trace_utilsr   Moduler   rO   rs   r$   r$   r$   r%   <module>   s    84