除了L2正则化之外,还有一个很常用的正则化技巧就是Dropout(随机失活)。它的主要思想就是随机丢弃网络每一层的一些神经元。
原理和实现
首先从原理上来理解一下什么是Dropout正则化。如下图所示(图片来源于吴恩达老师深度学习课程课件),左图为一个正常的网络,进行Dropout正则化就是对于每一层的单元,根据一定的概率来“删除”掉他们,如下面右图所示,以0.5的保留概率(keep-prob)进行Dropout之后,剩下的神经元组成了一个比较简单的网络。
实现Dropout的方法很多,最常用的是inverted dropout。以一个深层神经网络的某一个隐藏层为例来解释怎么进行Dropout正则化。首先假设对于第
l
l
l 层,其激活函数值为
a
[
l
]
a^{[l]}
a[l] ,我们设置的保留概率
k
e
e
p
_
p
r
o
b
=
0.8
keep\_prob=0.8
keep_prob=0.8,这意味着隐藏层的每一个神经元被以0.8的概率得到保留。
可以将inverted dropout方法归纳为四步:
- 根据 k e e p _ p r o b keep\_prob keep_prob 生成和 a [ l ] a^{[l]} a[l] 同形的随机概率矩阵 d [ l ] d^{[l]} d[l] ,
Dl = np.random.rand(Al.shape[0], Al.shape[1])
- 将 d [ l ] d^{[l]} d[l] 转化为0-1矩阵,
Dl = Dl < keep_prob
- 将 a [ l ] a^{[l]} a[l] 和 d [ l ] d^{[l]} d[l] 中的元素一一对应, d [ l ] d^{[l]} d[l] 为1表示对应的神经元被保留,为0表示舍弃掉,
Al = Al * Dl
- 为了确保 a [ l ] a^{[l]} a[l] 的期望值不变,将 a [ l ] a^{[l]} a[l] 除以 k e e p _ p r o b keep\_prob keep_prob ,
Al = Al / keep_prob
需要注意的是,在反向传播的时候,也需要像上面一样进行dropout操作,和前向传播关闭相同的神经元,即,对于某一层的 d a [ l ] da^{[l]} da[l] ,应该进行以下计算:
dAl = dAl * Dl
dAl = dAl / keep_prob
另一点是,Dropout正则化只在训练阶段实施,在测试阶段只需要利用训练好的参数进行正向预测,而不需要进行神经元的随机失活。
理解
Dropout正则化的作用可以从两方面理解:1)通过随机的神经元失活使得网络更小,有效防止过拟合;2)由于每个隐藏神经元都可能被清楚,因此网络的输出不会偏向于某一个特征,这样Dropout会产生类似于L2范数的效果。
代码
代码可以在我Github上找到。