我知道 dropout 的目的是通过停用一些神经元来避免过度拟合。
但是,我对它是如何完成的很感兴趣,即:它背后的数学,或者关于它为什么起作用的直觉。
我知道 dropout 的目的是通过停用一些神经元来避免过度拟合。
但是,我对它是如何完成的很感兴趣,即:它背后的数学,或者关于它为什么起作用的直觉。
向神经网络添加 dropout 层有几个功能。首先,这是一些实现它的简单代码:
In [1]: import numpy as np
In [2]: weights = np.random.randint(0, 100, (8, 8)) # example weights
In [3]: weights
Out[3]:
array([[10, 48, 9, 87, 23, 18, 60, 83],
[29, 48, 88, 43, 34, 56, 52, 82],
[35, 0, 70, 3, 8, 88, 6, 15],
[39, 16, 59, 91, 33, 13, 53, 73],
[20, 56, 70, 35, 16, 12, 80, 6],
[21, 17, 23, 21, 72, 93, 58, 56],
[26, 86, 38, 90, 91, 87, 65, 0],
[67, 6, 10, 94, 19, 25, 49, 61]])
In [4]: dropout_mask = np.random.randint(0, 2, (8, 8)) # either 0 or 1
In [5]: dropout_mask
Out[5]:
array([[1, 1, 0, 0, 0, 1, 0, 1],
[1, 0, 1, 1, 0, 0, 0, 0],
[1, 0, 0, 1, 0, 1, 1, 0],
[0, 0, 0, 0, 1, 0, 1, 0],
[0, 1, 0, 0, 0, 0, 1, 0],
[0, 1, 1, 1, 0, 0, 0, 1],
[0, 1, 1, 0, 1, 1, 1, 1],
[1, 0, 0, 1, 0, 1, 1, 1]])
# we make a copy here just to use helpful variable names
In [6]: masked_weights = weights.copy()
# where the mask is "on" (==1), we set those weights to 0
In [7]: masked_weights[dropout_mask == 1] = 0
In [8]: masked_weights
Out[8]:
array([[ 0, 0, 9, 87, 23, 0, 60, 0],
[ 0, 48, 0, 0, 34, 56, 52, 82],
[ 0, 0, 70, 0, 8, 0, 0, 15],
[39, 16, 59, 91, 0, 13, 0, 73],
[20, 0, 70, 35, 16, 12, 0, 6],
[21, 0, 0, 0, 72, 93, 58, 0],
[26, 0, 0, 90, 0, 0, 0, 0],
[ 0, 6, 10, 0, 19, 0, 0, 0]])
所以我们选择了大约一半的权重并将它们关闭以通过网络。
编辑:
如上所示,Dropout 在每次训练时都会随机丢弃神经元,但在测试期间(也称为推理),默认情况下会停用 dropout 层。这意味着所有神经元都可用并被使用。然而,仍然存在缩放问题 - 因此,虽然所有神经元在推理过程中都处于活动状态,但它们的输出被缩放以反映层的整体输出,使得预期的总和保持不变。这可以通过几种不同的方式执行 - 请参阅对此答案的评论以获取相关链接。
当然,所有深度学习框架(PyTorch、Tensorflow、CNTK 等)中都有很好的dropout实现。正如这里所讨论和展示的那样。
一个直观的解释是,确保每个神经元增加其鲁棒性并设法以自己的方式为网络做出贡献。我的意思是,辍学防止神经元链或神经元簇强烈依赖于彼此。它有助于集中神经元,以便能够在尽可能多的不同场景中传递一些有用的信息,例如,当它只接收来自前一层神经元子集的信号时。
从正则化的角度考虑 dropout 可能会有所帮助。我们将正则化项添加到模型中,以再次惩罚它们的某些行为。一个例子是通过贝叶斯信息准则进行线性回归,如果模型使用越来越多的协变量,我们会增加模型的误差。在反向传播中计算值时,我们还选择误差/正则化的形式,例如,我们选择误差平方和(损失),或者只是原始错误(损失)。另一方面,Dropout 对网络本身进行了更改!我们通过在一次通过网络时简单地删除对随机选择的神经元的访问来限制它。
实际上并没有涉及很多数学,原始论文用不超过四行解释了这个概念:
魔术真的发生在第二行,伯努利分布随机变量的元素乘法以及前一层的向量输出,. IN [7]这执行与我上面的代码示例完全相同的操作。
我相信原因是它受到直观想法的启发,易于实施,并最终证明在实践中表现出色。然后可以将上述方程应用于各种问题 - 我建议阅读本文以获取一些示例。
为了进一步了解 dropout(以及围绕神经网络概念的所有内容!),我衷心推荐阅读Michael Nielsen 的书。在第 3 章中可以找到带有非常有用的图表的 dropout 说明。