
    ^j"                     <   d Z ddlmZmZ ddlZddlmZ ddlmc mZ	 	 	 	 	 	 	 	 ddej                  dedededed	ed
edefdZ G d dej                        ZddededefdZ G d dej                        Z	 ddedeeee   f   dedeee   eee      f   fdZy)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
    )ListUnionNx	drop_prob
block_sizegamma_scale
with_noiseinplacecouple_channelsscale_by_keepc           	         | j                   \  }}	}
}t        ||
      t        ||      }}t        ||z  |
z  |z        t        ||z        z  t        |
|z
  dz   ||z
  dz   z        z  }||rdn|	|
|f}t        j                         5  t        j
                  || j                  | j                        j                  |      }t        j                  |||fd|dz  |dz  f      }|dz  dk(  s|dz  dk(  r|d|dz   dz  d|dz   dz  df   }d|z
  }ddd       |rt        j                         5  t        j                        j                         }|j                         ddd       |r"| j                        j                         | S | z  z   } | S |rt        j                         5  j                         |j!                  t        j"                  	      j%                         j'                  d
      z  }|j                  |j!                  | j                               ddd       |r| j                         | S | z  } | S # 1 sw Y   >xY w# 1 sw Y   xY w# 1 sw Y   >xY w)a   DropBlock. See https://arxiv.org/pdf/1810.12890.pdf

    DropBlock with an experimental gaussian noise option.

    Args:
        x: Input tensor of shape (B, C, H, W).
        drop_prob: Probability of dropping a block.
        block_size: Size of the block to drop.
        gamma_scale: Scale factor for the drop probability.
        with_noise: If True, add gaussian noise to dropped regions instead of zeros.
        inplace: If True, perform operation in-place.
        couple_channels: If True, all channels share the same drop mask (per the original paper).
            If False, each channel gets an independent mask.
        scale_by_keep: If True, scale kept activations to maintain expected values.

    Returns:
        Tensor with dropped blocks, same shape as input.
       )dtypedevice   )kernel_sizestridepaddingr   .N      ?)r   gHz>)shapeminfloattorchno_grademptyr   r   
bernoulli_F
max_pool2d
empty_likenormal_mul_add_numeltofloat32sumadd)r   r   r   r   r	   r
   r   r   BCHWkhkwgammanoise_shape
