a
    d                     @   s   d Z ddlZddlmZ ddlm  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皙?         ?F)	drop_prob
block_sizegamma_scale
with_noiseinplace	batchwisec                 C   s  | j \}}}	}
|
|	 }t|t|
|	}|| | |d  |
| d |	| d   }tt|
| jt|	| j\}}||d k||
|d d  k @ ||d k||	|d d  k @ @ }t|dd|	|
fj| jd}|rtj	d||	|
f| j| jd}n
t
| }d| | | dkj| jd}tj| |d|d d }|r|rht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.
          dtype)r   deviceZkernel_sizeZstridepaddinggHz>)shapemintorchZmeshgridZarangetor   Zreshaper   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)   Y/var/www/html/stable-diffusion-webui/venv/lib/python3.9/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}|rt| 	 }|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_2dF   s*    *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
   r/   )selfr   r   r   r   r	   r
   r/   	__class__r)   r*   r2   l   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 r0   )
trainingr   r/   r-   r   r   r   r	   r+   r
   r3   r   r)   r)   r*   forward~   s    zDropBlock2d.forward)r   r   r   FFFT)
__name__
__module____qualname____doc__floatintboolr2   r8   __classcell__r)   r)   r4   r*   r.   h   s$          r.           T)r   r6   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.

    rA   r   r   )r   )r   ndimZ	new_emptyr,   Zdiv_)r   r   r6   rB   Z	keep_probr   Zrandom_tensorr)   r)   r*   	drop_path   s    

rD   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).
    rA   T)r   rB   c                    s   t t|   || _|| _d S r0   )r1   rE   r2   r   rB   )r3   r   rB   r4   r)   r*   r2      s    zDropPath.__init__c                 C   s   t || j| j| jS r0   )rD   r   r6   rB   r7   r)   r)   r*   r8      s    zDropPath.forwardc                 C   s   dt | jddS )Nz
drop_prob=   z0.3f)roundr   )r3   r)   r)   r*   
extra_repr   s    zDropPath.extra_repr)rA   T)
r9   r:   r;   r<   r=   r?   r2   r8   rH   r@   r)   r)   r4   r*   rE      s   rE   )r   r   r   FFF)r   r   r   FF)rA   FT)r<   r   Ztorch.nnnnZtorch.nn.functionalZ
functionalr   r=   r>   r?   r+   ZTensorr-   Moduler.   rD   rE   r)   r)   r)   r*   <module>   s$     1  "!