深度学习之dropout
2021-05-24 本文已影响0人
ltochange
为了防止训练过拟合,在训练过程中随机丢弃一部分输出(有的文章说随机丢弃掉一些神经元)
在这里插入图片描述
左图不使用dropout
对于第层的输出
,直接进行线性变化,然后经过激活函数,得到第
层的输出
右图使用dropout
先按照伯努利分布,概率为采样,得到
, 与第
层的输出
维度相同。两者对应位置相乘,对
中的部分位置置0,得到dropout后的
. 最后进行线性变化,经过激活函数,得到第
层的输出
实现代码
import numpy as np
def dropout(x, prob):
if prob < 0. or prob >= 1: # prob概率值,在0~1之间
raise Exception('Dropout prob must be in interval [0, 1[.')
retain_prob = 1. - prob
# 通过binomial函数,生成与x一样的维数向量
sample = np.random.binomial(n=1, p=retain_prob, size=x.shape)
# 二项分布,当n=1时,即为伯努利分布
# 即将生成一个0、1分布的向量,0表示丢掉对应位置x的数值
print(sample)
x *= sample
print(x)
x /= retain_prob
# infer时不进行dropout,从而保持输出的结果稳定
return x
x = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], dtype=np.float32)
y = dropout(x, 0.4)
print(y)
个人理解
其中,代码第14行 x /= retain_prob
是对原始的x进行rescale,那么为什么要进行 rescale呢?可能是为了保持训练和测试的时候网络输出的期望一致
假设丢弃概率是p, 原始论文中的dropout(vanilla版本)在测试时做rescale
- 训练时,使用dropout,对于网络中的某个输出值x,期望变为
(1-p)x+p0=(1-p)x
- 为了保持测试过程(没有dropout)期望一致,在测试时,对于相应层输出乘以
1-p
inverted 版本,在训练时做rescale
- 训练时,使用dropout,对于网络中的某个输出值x,期望变为
(1-p)x+p0=(1-p)x
- 为了保持测试过程(没有dropout)期望一致,在训练时, 对包含dropout的输出乘
1/(1-p)
, 使得期望仍然为1/(1-p)*(1-p)x = x
,即代码中所使用的方法。从而保证测试时不需要对代码进行修改