第 3 章 深度学习基础
3.1 局部极小值与鞍点
在做优化的时候经常会发现,随着参数不断更新,训练的损失不会再下降,,但对这个损失仍然不满意。但有时候,模型一开始就训练不起来,不管怎么更新参数,损失都降不下去。这个时候到底发生了什么事情?
3.1.1 临界点及其种类
过去常见的一个猜想是我们优化到某个地方,这个地方参数对损失的微分为零,如图3.1所示。图中的两条曲线对应两个神经网络训练的过程。当参数对损失微分为零的时候,梯度下降就不能再更新参数了,训练就停下来了,损失不再下降了。
提到梯度为零的时候,最先想到的可能就是局部极小值(local minimum),如图 3.2a 所示。所以经常有人说,做深度学习时使用梯度下降会收敛在局部极小值,梯度下降不起作用。但其实损失不是只在局部极小值的梯度是零,还有其他可能会让梯度是零的点,比如鞍点(saddle point)。
鞍点其实就是梯度为零且区别于局部极小值和局部极大值(localmaximum)的点。图 3.2b 红色的点在 轴方向是比较高的,在 轴方向是比较低的,这就是一个鞍点。
把梯度为零的点统称为临界点(critical point)。损失没有办法再下降,也许是因为收敛在了临界点,但不一定收敛在局部极小值,因为鞍点也是梯度为零的点。
3.1.2 判断临界值种类的方法
判断一个临界点到底是局部极小值还是鞍点,更简便的方法是通过海森矩阵在该点的特征值来判断,有:
(1)海森矩阵 为正定矩阵(特征值全为正),临界点是局部极小值。
(2)海森矩阵 为负定矩阵(特征值全为负),临界点是局部极大值。
(3)海森矩阵 特征值有正有负,临界点是鞍点。
补充:
1. 正定矩阵与负定矩阵
如果 n 阶对称矩阵 A 对于任意非零的 n 维向量 都有 ,则称矩阵 A 为正定矩阵。
如果 n 阶对称矩阵 A 对于任意非零的 n 维向量 都有 ,则称矩阵 A 为负定矩阵。
2.文中式(3.1)的学习
【参考书目:《机器学习的数学》】
举个例子
一个简单的神经网络,它只有两个神经元,而且这个神经元还没有激活函数和偏置。输入 , 乘上 以后输出,然后再乘上 ,接着再输出,最终得到的数据就是 。
还有一个简单的训练数据集,这个数据集只有一组数据 (1,1),也就是 的标签是 1。 所以输入 1 进去,我们希望最终的输出跟 1 越接近越好,如图 3.3 所示。
画出这个神经网络的误差表面,如图 3.4 所示。取 [−2,2] 之间的 跟 的数值,算出这个范围内 , 数值所带来的损失,四个角落的损失是高的。
原点是鞍点,因为往某个方向走,损失可能会变大或变小。而另外两排临界点都是局部极小值。这是取 [−2,2] 之间的参数得到损失函数后,再计算出损失值,画出误差表面,得到的结论。
除此之外,还可以写出损失函数。对于图 3.3所示的神经网络,损失函数 是正确答案 减掉模型的输出 后取平方误差,这里只有一组数据,因此不会对所有的训练数据进行加和。令 , ,损失函数为
可以求出损失函数的梯度 :
在原点时, , ,此时梯度为零,原点就是一个临界点,但通过海森矩阵才能判断它是哪种临界点。刚才我们通过取 [−2,2] 之间的 和 判断出原点是一个鞍点,但假设还没有取所有可能的损失,要看看能不能用海森矩阵来判断原点是什么临界点。
海森矩阵 收集了 的二次微分:
对于原点,把 , 代进去,有海森矩阵:
特征值为2 和 −2,有正有负,因此原点是鞍点。
不仅能判断是不是在一个鞍点,还指出了参数的更新方向。之前参数更新时,都是看梯度 ,但走到某个地方以后发现 变成 0 了。但如果临界点是一个鞍点,还可以再看 ,怎么看以及如何更新参数呢?
设 为 的一个特征值, 为特征向量。对于优化问题,可令 ,则
若 ,则 。所以 。此时,,且
沿着 的方向更新 ,损失就会变小。因为根据上面两式,只要 ,沿着特征向量 的方向去更新参数,损失就会变小,所以虽然临界点的梯度为零,如果我们是在一个鞍点,只要找出负的特征值,再找出对应的特征向量,将其与 相加,就可以找到一个损失更低的点,逃离鞍点。
3.1.3 逃离鞍点的方法
问题
在深度学习中,为什么说高维空间中的局部极小值可能比鞍点更少见?
鞍点是函数中梯度为0的点。在高维空间中,鞍点只需满足某些方向的梯度接近0即可,而局部最小值需在所有方向的梯度接近0,显然更少见。
如图 3.5(a) 所示的一维空间中的误差表面,有一个局部极小值。但是在二维空间(如图 3.5(b) 所示),这个点就可能只是一个鞍点。常常会有人画类似图 3.5(c) 这样的图来告诉我们深度学习的训练是非常复杂的。
如果我们移动某两个参数,误差表面的变化非常的复杂,有非常多局部极小值。低维度空间中的局部极小值点,在更高维的空间中,实际是鞍点。
图 3.6 是训练某不同神经网络的结果,每个点对应一个神经网络。纵轴代表训练网络时,损失收敛到临界点,损失没法下降时的损失。
虽然在这个图上,越靠近右侧代表临界点“看起来越像”局部极小值,但这些点都不是真正的局部极小值。所以从经验上看起来,局部极小值并没有那么常见。多数的时候,训练到一个梯度很小的地方,参数不再更新,往往只是遇到了鞍点。
3.2 批量和动量
在计算梯度的时候,并不是对所有数据的损失 L 计算梯度,而是把所有的数据分成一个一个的批量(batch),如图 3.7 所示。
遍历所有批量的过程称为一个回合(epoch)。事实上,在把数据分为批量的时候,还会进行随机打乱(shuffle),也就是说,每个回合的批量的数据都不一样。
3.2.1 批量大小对梯度下降法的影响
假设现在有 20 笔训练数据,先看下两个最极端的情况,如图 3.8 所示。
(1) 图 3.8(a),这种使用全批量的数据来更新参数的方法即批量梯度下降法。此时模型必须把 20 笔训练数据都看完,才能够计算损失和梯度,参数才能够更新一次。
(2)图 3.8(b)中,批量大小等于 1,此时使用的方法即随机梯度下降法,也称为增量梯度下降法。用一笔数据算出来的损失相对带有更多噪声,因此其更新的方向如图 3.8 所示,是曲曲折折的 。
实例1:使用 Tesla V100 GPU 在 MNIST数据集得到的实验结果。
结果1:
(1)计算损失和梯度花费的时间不一定比使用小批量的计算时间长 。
(2) GPU 并行计算的能力存在极限,当批量大小很大的时候,时间会增加。
结果2:
考虑并行计算的时候,大的批量大小反而是较有效率的,一个回合大的批量花的时间反而是比较少的。
实例2:不同批量的图像识别。
结果:
大的批量更新比较稳定,小的批量的梯度的方向是有噪声的,但实际上有噪声的的梯度反而可以帮助训练。
图3.11反映出小批量梯度下降更好,如图3.12所示。
解释为:
(1)批量梯度下降在更新参数的时候,沿着一个损失函数来更新参数,走到一个局部最小值或鞍点显然就停下来了。梯度是零,如果不看海森矩阵,梯度下降就无法再更新参数了 。
(2)小批量梯度下降法每次是挑一个批量计算损失,所以每一次更新参数的时候所使用的损失函数是有差异的。所以这种有噪声的更新方式反而对训练其实是有帮助的。
其实小的批量也对测试有帮助。在论文“On Large-Batch Training for Deep Learning: Generalization Gap and Sharp Minima”中,可知:大的批量跟小的批量的训练准确率差不多,但测试的时候,大的批量比小的批量差,代表过拟合。如图3.13所示。
原因在于:(1)训练损失上面有多个局部最小值,损失都很低。如果局部最小值在一个“峡谷”里面,它是坏的最小值;如果局部最小值在一个平原上,它是好的最小值。(2)训练的损失跟测试的损失函数是不一样的。
3.2.2 动量法
动量法(momentum method)是另外一个可以对抗鞍点或局部最小值的方法。
如图 3.14所示,假设误差表面就是真正的斜坡,参数是一个球,把球从斜坡上滚下来,如果使用梯度下降,球走到局部最小值或鞍点就停住了。 但在物理的世界里,一个球从高处滚下,它并不一定会被鞍点或局部最小值卡住,如果将其应用到梯度下降中,这就是动量。
一般的梯度下降(vanilla gradient descent)如图 3.15 所示。
引入动量后,每次在移动参数的时候,不是只往梯度的反方向来移动参数,而是根据梯度的反方向加上前一步移动的方向决定移动方向。
动量的简单例子如图 3.17 所示。红色表示负梯度方向,蓝色虚线表示前一步的方向,蓝色实线表示真实的移动量。
一般梯度下降走到一个局部最小值或鞍点时,就被困住了。因为动量不是只看梯度,还看前一步的方向。即使梯度方向往左走,但如果前一步的影响力比梯度要大,球还是有可能继续往右走,甚至翻过一个小丘,也许可以走到更好的局部最小值,这就是动量有可能带来的好处 。
未完待续...