block_mask	keep_masknoisenormalize_scales                       [/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/timm/layers/drop.pydrop_block_2dr5      sb   8 JAq!QQZ!3B +	)A-12U27^CeQQSVVWZ\]`b\bef\fLgFhhE ?a1a8K	 $[[AGGAHHMXXY^_
 \\R1WbAg&	

 6Q;"q&A+#C"q&Aa1$EFJO	$" ]]_ 	#$$Y/779EJJz"	# FF9""5) H I%A H  <"+//"3illl6W6[6[6]6a6abf6g"g11!'':;<
 FF9 H IAHM$ $$	# 	#< <s&   BI05I1A9I'II$'I0c                   V     e Zd ZdZ	 	 	 	 	 	 	 ddededededededef fd	Zd
 Z xZ	S )DropBlock2daa   DropBlock. See https://arxiv.org/pdf/1810.12890.pdf

    Args:
        drop_prob: Probability of dropping a block.
        block_size: Size of the block to drop.
        gamma_scale: Scale factor for the drop probability.
        with_noise: If True, add gaussian noise to dropped regions instead of zeros.
        inplace: If True, perform operation in-place.
        couple_channels: If True, all channels share the same drop mask (per the original paper).
            If False, each channel gets an independent mask.
        scale_by_keep: If True, scale kept activations to maintain expected values.
    r   r   r   r	   r
   r   r   c                     t         |           || _        || _        || _        || _        || _        || _        || _        ddh}	|D ]   }
|
|	vsdd l	}|j                  d|
 d       " y )N	batchwisefastr   z/DropBlock2d() got unexpected keyword argument '')super__init__r   r   r   r	   r
   r   r   warningswarn)selfr   r   r   r	   r
   r   r   kwargsdeprecated_argskr>   	__class__s               r4   r=   zDropBlock2d.__init__t   s     	"&$$.* '/ 	VA' OPQsRSTU	V    c           
          | j                   r| j                  s|S t        || j                  | j                  | j                  | j
                  | j                  | j                  | j                        S )N)r   r   r   r	   r
   r   r   )	trainingr   r5   r   r   r	   r
   r   r   r@   r   s     r4   forwardzDropBlock2d.forward   s[    }}DNNHnn((LL 00,,	
 		
rE   g?   r   FFTT)
__name__
__module____qualname____doc__r   intboolr=   rI   __classcell__rD   s   @r4   r7   r7   f   su      #!$$!$("&VV V 	V
 V V "V  V6
rE   r7   rG   c                     |dk(  s|s| S d|z
  }| j                   d   fd| j                  dz
  z  z   }| j                  |      j                  |      }|dkD  r|r|j	                  |       | |z  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.

            r   r   )r   )r   ndim	new_emptyr   div_)r   r   rG   r   	keep_probr   random_tensors          r4   	drop_pathr[      sw     BhIIWWQZMDAFFQJ//EKK&11)<M3=9%}rE   c                   :     e Zd ZdZddedef fdZd Zd Z xZ	S )DropPathz^Drop paths (Stochastic Depth) per sample  (when applied in main path of residual blocks).
    r   r   c                 >    t         |           || _        || _        y N)r<   r=   r   r   )r@   r   r   rD   s      r4   r=   zDropPath.__init__   s    "*rE   c                 Z    t        || j                  | j                  | j                        S r_   )r[   r   rG   r   rH   s     r4   rI   zDropPath.forward   s!    DNNDMM4;M;MNNrE   c                 6    dt        | j                  d      dS )Nz
drop_prob=   z0.3f)roundr   )r@   s    r4   
extra_reprzDropPath.extra_repr   s    E$..3D9::rE   )rU   T)
rL   rM   rN   rO   r   rQ   r=   rI   rd   rR   rS   s   @r4   r]   r]      s&    +% +T +
O;rE   r]   drop_path_ratedepths	stagewisereturnc                    t        |t              rC|rt        d      t        j                  d| |d      D cg c]  }|j                          }}|S t        |      }|rEt        j                  d| |d      j                  |      D cg c]  }|j                          }}|S t        j                  d| |d      D cg c]  }|j                          }}|S c c}w c c}w c c}w )a   Generate drop path rates for stochastic depth.

    This function handles two common patterns for drop path rate scheduling:
    1. Per-block: Linear increase from 0 to drop_path_rate across all blocks
    2. Stage-wise: Linear increase across stages, with same rate within each stage

    Args:
        drop_path_rate: Maximum drop path rate (at the end).
        depths: Either a single int for total depth (per-block mode) or
                list of ints for depths per stage (stage-wise mode).
        stagewise: If True, use stage-wise pattern. If False, use per-block pattern.
                   When depths is a list, stagewise defaults to True.

    Returns:
        For per-block mode: List of drop rates, one per block.
        For stage-wise mode: List of lists, drop rates per stage.
    z;stagewise=True requires depths to be a list of stage depthsr   cpu)r   )	
isinstancerP   
ValueErrorr   linspaceitemr&   splittolist)re   rf   rg   r   dprtotal_depths         r4   calculate_drop_path_ratesrs      s    , &#Z[[!&>6RW!XYAqvvxYY
 &k',~~a]b'c'i'ijp'qr!188:rCrJ &+^^A~{[`%ab1668bCbJ Z s cs   CC!C&rJ   )rU   FT)F)rO   typingr   r   r   torch.nnnntorch.nn.functional
functionalr   Tensorr   rP   rQ   r5   Moduler7   r[   r]   rs    rE   r4   <module>r|      s        
    $"K<<KK K 	K
 K K K K\5
")) 5
pE $ t (;ryy ;$  &&c49n%& & 4;T%[))*	&rE   