深度学习100问
Author:louwill
Machine Learning Lab
前段时间朋友圈被一个谷歌将dropout写成专利的新闻刷屏了,纷纷发出这也行的感叹。当然,这里我们仅专注于dropout技术本身,以此为例说明dropout的重要性。
dropout专利新闻
dropout谷歌专利
dropout作为目前神经网络训练的一项必备技术,自从被Hinton提出以来,几乎是进行深度学习训练时的标配。就像做菜时必须加料酒一样,无论何时,大家在使用全连接层的时候都会习惯性的在后面加上一个dropout层。通常情况下,dropout被作为一种防止神经网络过拟合的正则化方法,对神经网络的泛化性能有很大的帮助。每个人都会用dropout,但你真的理解它吗?本节我们就来看看dropout里的一些关键细节问题。
dropout的概念相信大家都已熟稔在心了,是指在神经网络训练中,以一定的概率随机地丢弃一部分神经元来简化网络的一项操作。本质上来说,dropout就是在正常的神经网络基础上给每一层的每一个神经元加了一道概率流程来随机丢弃某些神经元以达到防止过拟合的目的。
在keras中,dropout的实现只需要一行代码:
from keras.layers import Dropout
x = Dropout(0.5)(x)
但作为深度学习从业人员的你,在使用keras敲下这样一行代码时,你需要心里对其实现细节无比清晰才对。我们先来看一下包含dropout的神经网络训练过程,主要是前向传播和反向传播。先来看包含dropout的前向传播过程。假设标准神经网络前向传播过程的数学描述为:
使用一个参数为p的服从Bernoulli二项分布的随机变量r,将这个随机变量加入到标准神经网络输入中,那么带有dropout的神经网络可以描述为:
这样的数学描述简洁明了,好像也没什么特别注意的细节。我们以一层全连接网络为例来看dropout的具体实现过程。
D1 = np.random.rand(A1.shape[0], A1.shape[1])
D1 = D1 < prob
A1 = np.multiply(D1, A1)
A1 = A1 / prob
其中A1为上一层的输出,D1为用随机数生成的一组dropout向量,然后将其与保留概率prob做比较得到一个布尔向量,再将其与A1做乘积即可得到失活后的A1,按理说dropout到这里应该也就完成了,但最后还有一个将A1除以保留概率的操作。所以这里有个疑问,为什么在dropout之后还要做个rescale的除法?
其实,这种实现dropout的方法也叫Inverted Dropout,是一种经典的dropout实现方法。先不说Inverted Dropout,我们来看正常dropout应该是怎样的:当我们使用了dropout后,在模型训练阶段只有占比为p部分的神经元参与了训练,那么在预测阶段得到的结果会比实际平均要大1/p,所以在测试阶段我们需要将输出结果乘以p来保持输出规模不变。这种原始的dropout实现方式也叫Vanilla Dropout。Vanilla操作有一个重大缺陷,那就是预测过程需要根据训练阶段所使用的dropout策略做调整,比较麻烦,所以一般情况下都不会使用这种方法。
既如此,相必大家也知道了,我们目前用的都是Inverted Dropout方法,为了能够在神经网络训练完成后安安心心的做预测,我们可以把全部心思都放在训练阶段,所有的设置都在训练阶段完成。所以为了保证神经网络在丢弃掉一些神经元之后总体信号强度不变和预测结果稳定,也有一种说法叫保证Bernoulli二项分布的数学期望不变,我们在Inverted Dropout方法中对dropout之后的做了除以p的rescale操作。
反向传播时同理,梯度计算时需要除以保留概率:
dA1 = np.multiply(dA1, D1)
dA1 = dA1 / prob
这就是dropout最关键的一个细节问题,一般在深度学习岗位面试时面试官喜欢追着问其中的细节。值得注意一下。
另一个细节问题在于dropout有一种类似集成学习的boosting思想在里面。神经网络以1-p的概率丢弃某些神经元,当进行多次训练时,因为随机性每次训练的都是不同的网络,dropout使得神经网络不依赖于某些独立的特征,最后的结果也就是几次训练之后的平均结果,这些都使得神经网络具备更好的泛化性能,也正是dropout能够防止过拟合的主要原因。
dropout作为一项主流的神经网络训练trick,大家在使用时要知其然,更要知其所以然。
有学术和技术问题的同学可以加我微信进入机器学习实验室读者交流群。加微信后说明来意,最好做个简单的自我介绍,让我有个印象。
参考资料:
往期精彩:
一个算法工程师的成长之路
长按二维码.关注机器学习实验室