U
    ¯Ê¹j=  ã                   @   s¨   d Z ddlZddlmZ ddlm  mZ ddlmZ de	e
e	eeed	œd
d„Zdeje	e
e	eedœdd„ZG dd„ dejƒZde	eedœdd„ZG dd„ dejƒZdS )a>   DropBlock, DropPath

PyTorch implementations of DropBlock and DropPath (Stochastic Depth) regularization layers.

Papers:
DropBlock: A regularization method for convolutional networks (https://arxiv.org/abs/1810.12890)

Deep Networks with Stochastic Depth (https://arxiv.org/abs/1603.09382)

Code:
DropBlock impl inspired by two Tensorflow impl that I liked:
 - https://github.com/tensorflow/tpu/blob/master/models/official/resnet/resnet_model.py#L74
 - https://github.com/clovaai/assembled-cnn/blob/master/nets/blocks.py

Hacked together by / Copyright 2020 Ross Wightman
é    Né   )Úndgridçš™™™™™¹?é   ç      ð?F)Ú	drop_probÚ
block_sizeÚgamma_scaleÚ
with_noiseÚinplaceÚ	batchwisec                 C   sð  | j \}}}	}
|
|	 }t|t|
|	ƒƒ}|| | |d  |
| d |	| d   }ttj|
| jd�tj|	| jd�ƒ\}}||d k||
|d d  k @ ||d k||	|d d  k @ @ }t |dd|	|
f¡j| jd�}|røtj	d||	|
f| j| jd�}n
t 
| ¡}d| | | dkj| jd�}tj| |d|d d� }|�r¢|�rbtjd||	|
f| j| jd�nt | ¡}|�rŒ|  |¡ |d|  ¡ n| | |d|   } nJ| ¡ |jtjd� ¡  d¡  | j¡}|�rà|  || ¡ n| | | } | S )a	   DropBlock. See https://arxiv.org/pdf/1810.12890.pdf

    DropBlock with an experimental gaussian noise option. This layer has been tested on a few training
    runs with success, but needs further validation and possibly optimization for lower runtime impact.
    é   r   )Údevice©Údtype)r   r   ©Zkernel_sizeZstrideÚpaddinggH¯¼šò×z>)ÚshapeÚminr   ÚtorchZaranger   ZreshapeÚtor   ZrandZ	rand_likeÚFÚ
max_pool2dZrandnZ
randn_likeÚmul_Úadd_ÚnumelÚfloat32ÚsumÚadd)Úxr   r   r	   r
   r   r   ÚBÚCÚHÚWÚ
total_sizeÚclipped_block_sizeÚgammaZw_iZh_iZvalid_blockZuniform_noiseÚ
block_maskÚnormal_noiseÚnormalize_scale© r*   úO/var/www/html/bwave/python/venv/lib/python3.8/site-packages/timm/layers/drop.pyÚdrop_block_2d   s>    ÿ&ÿ
ü,(r,   )r   r   r   r	   r
   r   c                 C   s  | j \}}}}	|	| }
t|t|	|ƒƒ}|| |
 |d  |	| d || d   }t | ¡ |¡}tj| | j¡|d|d d�}|rÆt | ¡ 	¡ }|r°|  
d| ¡ || ¡ n| d|  ||  } nTd| }| ¡ |jtjd� ¡  d¡ j| jd�}|�r|  
|| ¡ n| | | } | S )z» DropBlock. See https://arxiv.org/pdf/1810.12890.pdf

    DropBlock with an experimental gaussian noise option. Simplied from above without concern for valid
    block mask at edges.
    r   r   r   r   r   g�íµ ÷Æ°>)r   r   r   Z
empty_likeÚ
bernoulli_r   r   r   r   Znormal_r   r   r   r   r   r   )r   r   r   r	   r
   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r*   r+   Údrop_block_fast_2dN   s0    ÿ
   ÿ*r.   c                	       s<   e Zd ZdZdeeeeeeedœ‡ fdd	„Zd
d„ Z‡  Z	S )ÚDropBlock2dz9 DropBlock. See https://arxiv.org/pdf/1810.12890.pdf
    r   r   r   FT)r   r   r	   r
   r   r   Úfastc                    s<   t t| ƒ ¡  || _|| _|| _|| _|| _|| _|| _	d S ©N)
Úsuperr/   Ú__init__r   r	   r   r
   r   r   r0   )Úselfr   r   r	   r
   r   r   r0   ©Ú	__class__r*   r+   r3   y   s    	zDropBlock2d.__init__c                 C   sV   | j r| js|S | jr2t|| j| j| j| j| jƒS t|| j| j| j| j| j| j	ƒS d S r1   )
Útrainingr   r0   r.   r   r	   r
   r   r,   r   ©r4   r   r*   r*   r+   Úforward‹   s(         ÿ      ÿzDropBlock2d.forward)r   r   r   FFFT)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚfloatÚintÚboolr3   r9   Ú__classcell__r*   r*   r5   r+   r/   u   s$          øør/   ç        T)r   r7   Úscale_by_keepc                 C   s`   |dks|s| S d| }| j d fd| jd   }|  |¡ |¡}|dkrX|rX| |¡ | | S )a(  Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).

    This is the same as the DropConnect impl I created for EfficientNet, etc networks, however,
    the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper...
    See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for
    changing the layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use
    'survival rate' as the argument.

    rB   r   r   )r   )r   ÚndimZ	new_emptyr-   Zdiv_)r   r   r7   rC   Z	keep_probr   Zrandom_tensorr*   r*   r+   Ú	drop_path–   s    

rE   c                       s:   e Zd ZdZdeedœ‡ fdd„Zdd„ Zd	d
„ Z‡  Z	S )ÚDropPathz^Drop paths (Stochastic Depth) per sample  (when applied in main path of residual blocks).
    rB   T)r   rC   c                    s   t t| ƒ ¡  || _|| _d S r1   )r2   rF   r3   r   rC   )r4   r   rC   r5   r*   r+   r3   ­   s    zDropPath.__init__c                 C   s   t || j| j| jƒS r1   )rE   r   r7   rC   r8   r*   r*   r+   r9   ²   s    zDropPath.forwardc                 C   s   dt | jdƒd›�S )Nz
drop_prob=é   z0.3f)Úroundr   )r4   r*   r*   r+   Ú
extra_reprµ   s    zDropPath.extra_repr)rB   T)
r:   r;   r<   r=   r>   r@   r3   r9   rI   rA   r*   r*   r5   r+   rF   ª   s   rF   )r   r   r   FFF)r   r   r   FF)rB   FT)r=   r   Ztorch.nnÚnnZtorch.nn.functionalZ
functionalr   Úgridr   r>   r?   r@   r,   ZTensorr.   ÚModuler/   rE   rF   r*   r*   r*   r+   Ú<module>   sD         ùù8     úú'!