2020-5-21 吴恩达-改善深层NN-w1 深度学习的实用层面(1.6 Dropout 正则化-inverted dropout反向随机失活)

1.视频网站:mooc慕课https://mooc.study.163.com/university/deeplearning_ai#/c
2.详细笔记网站(中文):http://www.ai-start.com/dl2017/
3.github课件+作业+答案:https://github.com/stormstone/deeplearning.ai

除了L2正则化,还有一个非常实用的正则化方法——“Dropout(随机失活)”,本节介绍它的工作原理。
在这里插入图片描述

1.工作原理

假设你在训练上图这样的NN,它存在过拟合,dropout会遍历网络的每一层,并设置消除神经网络中节点的概率。
0在这里插入图片描述

如上图。
假设网络中的每一层,每个节点都以抛硬币的方式设置概率,每个节点得以保留和消除的概率都是0.5,设置完节点概率,我们会消除一些节点,然后删除掉从该节点进出的连线。
在这里插入图片描述

最后得到一个节点更少,规模更小的网络,再用backprop方法进行训练。

上面介绍的是一个样本精简的例子。对于其它样本,我们照旧以抛硬币的方式设置概率,保留一类节点集合,删除其它类型的节点集合,都将采用一个精简后NN来训练它。

这种方法似乎有点怪,单纯遍历节点,编码也是随机的,可它真的有效。不过可想而知,我们针对每个训练样本训练规模极小的网络,最后你可能会认识到为什么要正则化网络,因为我们在训练极小的网络。

2.反向随机失活 inverted dropout

2.1训练阶段

实现Dropout有几种方法。最常用的方法是inverted dropout(反向随机失活)

出于完整性考虑,我们用一个三层(l=3)网络来说明,编码中应该涉及整个3层,在这里只以某一层中实施dropout过程为例。

step1.
定义d3表示一个三层的dropout向量矩阵。

d3 = np.random.rand(a3.shape[0],a3.shape[1])

然后看它是否小于某数,我们称之为keep-pro,d3<keepprobd3<keep-prob
keep-prob是一个具体数字。抛硬币的例子它是0.5,而这里它定义为0.8,它表示保留某个隐藏单元的概率,或者说消除任意一个隐藏单元的概率是0.2,它的作用就是生成随机矩阵。

keep-prob = 0.8

归纳一下,d3是一个矩阵,keep-prob=0.8。每个样本和每个隐藏单元在d3中的对应值为1的概率都是0.8,对应为0的概率是0.2。

step2.
接下来要做的就是从第三层中获取激活函数,这里我们叫它a3,它包含了要计算的激活函数。

a3 =np.multiply(a3,d3) #a3*=d3

这里是元素相乘,也可写为a3*=d3,它的作用就是过滤d3中所有等于0的元素。而各个元素等于0的概率只有20%,乘法运算最终把d3中相应元素输出,即让d3中0元素与a3中相对元素归零。

用python实现该算法,d3是一个布尔型数组,值为true和false,而不是1和0,乘法运算依然有效,python会把true和false翻译为1和0。

step3.关键
最后,我们用a3除以0.8,或者除以keep-prob参数。注意:step2执行完,a3只有初始值的0.8(有0.2被过滤了)。

a3 /=  keep-prob

解释一下为什么要这么做。
为方便起见,我们假设第三隐藏层上有50个单元或者说50个神经元。保留和删除它们的概率分别为80%和20%,这意味着最后被删除或归零的单元平均有10个(50×20%=10)。

现在我们看下Z[4]Z[4]=W[4]a[3]+b[4]Z^{[4]}=W^{[4]}a^{[3]}+b^{[4]}
我们的预期是,a3减少20%,也就是说中a[3]有20%的元素被归零。为了不影响Z[4]的期望值,我们需要用W[4]a[3]/0.8W^{[4]}a^{[3]}/0.8,它将会修正或弥补减少的20%,a3的期望值不会变,所以 a3 /= keep-prob 就是所谓的dropout方法

它的功能是,不论keep-prop的值是多少,例如0.8,0.9甚至是1,(如果keep-prop设置为1,那么就不存在dropout,因为它会保留所有节点。)反向随机失活(inverted dropout)方法通过除以keep-prob,确保a3的期望值不变。即:第三层单元减少,但是Z[4]Z^{[4]}不变。

事实证明,在测试阶段,当我们评估一个NN时,使用反向随机失活方法会让测试阶段变得更容易,因为它的数据扩展问题变少。

目前实施dropout最常用的方法就是Inverted dropout。
Dropout早期的迭代版本都没有除以keep-prob,所以在测试阶段,平均值会变得越来越复杂,不过那些版本已经不再使用了。

你会发现,不同的训练样本,清除不同的隐藏单元也不同。实际上,如果你通过相同训练集多次传递数据,每次训练数据的梯度不同,则随机对不同隐藏单元归零,有时却并非如此。

比如,需要将相同隐藏单元归零,第一次迭代梯度下降时,把一些隐藏单元归零,第二次迭代梯度下降时,也就是第二次遍历训练集时,对不同类型的隐藏层单元归零。矩阵向量d3用来决定第三层中哪些单元归零,无论用前向传播foreprop还是反向传播backprop,上面例子里我们只介绍了前向传播foreprob。

2.2测试阶段-不使用dropout函数

如何在测试阶段训练算法?方法就是不使用dropout函数。

在测试阶段,我们已经给出了X,或是想预测的变量,用的是标准计数法。
我们用第0层的激活函数a[0]标注为测试样本X,a[0]=Xa^{[0]}=X,我们在测试阶段不使用dropout函数,尤其是像下列情况:

z[1]=W[1]a[0]+b[1]z^{[1]}=W^{[1]}a^{[0]}+b^{[1]}
a[1]=g[1](z[1])a^{[1]}=g^{[1]}(z^{[1]})
z[2]=W[2]a[1]+b[2]z^{[2]}=W^{[2]}a^{[1]}+b^{[2]}
a[2]=......a^{[2]}=......

以此类推直到最后一层,预测值为y^\hat y
显然在测试阶段,我们并未使用dropout,自然也就不用抛硬币来决定失活概率,以及要消除哪些隐藏单元了。

因为在测试阶段进行预测时,我们不期望输出结果是随机的,如果测试阶段应用dropout函数,预测会受到干扰。理论上,你只需要多次运行预测处理过程,每一次不同的隐藏单元会被随机归零(dropout)。但是这个过程计算效率低,得出的结果也几乎相同,与不使用dropout函数产生的结果极为相似。

Inverted dropout函数在除以keep-prob时可以记住上一步的操作,目的是确保即使在测试阶段不执行dropout来调整数值范围,激活函数a的预期结果也不会发生变化,所以没必要在测试阶段额外添加尺度参数,这与训练阶段不同。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章