第二门课 改善深层神经网络:超参数调试、正则化以及优化(Improving Deep Neural Networks:Hyperparameter tuning, Regularization and Optimization)
第一周:深度学习的实践层面(Practical aspects of Deep Learning)(下)
文章目录
- 第二门课 改善深层神经网络:超参数调试、正则化以及优化(Improving Deep Neural Networks:Hyperparameter tuning, Regularization and Optimization)
-
- 第一周:深度学习的实践层面(Practical aspects of Deep Learning)(下)
-
- 1.7 理解 dropout(Understanding Dropout)
- 1.8 其他正则化方法(Other regularization methods)
- 1.9 归一化输入(Normalizing inputs)
- 1.10 梯度消失/梯度爆炸(Vanishing / Exploding gradients)
- 1.11 神经网络的权重初始化(Weight Initialization for Deep NetworksVanishing / Exploding gradients)
- 1.12 梯度的数值逼近(Numerical approximation of gradients)
- 1.13 梯度检验(Gradient checking)
- 1.14 梯度检验应用的注意事项(Gradient Checking Implementation Notes)
1.7 理解 dropout(Understanding Dropout)
Dropout可以随机删除网络中的神经单元,他为什么可以通过正则化发挥如此大的作用呢?
直观上理解:不要依赖于任何一个特征,因为该单元的输入可能随时被清除,因此该单元通过这种方式传播下去,并为单元的四个输入增加一点权重,通过传播所有权重,dropout将产生收缩权重的平方范数的效果,和之前讲的 L 2 L2 L2正则化类似;实施dropout的结果实它会压缩权重,并完成一些预防过拟合的外层正则化; L 2 L2 L2对不同权重的衰减是不同的,它取决于激活函数倍增的大小。
总结一下,dropout的功能类似于 L 2 L2 L2正则化,与 L 2 L2 L2正则化不同的是应用方式不同会带来一点点小变化,甚至更适用于不同的输入范围。
第二个直观认识是,我们从单个神经元入手,如图,这个单元的工作就是输入并生成一些有意义的输出。通过dropout,该单元的输入几乎被消除,有时这两个单元会被删除,有时会删除其它单元,就是说,我用紫色圈起来的这个单元,它不能依靠任何特征,因为特征都有可能被随机清除,或者说该单元的输入也都可能被随机清除。我不愿意把所有赌注都放在一个节点上,不愿意给任何一个输入加上太多权重,因为它可能会被删除,因此该单元将通过这种方式积极地传播开,并为单元的四个输入增加一点权重,通过传播所有权重,dropout将产生收缩权重的平方范数的效果,和我们之前讲过的 L 2 L2 L2正则化类似,实施dropout的结果是它会压缩权重,并完成一些预防过拟合的外层正则化。
事实证明,dropout被正式地作为一种正则化的替代形式, L 2 L2 L2对不同权重的衰减是不同的,它取决于倍增的激活函数的大小。
总结一下,dropout的功能类似于 L 2 L2 L2正则化,与 L 2 L2 L2正则化不同的是,被应用的方式不同,dropout也会有所不同,甚至更适用于不同的输入范围。
实施dropout的另一个细节是,这是一个拥有三个输入特征的网络,其中一个要选择的参数是keep-prob,它代表每一层上保留单元的概率。所以不同层的keep-prob也可以变化。第一层,矩阵 W [ 1 ] W^{[1]} W[1]是7×3,第二个权重矩阵 W [ 2 ] W^{[2]} W[2]是7×7,第三个权重矩阵 W [ 3 ] W^{[3]} W[3]是3×7,以此类推, W [ 2 ] W^{[2]} W[2]是最大的权重矩阵,因为 W [ 2 ] W^{[2]} W[2]拥有最大参数集,即7×7,为了预防矩阵的过拟合,对于这一层,我认为这是第二层,它的keep-prob值应该相对较低,假设是0.5。对于其它层,过拟合的程度可能没那么严重,它们的keep-prob值可能高一些,可能是0.7,这里是0.7。如果在某一层,我们不必担心其过拟合的问题,那么keep-prob可以为1,为了表达清除,我用紫色线笔把它们圈出来,每层keep-prob的值可能不同。
注意keep-prob的值是1,意味着保留所有单元,并且不在这一层使用dropout,对于有可能出现过拟合,且含有诸多参数的层,我们可以把keep-prob设置成比较小的值,以便应用更强大的dropout,有点像在处理 L 2 L2 L2正则化的正则化参数 λ \lambda λ,我们尝试对某些层施行更多正则化,从技术上讲,我们也可以对输入层应用dropout,我们有机会删除一个或多个输入特征,虽然现实中我们通常不这么做,keep-prob的值为1,是非常常用的输入值,也可以用更大的值,或许是0.9。但是消除一半的输入特征是不太可能的,如果我们遵守这个准则,keep-prob会接近于1,即使你对输入层应用dropout。
总结一下,如果你担心某些层比其它层更容易发生过拟合,可以把某些层的keep-prob值设置得比其它层更低,缺点是为了使用交叉验证,你要搜索更多的超级参数,另一种方案是在一些层上应用dropout,而有些层不用dropout,应用dropout的层只含有一个超级参数,就是keep-prob。
结束前分享两个实施过程中的技巧,实施dropout,在计算机视觉领域有很多成功的第一次。计算视觉中的输入量非常大,输入太多像素,以至于没有足够的数据,所以dropout在计算机视觉中应用得比较频繁,有些计算机视觉研究人员非常喜欢用它,几乎成了默认的选择,但要牢记一点,dropout是一种正则化方法,它有助于预防过拟合,因此除非算法过拟合,不然我是不会使用dropout的,所以它在其它领域应用得比较少,主要存在于计算机视觉领域,因为我们通常没有足够的数据,所以一直存在过拟合,这就是有些计算机视觉研究人员如此钟情于dropout函数的原因。直观上我认为不能概括其它学科。
dropout一大缺点就是代价函数 J J J不再被明确定义,每次迭代,都会随机移除一些节点,如果再三检查梯度下降的性能,实际上是很难进行复查的。定义明确的代价函数 J J J每次迭代后都会下降,因为我们所优化的代价函数 J J J实际上并没有明确定义,或者说在某种程度上很难计算,所以我们失去了调试工具来绘制这样的图片。我通常会关闭dropout函数,将keep-prob的值设为1,运行代码,确保J函数单调递减。然后打开dropout函数,希望在dropout过程中,代码并未引入bug。我觉得你也可以尝试其它方法,虽然我们并没有关于这些方法性能的数据统计,但你可以把它们与dropout方法一起使用。
1.8 其他正则化方法(Other regularization methods)
除了 L 2 L2 L2正则化和随机失活(dropout)正则化,还有几种方法可以减少神经网络中的过拟合:
一.数据扩增
假设你正在拟合猫咪图片分类器,如果你想通过扩增训练数据来解决过拟合,但扩增数据代价高,而且有时候我们无法扩增数据,但我们可以通过添加这类图片来增加训练集。例如,水平翻转图片,并把它添加到训练集。所以现在训练集中有原图,还有翻转后的这张图片,所以通过水平翻转图片,训练集则可以增大一倍,因为训练集有冗余,这虽然不如我们额外收集一组新图片那么好,但这样做节省了获取更多猫咪图片的花费。
除了水平翻转图片,你也可以随意裁剪图片,这张图是把原图旋转并随意放大后裁剪的,仍能辨别出图片中的猫咪。
通过随意翻转和裁剪图片,我们可以增大数据集,额外生成假训练数据。和全新的,独立的猫咪图片数据相比,这些额外的假的数据无法包含像全新数据那么多的信息,但我们这么做基本没有花费,代价几乎为零,除了一些对抗性代价。以这种方式扩增算法数据,进而正则化数据集,减少过拟合比较廉价。
像这样人工合成数据的话,我们要通过算法验证,图片中的猫经过水平翻转之后依然是猫。大家注意,我并没有垂直翻转,因为我们不想上下颠倒图片,也可以随机选取放大后的部分图片,猫可能还在上面。
对于光学字符识别,我们还可以通过添加数字,随意旋转或扭曲数字来扩增数据,把这些数字添加到训练集,它们仍然是数字。为了方便说明,我对字符做了强变形处理,所以数字4看起来是波形的,其实不用对数字4做这么夸张的扭曲,只要轻微的变形就好,我做成这样是为了让大家看的更清楚。实际操作的时候,我们通常对字符做更轻微的变形处理。因为这几个4看起来有点扭曲。所以,数据扩增可作为正则化方法使用,实际功能上也与正则化相似。
二.early stopping
还有另外一种常用的方法叫作early stopping,运行梯度下降时,我们可以绘制训练误差,或只绘制代价函数 J J J的优化过程,在训练集上用0-1记录分类误差次数。呈单调下降趋势,如图。
因为在训练过程中,我们希望训练误差,代价函数 J J J都在下降,通过early stopping,我们不但可以绘制上面这些内容,还可以绘制验证集误差,它可以是验证集上的分类误差,或验证集上的代价函数,逻辑损失和对数损失等,你会发现,验证集误差通常会先呈下降趋势,然后在某个节点处开始上升,early stopping的作用是,你会说,神经网络已经在这个迭代过程中表现得很好了,我们在此停止训练吧,得到验证集误差,它是怎么发挥作用的?
当你还未在神经网络上运行太多迭代过程的时候,参数 w w w接近0,因为随机初始化 w w w值时,它的值可能都是较小的随机值,所以在你长期训练神经网络之前 w w w依然很小,在迭代过程和训练过程中 w w w的值会变得越来越大,比如在这儿,神经网络中参数 w w w的值已经非常大了,所以early stopping要做就是在中间点停止迭代过程,我们得到一个 w w w值中等大小的弗罗贝尼乌斯范数,与 L 2 L2 L2正则化相似,选择参数w范数较小的神经网络,但愿你的神经网络过度拟合不严重。
术语early stopping代表提早停止训练神经网络,训练神经网络时,我有时会用到early stopping,但是它也有一个缺点,我们来了解一下。
我认为机器学习过程包括几个步骤,其中一步是选择一个算法来优化代价函数 J J J,我们有很多种工具来解决这个问题,如梯度下降,后面我会介绍其它算法,例如Momentum,RMSprop和Adam等等,但是优化代价函数 J J J之后,我也不想发生过拟合,也有一些工具可以解决该问题,比如正则化,扩增数据等等。
在机器学习中,超级参数激增,选出可行的算法也变得越来越复杂。我发现,如果我们用一组工具优化代价函数 J J J,机器学习就会变得更简单,在重点优化代价函数 J J J时,你只需要留意 w w w和 b b b, J ( w , b ) J(w,b) J(w,b)的值越小越好,你只需要想办法减小这个值,其它的不用关注。然后,预防过拟合还有其他任务,换句话说就是减少方差,这一步我们用另外一套工具来实现,这个原理有时被称为“正交化”。思路就是在一个时间做一个任务,后面课上我会具体介绍正交化,如果你还不了解这个概念,不用担心。
但对我来说early stopping的主要缺点就是你不能独立地处理这两个问题,因为提早停止梯度下降,也就是停止了优化代价函数 J J J,因为现在你不再尝试降低代价函数 J J J,所以代价函数 J J J的值可能不够小,同时你又希望不出现过拟合,你没有采取不同的方式来解决这两个问题,而是用一种方法同时解决两个问题,这样做的结果是我要考虑的东西变得更复杂。
如果不用early stopping,另一种方法就是 L 2 L2 L2正则化,训练神经网络的时间就可能很长。我发现,这导致超级参数搜索空间更容易分解,也更容易搜索,但是缺点在于,你必须尝试很多正则化参数 λ \lambda λ的值,这也导致搜索大量 λ \lambda λ值的计算代价太高。
Early stopping的优点是,只运行一次梯度下降,你可以找出 w w w的较小值,中间值和较大值,而无需尝试 L 2 L2 L2正则化超级参数 λ \lambda λ的很多值。
如果你还不能完全理解这个概念,没关系,下节课我们会详细讲解正交化,这样会更好理解。
虽然 L 2 L2 L2正则化有缺点,可还是有很多人愿意用它。吴恩达老师个人更倾向于使用 L 2 L2 L2正则化,尝试许多不同的 λ \lambda λ值,假设你可以负担大量计算的代价。而使用early stopping也能得到相似结果,还不用尝试这么多 λ \lambda λ值。
这节课我们讲了如何使用数据扩增,以及如何使用early stopping降低神经网络中的方差或预防过拟合。
1.9 归一化输入(Normalizing inputs)
训练神经网络,其中一个加速训练的方法就是归一化输入。假设一个训练集有两个特征,输入特征为2维,归一化需要两个步骤:
-
零均值
-
归一化方差;
我们希望无论是训练集和测试集都是通过相同的 μ μ μ和 σ 2 σ^2 σ2定义的数据转换,这两个是由训练集得出来的。
第一步是零均值化, μ = 1 m ∑ i = 1 m x ( i ) \mu = \frac{1}{m}\sum_{i =1}^{m}x^{(i)} μ=m1∑i=1mx(i),它是一个向量, x x x等于每个训练数据 x x x减去 μ \mu μ,意思是移动训练集,直到它完成零均值化。
第二步是归一化方差,注意特征 x 1 x_{1} x1的方差比特征 x 2 x_{2} x2的方差要大得多,我们要做的是给 σ \sigma σ赋值, σ 2 = 1 m ∑ i = 1 m ( x ( i ) ) 2 \sigma^{2}= \frac{1}{m}\sum_{i =1}^{m}{({x^{(i)})}^{2}} σ2=m1∑i=1m(x(i))2,这是节点 y y y 的平方, σ 2 \sigma^{2} σ2是一个向量,它的每个特征都有方差,注意,我们已经完成零值均化, ( x ( i ) ) 2 ({x^{(i)})}^{2} (x(i))2元素 y 2 y^{2} y2就是方差,我们把所有数据除以向量 σ 2 \sigma^{2} σ2,最后变成上图形式。
x 1 x_{1} x1和 x 2 x_{2} x2的方差都等于1。提示一下,如果你用它来调整训练数据,那么用相同的 μ μ μ 和 σ 2 \sigma^{2} σ2来归一化测试集。尤其是,你不希望训练集和测试集的归一化有所不同,不论 μ μ μ的值是什么,也不论 σ 2 \sigma^{2} σ2的值是什么,这两个公式中都会用到它们。所以你要用同样的方法调整测试集,而不是在训练集和测试集上分别预估 μ μ μ 和 σ 2 \sigma^{2} σ2。因为我们希望不论是训练数据还是测试数据,都是通过相同μ和 σ 2 \sigma^{2} σ2定义的相同数据转换,其中 μ μ μ和 σ 2 \sigma^{2} σ2是由训练集数据计算得来的。
我们为什么要这么做呢?为什么我们想要归一化输入特征,回想一下右上角所定义的代价函数。
J ( w , b ) = 1 m ∑ i = 1 m L ( y ^ ( i ) , y ( i ) ) J(w,b)=\frac{1}{m}\sum\limits_{i=1}^{m}{L({ { {\hat{y}}}^{(i)}},{ {y}^{(i)}})} J(w,b)=m1i=1∑mL(y^(i),y(i))
如果你使用非归一化的输入特征,代价函数会像这样:
这是一个非常细长狭窄的代价函数,你要找的最小值应该在这里。但如果特征值在不同范围,假如 x 1 x_{1} x1取值范围从1到1000,特征 x 2 x_{2} x2的取值范围从0到1,结果是参数 w 1 w_{1} w1和 w 2 w_{2} w