U
    ¯Ê¹jð  ã                   @   st   d Z ddlZddlmZ ddlm  mZ ddlmZm	Z	 ddl
m
Z
 ddlmZ ddlmZ G d	d
„ d
ejƒZdS )aã   Gather-Excite Attention Block

Paper: `Gather-Excite: Exploiting Feature Context in CNNs` - https://arxiv.org/abs/1810.12348

Official code here, but it's only partial impl in Caffe: https://github.com/hujie-frank/GENet

I've tried to support all of the extent both w/ and w/o params. I don't believe I've seen another
impl that covers all of the cases.

NOTE: extent=0 + extra_params=False is equivalent to Squeeze-and-Excitation

Hacked together by / Copyright 2021 Ross Wightman
é    N)Únné   )Úcreate_act_layerÚget_act_layer)Úcreate_conv2d)Úmake_divisible)ÚConvMlpc                       sD   e Zd ZdZddddddddejejdf‡ fd	d
„	Zdd„ Z‡  Z	S )ÚGatherExcitez$ Gather-Excite Attention Module
    NFr   Tg      °?r   Zsigmoidc                    s®  t t| ƒ ¡  |	| _t|
ƒ}
|| _|�r t ¡ | _|dkr€|d k	sJt	dƒ‚| j 
dt|||ddd�¡ |r~| j 
dt |¡¡ nž|d dks�t	‚tt |¡ƒ}t|ƒD ]v}| j 
d	|d › �t||d
ddd�¡ |rò| j 
d|d › �t |¡¡ ||d kr¦| j 
d|d › �|
dd�¡ q¦nJd | _| jdk�r@d| _d| _n*|d dk�sRt	‚| jd d | _| j| _|�s‚t|| |dd�}|�r–t|||
d�nt ¡ | _t|ƒ| _d S )Nr   zBspatial feature size must be specified for global extent w/ paramsZconv1r   T)Úkernel_sizeÚstrideZ	depthwiseZnorm1é   Úconvé   ZnormZact)Zinplaceg        )Zround_limit)Ú	act_layer)Úsuperr	   Ú__init__Úadd_maxpoolr   Úextentr   Z
SequentialÚgatherÚAssertionErrorZ
add_moduler   ÚBatchNorm2dÚintÚmathÚlog2ÚrangeÚgkÚgsr   r   ZIdentityÚmlpr   Úgate)ÚselfZchannelsZ	feat_sizeZextra_paramsr   Zuse_mlpZrd_ratioZrd_channelsZ
rd_divisorr   r   Z
norm_layerZ
gate_layerZnum_convÚi©Ú	__class__© úX/var/www/html/bwave/python/venv/lib/python3.8/site-packages/timm/layers/gather_excite.pyr      sH    
 ÿþ"zGatherExcite.__init__c                 C   sì   |j dd … }| jd k	r$|  |¡}n†| jdkr^|jddd�}| jrªd| d|jddd�  }nLtj|| j| j	| jd d	d
�}| jrªd| dtj
|| j| j	| jd d�  }|  |¡}|j d dksÐ|j d dkrÞtj||d�}||  |¡ S )Néþÿÿÿr   )r   r   T)ÚdimZkeepdimsg      à?)Zkeepdimr   F)r
   r   ÚpaddingZcount_include_pad)r
   r   r'   éÿÿÿÿr   )Úsize)Úshaper   r   Zmeanr   ZamaxÚFZ
avg_pool2dr   r   Z
max_pool2dr   Zinterpolater   )r   Úxr)   Zx_ger#   r#   r$   ÚforwardF   s(    

    ÿ(
zGatherExcite.forward)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ZReLUr   r   r-   Ú__classcell__r#   r#   r!   r$   r	      s           ý*r	   )r1   r   Ztorchr   Ztorch.nn.functionalZ
functionalr+   Z
create_actr   r   r   Zhelpersr   r   r   ÚModuler	   r#   r#   r#   r$   Ú<module>   s   