想起来前两天小师弟问我问题,为什么dropout是有用的,看起来像是一个有bug的操作。
这里谈下自己的理解,不一定正确:
1)dropout的经典解读之一是network的ensemble,每次drop不同的weights,从而形成不同的sub-network,最后ensemble所有的sub-network
2)那么为什么sub-network可行呢?这个很少有人提到。我觉得一种合理的解释是,原来的network是冗余的,看看最近火起来的网络压缩相关的工作就知道,其实网络中有大量的weights是没必要的,因此去掉一些weights之后的sub-network仍然有用。还有,因为每次drop的都是不同的weights,而网络压缩对于同一个网络的压缩结果也往往不同,所以保证了大多数的sub-network都可用(即便没有原始的网络准确率,但ensemble之后效果就比原来的好了)。
3)dropout的训练和测试的不同设置也保证了该方法的可用性。比如测试时输出会根据训练时的drop rate做相应的scaling。
Dropout在RNN中的应用综述(下面是转载):
Dropout
受性别在进化中的作用的启发,Hinton等人最先提出Dropout,即暂时从网络中移除神经网络中的单元。 Srivastava等人将Dropout应用于前馈神经网络和受限玻尔兹曼机,并注意到隐层0.5,输入层0.2的 dropout 率 适用于各种任务。
图1. a)标准神经网络,没有dropout。 b)应用了dropout的神经网络。
Srivastava等人的工作的核心概念是“在加入了dropout的神经网络在训练时,每个隐藏单元必须学会随机选择其他单元样本。这理应使每个隐藏的单元更加健壮,并驱使它自己学到有用的特征,而不依赖于其他隐藏的单元来纠正它的错误“。在标准神经网络中,每个参数通过梯度下降逐渐优化达到全局最小值。因此,隐藏单元可能会为了修正其他单元的错误而更新参数。这可能导致“共适应”,反过来会导致过拟合。而假设通过使其他隐藏单元的存在不可靠,dropout阻止了每个隐藏单元的共适应。
对于每个训练样本,重新调整网络并丢弃一组新的神经元。在测试时,权重需要乘以相关单元的dropout率。
图2. (a) 隐藏单元数(n)固定时的误差 (2)dropout后隐藏单元数固定。
我们可以在图2a中看到,测试误差在保持神经元(1-dropout)的概率为0.4到0.8之间是稳定的。 随着dropout率降低到c以下 0.2(P> 0.8),测试时间误差会增加。Dropout率过高时(p <0.3),网络欠拟合。
Srivatava等进一步发现“随着数据集变大,dropout的增益增加到一个点然后下降。 这表明,对于任何给定的网络结构和dropout率,存在一个“最佳点”。
Srivastava等用伯努利分别来表示隐藏单元被激活的概率,其中值1为概率p,否则为0。
dropout的示例代码如下:
class Dropout(): def __init__(self, prob=0.5): self.prob = prob self.params = [] def forward(self,X): self.mask = n