局部最小值与鞍点 (Local Minimum & Saddle Point)
我们在做优化的时候经常会发现,随着参数不断更新,训练的损失不会再下降, 但是我们对这个损失仍然不满意.把深层网络(deep network)、线性模型和浅层网络(shallow network) 做比较,可以发现深层网络没有做得更好——深层网络没有发挥出它完整的力量,所以优化是有问题的.但有时候,模型一开始就训练不起来,不管我们怎么更新参数,损失都降不下去.
临界点及其种类
在优化过程中,优化到某个地方的损失关于参数的微分为零的时候,梯度下降就不能再更新参数了,训练就停下来了,损失不再下降.
当梯度为0时,我们最先想到的是到达了局部最小值,然而损失不是只在局部极小值的梯度是零,还有其他可能会让梯度是零的点,比如鞍点(saddle point).鞍点其实就是梯度是零且区别于局部极小值和局部极大值(local maximum)的点.
我们把梯度为零的点统称为临界点(critical point),损失没有办法再下降,也许是因为收敛在了 临界点,但不一定收敛在局部极小值,因为鞍点也是梯度为零的点.
判断临界值种类
判断一个临界点到底是局部极小值还是鞍点需要知道损失函数的形状.可是怎么知道损失函数的形状?网络本身很复杂,用复杂网络算出来的损失函数显然也很复杂.虽然无法完整 知道整个损失函数的样子,但是如果给定某一组参数,比如 θ θ θ,在 θ ′ θ^′ θ′附近的损失函数是有办法写出来的–利用泰勒级数近似:
L ( θ ) ≈ L ( θ ′ ) + ( θ − θ ′ ) T g + 1 2 ( θ − θ ′ ) T H ( θ − θ ′ ) L(θ)\approx L(θ^{′})+(θ-θ^{′})^{T}g+\frac{1}{2}(θ-θ^{′})^{T}H(θ-θ^{′}) L(θ)≈L(θ′)+(θ−θ′)Tg+21(θ−θ′)TH(θ−θ′)
其中g代表梯度,是一个向量,gi 是向 量 g 的第 i 个元素,就是L关于θ的第i个元素的偏导数, g i = δ L ( θ ′ ) δ θ i g_i=\frac{\delta L(θ^′)}{\delta θ_i} gi=δθiδL(θ′),弥补 L ( θ ′ ) L(θ^′) L(θ′)和 L ( θ ) L(θ) L(θ)之间的差距,有时会写成 ∇ L ( θ ′ ) \nabla L(θ^{′}) ∇L(θ′)
展开两项还不足以描述L(θ),H里面放的是L的二次微分,它第i行, 第j列的值Hij就是把θ的第 i 个元素对 L ( θ ′ ) L(θ^{′}) L(θ′)
作微分,再把θ的第j个元素二次微分,即 H i j = δ 2 δ θ i δ θ j L ( θ ′ ) H_{ij}=\frac{{\delta}^2}{\delta θ_i \delta θ_j} L(θ^{′}) Hij=δθiδθjδ2L(θ′).
在临界点,梯度g为0,因此第二项为0,我们可以根据第三项判断 θ ′ θ^′ θ′附近的误差表面,从而得知它是哪种类型,假设用向量v表示 ( θ − θ ′ ) , 令 (θ-θ^{′}),令 (θ−θ′),令 α = v T H v \alpha=v^{T}Hv α=vTHv,有如下三种情况:
- 对所有v有 α > 0 \alpha>0 α>0 局部最小值
- 对所有v有 α < 0 \alpha<0 α<0 局部最大值
- 有时大于零,有时小于零,代表是鞍点
当处于临界点,我们通过海森矩阵H收集了L的二次微分,对于某点,我们可以代入具体参数值,得到海森矩阵,通过特征值判断类型,例如特征值有正有负,就是鞍点,如果特征值都是正的(正定矩阵),就是局部最小值,负定矩阵同理.实际上H不仅可以判断类型,还指出了参数的更新方向
沿着 u 的方向更新 θ,损失就会变小.因为根据式 (3.10) 和式 (3.11),只要 θ = θ′ + u,沿着特征向量 u 的方向去更新参数,损失就会变小,所以虽然临界点的梯度为零,如果我们是 在一个鞍点,只要找出负的特征值,再找出这个特征值对应的特征向量.将其与 θ′ 相加,就 可以找到一个损失更低的点.
所以,鞍点并非什么大问题,但实际上,我们几乎不会真的把海森矩阵算出来,因为海森矩阵需要算二次微分,计算这个矩阵的运算量非常大,还要把它的特征值 跟特征向量找出来,所以几乎没有人用这个方法来逃离鞍点.还有一些其他逃离鞍点的方法的运算量都比要算海森矩阵小很多.
认识到鞍点其实没那么可怕,我们再回到老问题-局部最小值,我们在训练一个网络的时候,参数数量动辄达百万千万级,所以误差 表面其实有非常高的维度—— 参数的数量代表了误差表面的维度:
在一维中,我们认为自己遇到了局部最小值,实际上在二维中只不过是个鞍点,仍然有路可走(继续优化),那么如果维度足够高,实际上遇到局部最小值的情况很有限,因为一旦能找到临界点,如果其特征值有负,就可以继续梯度下降,只有全为正特征值,才意味着是局部最小值:
最小值比例 = 正特征值数量 总特征值数量 最小值比例=\frac{正特征值数量}{总特征值数量} 最小值比例=总特征值数量正特征值数量
实际上,我们几乎找不到所有特征值都为正的临界点,所以从经验上看起来,局部极小值并没有那么常见.多数的时候,我们训练到一个梯度很小的地方,参数不再更新,往往只是遇到了鞍点.
批量与动量(Batch & Momentum)
在计算梯度时,往往不会直接将所有数据集投入训练,而是将其分为多个批量,每个批量大小为B,训练时,取出B笔数据计算损失,并更新参数,当遍历完全部数据后,称为一个回合(epoch).事实上,每次进行分批量时,还会进行随机打乱(shuffle)
批量大小对梯度下降的影响
在实际训练时,具体的批量大小也作为一个超参数,为了理解这个超参数如何更好确定,取两个极端情况
- 不使用批量(批量大小即训练数据大小),这种使用全批量(full batch)的方法即批量梯度下降法(Batch Gradient Descent),这种方法需要把所有训练数据都查看完,才能够计算损失和梯度,进行一次参数更新
- 批量大小为1,这种方法即随机梯度下降法(Stochastic Gradient Descent),这意味着每取出一次,进行一次更新
理论上,BGD更新需要查看完所有数据,相比SGD可能需要更大的时间开销,每次更新相比SGD更慢,但更稳定.但实际上考虑并行计算,BGD花费的时间不一定比SGD更长(当然,GPU的并行计算能力存在极限).
以上讨论告诉我们在每次计算和更新时,并行计算的支持让批量大小可以尽可能增大,还需要考虑更新次数对时间的开销,当批量过小,单个回合所需要的参数更新次数更多,因此,考虑并行计算时,大批量的计算和更新反而更有效率.
大批量的更新更稳定,回合时间更短,计算时间虽然长但并行计算解决了这个问题,那么小批量的优势在哪?
由于小批量每次随机取一小部分进行计算更新,每次的更新方向是带有随机性的,即梯度方向有噪声(noisy),实际上有噪声的梯度反而可以帮助训练,这个优势体现在优化中.
批量梯度下降在更新参数的时候,沿着一个损失函数来更新参数,走到一个局部最小值点或鞍点显然就停下来了。梯度是零,如果不看海森矩阵,梯度下降就无法再更新参数 。但小批量梯度下降每次挑 一个批量计算损失,所以每一次更新参数的时候所使用的损失函数是有差异的.选到第一个 批量的时候,用 L1计算梯度;选到第二个批量的时候,用 L2计算梯度,在优化时,在某位置对于L1的梯度为0,优化停止,但对于L2,仍能继续优化,继续降低损失.
另外,由于对于局部最小值来说,平坦的最小值相较尖锐的最小值具有更高的稳定性,能够更好的适应损失函数的变化(损失函数变化时具体损失的变动不大),而小批量的随机性正好能让参数有机会脱离尖锐的最小值,找到更好的局部最小值,更具稳定性.
动量法
动量法是另外一个对抗鞍点和局部最小值点的方法
由于惯性,球会滚过鞍点,到达局部最小值,甚至翻过坡找到更好的局部最小值
一般的梯度下降(vanilla gradient descent)如图所示。初始参数为 θ0,计算完梯度后,往梯度的反方向去更新参数 θ1= θ0− ηg0。有了新的参数 θ1后,再计算与更新,直到临界点.
而引入动量后,每次在移动参数的时,不是只往梯度的反方向来移动参数,而是根据梯度的反方向加上前一步移动的方向决定移动方向,每一步的移动都用 m 来表示。m 其实可以写成之前所有计算的梯度的加权和。其中 η 是学习率,λ 是前一个方向的权重参数.可以从两个角度来理解动量法。一个角度是动量是梯度的反方向加上前一次移动的方向。另外一个角度是当加上动量的时候,更新的方向不是只考虑现在的梯度,而是考虑过去所有梯度的总和.