地址:https://zhuanlan.zhihu.com/p/680112242
我在面试算法岗位候选人的时候,比较喜欢问应用ML方面的问题。
然而,也有一些概念性的问题,比如下面这个,我就经常爱问:
Dropout是如何运作的?
很简单,对吧?
显然,每个候选人都会给我一个不完整的答案,我将在下面提到:
候选人的回答
简言之,Dropout就是将神经网络中的神经元随机归零。这样做是为了规范网络。
Dropout将网络中的神经元随机归零
Dropout仅在训练期间应用,哪些神经元激活归零是使用伯努利分布决定的:
p是随机归零的概率
我的后续问题:好的,完美!我们在Dropout中还会做其他的动作吗?
候选人:不,就是这样。我们只将神经元归零并像平常一样训练网络。
当然,我不能说上述回答不正确。他们其实是正确的。
然而,这只是Dropout工作原理的50%,令人失望的是,大多数资源并没有涵盖剩下的50%。
如果您也只知道我上面提到的50%细节,那么请继续阅读,因为有新信息可供您使用。
Dropout实际上是如何运作的?
首先,我们必须注意Dropout仅在训练期间应用,而不在推理/评估阶段应用:
dropout只在训练阶段使用
现在,考虑一个神经元的输入是使用前一个隐藏层中的100个神经元计算的:
一个神经元的输入是前一个隐藏层的多个神经元所计算
为了简单起见,我们假设一些事情:
-
每个黄色神经元激活后的值为1。
-
从黄色神经元到蓝色神经元的边权重也是1。
一个合理的假设
结果,蓝色神经元收到的输入将为100,如下所示:
当不存在dropout时,蓝色神经元是所有黄色神经元的输入
好,现在,在训练过程中,如果我们使用了Dropout,例如40%的dropout率,那么大约40%的黄色神经元激活将被清零。
结果,蓝色神经元收到的输入约为60,如下所示:
采用了Dropout后的输入
不过,以上观点只在训练阶段。
如果在推理阶段存在相同的场景,那么蓝色神经元收到的输入将为100。
因此,在相似条件下:
-
训练起见收到的输入:60。
-
推理期间收到的输入:100。
问题来了:
在训练期间,平均神经元输入明显低于推理期间收到的输入。
更正式地说,使用Dropout会显著影响激活的规模。
然而,我们希望整个模型中的神经元在训练和推理期间必须接受大致相同的激活平均值(或期望值)。
为了解决这个问题,Dropout执行了一个额外的步骤。
这个想法是在训练期间缩放剩余的主动输入。
最简单的方法是将训练期间的所有激活缩放一个因子1/(1-p),其中p是dropout率。
例如,在神经元输入60上使用此技术,我们将得到以下结果(假设我们的dropout率为40%):
缩放因子后,训练和推理的结果就相同了
如上所述,缩放神经元输入使其达到所需的范围,这使得网络的训练和推理阶段保持一致。
实验验证
事实上,我们可以使用PyTorch来验证Dropout确实执行了此步骤。
让我们定义一个dropout层,如下所示:
import torch
import torch.nn as nn
dropout_layer = nn.Dropout(0.2)
现在,我们考虑一个随机张量并将该dropout层应用于它:
dropout_layer.train()
x=torch.rand((1, 5))