Dropout
定义理解
torch.nn.Dropout(p=0.5, inplace=False)
dropout和P
下面是pytorch官方文档
During training, randomly zeroes some of the elements of the input tensor with probability p using samples from a Bernoulli distribution. Each channel will be zeroed out independently on every forward call.
在训练期间,使用伯努利分布的样本,以概率p随机归零输入张量的一些元素。每个信道将在每次前向传播时独立归零。
一句话来说就是我让输入的tensor中每一个元素都有p的概率变为0,剩下的元素都除以(1-p),就是扩大剩余的元素来保证整体平均值一定
注意:
- 在pytorch中的p也就是p是让输入归0的概率,也就可以说是输入失效的比例,越高失效越多
- Dropout作用于神经元也就是输入的tensor数据,而非作用域模型的params。
原理:(结合下面的实例观看更佳)
dropout是一个和iput的tensor矩阵,里面全是0和1/(1-p),生成一个和输入矩阵尺寸完全相同的矩阵,通过逐个元素相乘的乘法让某些矩阵值为0,也就是相当于让神经元失效,让某些参数失效,比如上图,我是每次三个相同颜色的块经过kernel加权加偏置一个新的块,但此时我让三个块失效一个(比如dropout的p设置为0.33),让他乘以0权重,剩下两个乘以(1/(1-p)),然后再加和,这就保证了每一次训练结果的范围是相同的。
原本是三个特征结合算出一块,现在随机地让一些特征失效,防止模型对某些特征更加深入地学习,降低过拟合的可能,提高泛化能力
使某些神经元失效是对dropout更形象的解释,这里注意并非让kernel失效,而是让输入tensor的数据也就是神经元。
需要注意的是后面反向传播更新参数时这些神经元也是失效的,不参与参数更新
另外记住一点dropout经实践能减少过拟合就好了,原因的我觉得也都是理论上的,就没有啥说服力
实例
新建一个Dropout层,
import torch.nn as nn
import torch
m = nn.Dropout(p=0.4)
input = torch.randn(5, 3)
print(input)
output = m(input)
print(output)
输入input
输出output
可以看到15个数有7个数变为了0,概率是非常接近0.4的
可以看到第2行1列的1.46刚好除以(1-0.4)得到2.43。
drop path
def __init__(self, drop_prob: float = 0., scale_by_keep: bool = True):
参考自
「解析」正则化 DropPath_timm droppath_ViatorSun的博客-CSDN博客、
作用:
一句话,随机让一个整样本(1行数据)以drop_prob的概率直接失效,值都变为0
那么在drop_path分支中,每个batch有drop_prob的概率样本不会 “执行”,会以0直接传递。
若x为输入的张量,其通道为[B,C,H,W],那么drop_path的含义为在一个Batch_size中,随机有drop_prob的样本,也就是使B个样本,大概B*drop_prob个样本会直接变为0.
参数scale_by_keep指是否将其他未失效的样本同时除以(1-drop_prob),以使平均数相同。
示例
self.drop_path = DropPath(0.3)
test=torch.arange(15,dtype=torch.float).resize(5,3)
print(x)
output=self.drop_path(x)
print(output)
原tensor
tensor([[ 0., 1., 2.],
[ 3., 4., 5.],
[ 6., 7., 8.],
[ 9., 10., 11.],
[12., 13., 14.]], device='cuda:0')
经过drop path输出的tensor
tensor([[ 0.0000, 0.0000, 0.0000],
[ 0.0000, 0.0000, 0.0000],
[ 8.5714, 10.0000, 11.4286],
[12.8571, 14.2857, 15.7143],
[17.1429, 18.5714, 20.0000]], device='cuda:0')
前两条变为了0,后三条除以了(1-drop_prob)也就是0.7
drop path与Dropout的区别
Dropout置为0的基本单位是1个神经原,也就是[B,C,W,H]中有B*C*W*H个神经元
drop path置为0的基本单位是1条数据,也就是[B,C,W,H]中以B为单位,如果要为0那么[C,W,H]个神经原一起为0