《deep learning》学习笔记(8)——深度模型中的优化
https://blog.csdn.net/u011239443/article/details/80046684
机器学习中的算法涉及诸多的优化问题,典型的就是利用梯度下降法(gradient descent)求使损失函数 J(theta) 下降的模型参数 theta 。在深度学习,尤其是深度神经网络的训练和预测中,大的模型往往要花上数天甚至是数月的训练时间,因此虽然模型的优化费事费力,仍然是一个高回报的步骤, 因为好的模型和优化方法可以极大的加速深度学习模型的训练。在本章中,将主要介绍神经网络优化这一特定问题:寻找神经网络的参数 theta,可以显著的降低由训练集误差项和正则化项组成的代价函数 J(theta) 。
8.1 学习和纯优化有什么不同
在机器学习的问题中,我们关心的是算法的性能度量 P, 它通常定义于测试集之上而且往往是不可解的,因此,我们采取的策略是间接地优化 P:我们希望通过降低代价函数 J(theta) 的方式来提高 P。而传统的纯优化就是单纯的优化目标 J本身。深度学习中,代价函数通常用训练集上损失函数的期望或者平均 :
[图片上传失败…(image-7fe1ff-1524449135535)]
其中,L是每个样本的损失函数(loss function), [图片上传失败…(image-d662-1524449135535)] 是输入x时候的预测的输出, [图片上传失败…(image-821270-1524449135535)] 是样本的经验分布,在监督学习中,y是目标输出。上式定义了训练集上的目标函数,而我们真正希望最小化的是基于数据生成分布 [图片上传失败…(image-bc3927-1524449135535)] 的期望:
[图片上传失败…(image-d35fae-1524449135535)]
8.1.1 经验风险最小化
机器学习算法真正目标是想降低期望误差,这样的一个量也叫做风险(risk)。需要注意的是,该式所计算的值是取自数据的真实潜在分布 [图片上传失败…(image-6a279b-1524449135535)] 。如果我们知道了真实的数据分布,那么这将变成一个可以被优化算法优化的问题。但是,通常我们只有训练集的样本。因此,机器学习优化问题在这里可以转化为求最小化训练集上的误差期望,也就是说用已知的经验分布 [图片上传失败…(image-482949-1524449135535)] 代替未知的真实分布 [图片上传失败…(image-8106dd-1524449135535)] 。这样一来,我们转为最小化经验风险(emperical risk):
[图片上传失败…(image-e7c42a-1524449135535)]
上式中 m 表示训练样本的数目。基于这种评价训练误差的训练过程被称为经验风险最小化(empirical risk minimization)。总结起来,我们并没有直接优化风险,而是优化经验风险,希望能够很大程度上的降低风险。单纯依靠最小化经验风险可能导致过拟合现象,而且在很多的情形下,减小经验风险并不可行,所以在深度学习中,我们很少使用经验风险最小化,而使用另外一不同的方法。
8.1.2 代理损失函数和提前终止
有时候我们的真正损失函数,比如 0-1 分类误差并无法被有效的优化,此时我们会使用代理损失函数(surrogate loss function)来作为原来目标的替代,而且会带来好处。比如,正确分类类别的负对数似然通常用作 0-1 损失的替代,。负对数似然允许模型估计给定样本的类别的条件概率,能够输出期望最小分类误差所对应的类型。有些情况下,代理损失函数可以比原损失函数学到更多的东西,比如对数似然代替 0-1 分类误差函数时,当训练集上的误差达到0之后,测试集上的误差还可以持续下降,也就是说此时模型可以继续学习以拉开不同类别直接的距离以提高分类的鲁棒性。也就是说,代理损失函数从训练数据中学到了更多的东西。
另外一个一般优化算法和机器学习训练算法不同的地方是,训练算法不会停在局部极小值点,而且通常机器学习的算法会提前设置终止条件,当条件满足时(通常在过拟合之前)算法就停止,虽然此时代理损失函数仍然有较大的导数。对于纯优化来说,终止时导数非常小。
8.1.3 批量算法和小批量算法
机器学习算法的目标函数通常可以分解为训练样本上的求和。机器学习中的优化算法在计算参数的每一次更新时,通常仅仅使用整个代价函数的一部分项来估计代价函数的期望值。例如:
[图片上传失败…(image-173eac-1524449135535)]
最大化这个总和等价于最大化训练集在经验分布上的期望:
[图片上传失败…(image-367f5-1524449135535)]
优化算法用到的目标函数 J 中用到的大多数属性也是训练集上的期望。例如常用的梯度期望:
[图片上传失败…(image-78a1dc-1524449135535)]
准确的计算这个期望的代价非常大,因为需要在训练集的每个数据上进行以上的计算,计算量非常大。在真正的实践中,我们通常会随机采样少量的样本,然后计算这些样本上的平均值。简单的论证如下:n个样本的平均值的方差是 [图片上传失败…(image-fd0bad-1524449135535)] ,其中 sigma 是样本真实的标准差。这个公式表明,当样本量增大100倍时,相应地只能得到10倍的误差减小,也就是说回报是低于线性的。如果能够快速的计算出梯度的估计值,而不是缓慢的计算所有梯度的准确值,大多数算法会收敛的更快。另外,训练集的冗余也使得我们考虑使用小数目的部分样本进行模型训练。
使用整个训练集的优化方法被称为批量(batch) 或确定性(deterministic)梯度算法,他们会在每次更新参数时计算所有样本。通常,“批量梯度下降”指使用全部训练集,而“批量”单独出现时,指一组样本。每次只使用部分样本的方法被称为随机(stochastic)或者在线(online)算法。在线通常是指从连续产生的数据流(stream)中提取样本,而不是从一个固定大小的样本中遍历多次采样的情形。大多数深度学习算法介于两者之间,使用一个以上但不是全部的训练样本,传统上称这种方法为小批量(minibatch)或者小批量随机(minibatch stochastic)方法,现在统称为随机(stochastic)方法。
小批量大小由以下因素决定:
- 更大批量产生更精准梯度,但是回报低于线性
- 太小的批量无法充分利用多核架构
- 如果可并行处理,那么内存消耗和批量大小成正比
- 特定大小数组运行在某些硬件上,运行更快
- 小批量引入噪声,具有正则化的效果
不同的算法使用不同的方法从小批量中提取信息,有些表现好,有些表现不好,原因可能是无法在小批量上面获取有用信息,或者是放大了小批量上面的误差噪声。
小批量是随机抽取的这一点非常重要,以防连续遍历时数据之间的相关性导致梯度估计的相关性。从一组样本中计算出梯度期望的无偏估计要求这些样本之间是互相独立的。通常的做法是在训练之前,将数据随机打乱一次后,再按照顺序一直往下取 minibatch 就可以了。每个独立的模型每次遍历数据时都会使用我们已经提前打乱的数据,这种理论上偏离随机采样的方法并没有给模型训练带来怎样的影响。 小批量随机梯度下降的一个有趣的事实是,只要没有重复使用样本,它将遵循着真实泛化误差的梯度。在线学习最好体现了随机梯度下降是最小泛化误差的原因:所有数据都是新的独立产生的,而不是原来固定大小的训练集,这种情况下每次更新的样本是直接从分布 p_{data} 中采样获得的无偏样本。
除非数据量非常之大,通常最好是多次遍历数据集,如果只在第一次随机打乱数据顺序后不再改变顺序,只有第一次遍历数据符合泛化误差梯度的无偏估计,额外的训练仍然可以继续减小训练误差而获得好处。随着数据集的不断增大,往往一个数据只会使用一次,甚至只是使用部分训练集,这时过拟合不再是问题,欠拟合和计算效率成为我们需要考虑的问题。
8.2 神经网络优化中的挑战
优化通常是一个非常困难的任务,传统的机器学习会想办法设计目标函数和约束,使得目标函数是凸函数,从而避免优化过程中出现非凸函数的问题。然而,即使是凸函数,也会遇到优化的问题,本节将主要探讨深度学习优化问题中会遇到的挑战。
8.2.1 病态
在优化凸函数的时候,会遇到Hessian矩阵 H 病态的情况。病态情况一般被认为广泛存在于神经网络的训练过程中,体现在随机梯度下降会“卡”在某些特殊的情况,此时即使很小的更新步长也会增加代价函数。回顾之前的代价函数的二阶泰勒展开预测梯度下降的 [图片上传失败…(image-69f034-1524449135535)] 会增加:
[图片上传失败…(image-687d19-1524449135535)]
当 [图片上传失败…(image-e1ccf1-1524449135535)] 超过 [图片上传失败…(image-f81c8a-1524449135535)] 时,梯度的病态会成为问题,很多情况下,梯度的范数不会再训练中显著的减小,但是 [图片上传失败…(image-fe0850-1524449135535)] 的增长会超过一个数量级。结果是,尽管梯度很强,但是学习率必须收缩以弥补更强的曲率,因此学习变得非常缓慢。 有些适合于解决其他情况中的病态的技术并不适用于深度神经网络。比如牛顿法在解决带有病态条件的Hessian矩阵的凸优化问题时,是有效的方法,但是运用到神经网络时需要很大的改动。
8.2.2 局部极小值
在凸优化问题中,优化问题可以简化为寻找一个局部极小值点,因为任何的局部极小值就是全局最小值。虽然有些凸函数底部是一个很大的平坦区域,并非单一的极值点,但是应用过程中实际上该区域中每一个极小值点都是一个可以接受的点。所以说,对于凸优化问题来说,找到任何形式的临界点,就是找到了一个不错的可行解。而对于非凸函数问题,比如神经网络问题,可能会存在很多的局部极小值点。
如果一个足够大的模型可以唯一确定一组模型的参数,那么我们说该模型是可以辨认的。带有潜变量的模型往往是不可辨认的,因为互相交换潜变量,可以得到等价的模型。神经网络代价函数具有非常多甚至是无限多的局部极小值点,而且,由于不可辨识性问题而产生的局部极小值都有相同的代价函数,因此局部极小值点并非是非凸带来的问题。如果局部极小值点相比全局最小值点有很大的代价,那么局部极小值点会带来很大的问题。对于实际使用的神经网络,是否存在很多代价很大的局部极小值点,优化算法是否会碰到这些极小值点都是尚未解决的公开问题。学者们现在猜想,对于足够大的神经网络而言,大部*部极小值都具有很小的代价函数,我们能不能找到全局最小点并不重要,重要的是能够在参数空间里找到一个代价很小的可以接受的点。
8.2.3 高原、鞍点和其他平坦区域
很多高维非凸函数而言,局部极值远少于另一类梯度为零的点:鞍点。在一个鞍点附近,有些方向有更大的代价函数,有些方向有更小的代价函数。在鞍点处,Hessian矩阵同时具有正负特征值,位于正特征值对应的特征向量方向的点比鞍点有更大的代价,负特征值对应的特征向量方向的点比鞍点有更小的代价。鞍点是某个方向的横截面的极大值点,也是另一个方向截面的极小值点。
在低维空间中,局部极值很常见,而在高维空间中,鞍点则很常见。理论上已经证明,不具有非线性的浅层自编码器只有全局极小值和鞍点,没有代价比全局极小值更大的局部极小值点。试验中发现,梯度下降在很多情况下可以逃离鞍点。对于牛顿法而言,鞍点是一个问题,因为梯度下降旨在朝着“下坡”方向移动,而非明确寻找梯度为0的点。如果不经修改,牛顿法就会跳进一个鞍点。而在高维空间中,鞍点激增,所以以牛顿法为代表的二阶方法无法成功取代梯度下降。
8.2.4 悬崖和梯度爆炸
多层神经网络因为有大量的因子相乘,典型的比如循环神经网络,因为长的时间序列会有大量因子相乘,这中情况下存在像悬崖一样的斜率较大的区域,当遇到这种悬崖结构时,梯度更新会很大程度的改变参数的值,进而跳过这样的区域。不管是从上还是从下接近悬崖,都会产生不好的结果。如果采用启发式梯度截断可以避免严重的后果。基本想法在于梯度只是指明了移动的最佳方向,并没有指明最佳步长,因此启发式梯度截断会减小步长,使得梯度下降不太可能一步走出最陡下降方向的悬崖区域。
8.2.5 长期依赖
在一些算中,当计算图变得非常深的时候,会面临一个长期依赖的问题。深层的计算图不仅存在于前馈网络,也存在于循环神经网络中,因为循环神经网络要在很长的时间序列的各个时刻重复应用相同操作来构建非常深的计算图。举个例子,假如某个计算图包含一条反复与矩阵 W 相乘的路径,那么 t步之后,相当于乘以 W^t 。假设 W 有特征分解:
[图片上传失败…(image-d333b8-1524449135535)]
当特征值 lambda_i 不在 1 附近时,若大于1,则会爆炸,若小于1,则会消失。梯度消失与爆炸问题(vanishing and exploding gradient problem)是指该计算图上面的梯度会因 [图片上传失败…(image-3386ba-1524449135535)] 发生大幅度的变化。梯度消失使得我们不知道参数朝哪个方向移动可以快速改进代价函数,而梯度爆炸会使得学习不稳定。循环网络中使用的相同的矩阵 W 并没有在前馈网络中使用,因此即使使用非常深的前馈网络,也能避免梯度消失于爆炸问题。
8.2.6 非精确梯度
大多数优化算法先决条件是我们知道精确的梯度或者是Hessian矩阵,然而在实践中,往往都是有偏的估计,几乎所有的深度学习算法都需要基于采样的估计,比如小批量数据计算更新梯度。有些情况下,我们希望最小化的目标函数实际上是难以处理的,所以此时我们只能使用近似梯度。大多数神经网络算法的设计都考虑到了梯度估计的缺陷,所以选择比真实损失函数更容易估计的代理损失函数来避免这个问题。
8.2.7 局部和全局结构间的弱对应
以上讨论的大都是单点的性质,如果利用梯度下降在某个方向上损失函数改进很大,但是并没有指向全局代价更低的遥远区域,那么单点处表现很好,但是全局表现不佳。有学者认为大部分训练的运行时间取决于到达最终解的路径长度,大多数优化研究难点集中于训练是否找到了全局最小点,局部最小点,鞍点,但是在实践中神经网络并不会达到其中任何一种。
梯度下降和几乎所有可以有效训练神经网络的方法,都是基于局部较小更新。以上的内容都是集中于为何这些局部范围更新的正确方向难以计算,但是难以确定局部下降是否定义通向有效解的足够短的路径。目标函数可能有诸如病态条件或不连续梯度的问题,使得梯度为目标函数提供较好近似的区间非常小。有些情况下,局部下降或许可以定义通向解的路径,但是该路径包含很多次更新,因此遵循该路径会带来很大的计算代价;还有些情况下,局部下降完全无法定义通向解的路径;还有些情况下,局部移动太过贪心,朝着下坡的方向移动,但是却和所以可行解越来越远。
许多现有的研究方法在研究求解具有困难全局结构的问题时,着力于寻找良好的初始点,而不是在局部范围内更新的算法,因为前者实现目标更加可行。
8.2.8 优化的理论限制
一些理论研究表明,我们为任何神经网络设计的任何优化算法都有性能限制,但是,这样的理论上的性能限制并不影响神经网络在实践中的应用。寻找一个给定规模的网络的可行解是困难的,但在现实情况中,我们可以通过选择更大的网络,设置更多的参数,轻松找到可以接受的解。另外,在神经网络中实践中,我们不关注某个函数的精确的极小值点,只要求损失减到足够小以获得可以接受的泛化误差即可。理论研究优化算法的性能上界需要学术界更多的努力。
8.3 基本算法
以上内容已经讲解了神经网络优化的理论指导思想,使用梯度下降和随机梯度下降,可以很大程度上加速模型的训练,代价函数会沿着随机挑选的小批量数据的梯度方向下降。
8.3.1 随机梯度下降
随机梯度下降(SGD)及其变种是一般机器学习中应用最多的优化算法,尤其是在深度学习中。按照数据生成分布 p_{data} 随机抽取 m个小批量(独立同分布,iid)的样本,通过计算它们梯度的均值,得到梯度的无偏估计。下图展示了这个算法的过程:
SGD算法中的一个关键参数是学习率 epsilon_k ,在此之前我们介绍SGD都是使用的固定的学习率,在实践中,随着梯度的降低,有必要逐步减小学习率。由于SGD中随机采样 minibatch 会引入噪声源,因此在极小点处梯度并不会消失。而批量梯度下降使用全量数据更新梯度,在接近极小值点时,梯度很小并逐步变为0,因此,批量梯度下降可以使用固定学习率。与之对比,SGD收敛的一个充分条件是:
[图片上传失败…(image-1092d6-1524449135535)]
[图片上传失败…(image-8ae940-1524449135535)]
在实践中,一般会选择线性衰减学习率知道第 tau 次迭代:
在第 tau 次迭代之后,一般使 epsilon 保持常数。学习率可以通过实验误差的演变曲线来选取,如果初始 epsilon_0 选取的过大,则会出现损失上升和震荡,而如果 epsilon_0 选取的过小,学习过程会过于缓慢。
SGD及其相关的小批量,或者是更广义的基于梯度优化的在线学习算法,一个重要的性质是每一步更新的计算时间不依赖与总的训练样本的多少。即使总的数据集很大,它也能收敛,而且SGD往往在处理完整个训练集之前就收敛到可接受的误差范围之内。
研究算法的收敛率,一般会衡量额外误差(excess error) [图片上传失败…(image-9a0cd-1524449135535)] ,也即当前代价函数超出最低可能代价的量。SGD应用于凸问题时,k步迭代之后误差的量级是 [图片上传失败…(image-b1d3a3-1524449135535)] ,在强凸情况下误差量级是 [图片上传失败…(image-204351-1524449135535)] 。在没有额外假设和辅助信息之下,以上的界限不能进一步改进。批量梯度下降理论上SGD有更好的收敛率,然而有学者研究指出,泛化误差的下降速度不会快于 [图片上传失败…(image-152859-1524449135535)] ,因此对于机器学习算法而言,不值得探索收敛快于 [图片上传失败…(image-a983cb-1524449135535)]的优化算法,因为往往过快的收敛对应着过拟合。对于大数据集,SGD只需要少量的样本计算梯度从而实现初始快速更新。但是由SGD损失了常数倍 [图片上传失败…(image-3ed4bd-1524449135535)] 的渐进分析,我们可以在学习中逐渐增大小批量的batch大小,以此权衡并充分利用批量梯度下降和随机梯度下降两者的优点。
8.3.2 动量
SGD是最受欢迎的优化算法,但是其学习过程有时会有点缓慢,动量方法旨在加速学习过程,特别是处理高曲率,小但一致的梯度,或者是带有噪声的梯度。动量算法积累了之前梯度指数级衰减的移动平均,并且继续沿该方向移动。从形式上看,动量算法引入了变量 v充当速度角色-代表参数在参数空间移动的方向和速率,速度被认为是负梯度的指数衰减平均。动量这个名词的引入也是为了类比物理当中的动力概念。超参数 alpha 决定了之前的梯度贡献衰减得有多快,更新规则如下:
[图片上传失败…(image-54596b-1524449135535)]
速度 v 累积了梯度元素 [图片上传失败…(image-ad7491-1524449135535)] ,相对于 epsilon, alpha 越大,之前梯度对现在方向的影响也越大。
在之前的SGD或者批量梯度下降中,步长只是梯度范数乘以学习率,现在,步长取决于梯度序列的大小和排列,当许多连续的梯度指向相同的方向时,步长最大,如果动量算法始终观察到梯度 g ,那么它会在 -g 的方向上不断的加速。其中,步长大小为:
[图片上传失败…(image-63fa76-1524449135535)]
因此将动量方法的超参数视为 [图片上传失败…(image-326dd5-1524449135535)] 有助于SGD类比理解。比如, [图片上传失败…(image-f2ae01-1524449135535)] 对应着最大速度10倍于梯度下降算法。在实践中,一般 alpha 会取值为0.5, 0.9和0.99,和学习率一样, alpha 也会随着时间不断地调整。一开始取比较小的值,逐渐变大,随着训练的深入,调整 alpha 没有收缩 epsilon 重要。
8.3.3 Nesterov 动量
受Nesterov加速梯度算法的启发,Sutskever等人提出了动量算法的一个变种,更新规则如下:
参数 alpha 发挥了和标准动量方法中类似的作用,Nesterov动量和标准动量之间的区别在于梯度的计算上。Nesterov动量中,梯度计算在施加当前速度之后,可以理解为Nesterov 动量往标准动量方法中添加了一个校正因子。在凸优化问题使用批量梯度下降的情况下,Nesterov 动量将 k 步之后额外误差收敛率从 [图片上传失败…(image-45126b-1524449135535)] 提高到 [图片上传失败…(image-da0aaa-1524449135535)] ,对SGD没有改进收敛率。完整的 Nesterov动量算法如下所示:
8.4 参数初始化策略
有些算法本质上是非迭代的,只是求解一个点。而有些其他优化算法本质上是迭代的,应用这类优化问题时,能在可接受的时间内收敛到可接受的解,并且收敛值与初始值无关。深度学习的模型通常是迭代的,因此要求使用者制定一些开始迭代的初始点。另外,深度学习模型又是一个很复杂的问题,以至于大部分算法的结果收到初始值的影响。初始点能决定算法是否收敛,有些初始点十分不稳定,使得算法会遭遇数值困难,并完全失败。在收敛的情形下,初始点可以决定学习收敛的有多快,以及是否收敛到一个代价高或者低的点。另外,差不多代价的点可以导致区别极大的泛化误差,初始点可以影响泛化。
现代机器学习乃至深度学习和神经网络的初始化策略是简单和启发式的,改进初始化是一项困难的任务。神经网络的优化到目前都没有被很好的理解。有些初始化策略在神经网络初始化时具有很好的效果,然而我们并没有理解哪些性质可以在初始化之后得意保持。进一步,有些初始化从优化的观点是有利的,但是从泛化的角度看是不利的。
目前完全确信的唯一特性是初始参数需要在不同的单元之间“破坏对称性”。比如,如果具有相同**函数的两个隐藏单元连接到相同的输入,那么这些单元必须具有不同的初始化参数。如果他们具有相同的参数,那么应用到确定性损失和模型的确定性学习算法之上时将会一直以相同的方式更新这两个单元。通常来说,最好还是初始化每个单元使其和其他单元计算不同的函数,这或许有助于确保没有输入模式丢失在前向传播的零空间中,也没有梯度丢失在反向传播的零空间中。每个单元计算不同的函数的目标促使了参数的随机初始化。
我们几乎总是初始化模型的权重为高斯或者均匀分布中随机抽取的值,两者似乎没有很大的区别,然而初始分布的大小确实对优化过程的结果和网络的泛化能力都有很大的影响。
更大的初始权重具有更强的破坏对称性的作用,有助于避免冗余的单元,也有助于避免在每层线性成分的前向或反向传播中丢失信号。如果权重初始太大,那么会在前向或者反向中产生爆炸的值。对于初始化网络,正则化和优化有着不同的观点:优化观点建议权重应该足够大以成功传播信息,正则化则希望参数小一点以降低模型复杂度。
很多启发式的方法可用于选择权重的初始大小。一种初始化 m 个输入和 n 个输出的全连接层的权重启发式方法是从分布
中采样权重,而 Glorot 和 Bengio 建议使用标准初始化(normalized initialization):
后一种启发式方法初始化所有的层,目的在于使其处于具有相同**方差和使其具有相同的梯度方差之间。虽然这种假设网络是不含有非线性的链式矩阵乘法,现实的神经网络会违反这个假设,但是很多设计给线性模型的算法在非线性模型上面都有很好的效果。
如果计算资源允许,将每层权重的初始值范围设定为一个超参数通常是一个好主意,比如随机搜索来进行参数挑选。是否选择使用密集或者稀疏初始化也可以设置为一个超参数,当然我们也可以选择手动搜索最优初始范围。以上都是关注权重的初始化,其他参数的初始化通常是更加容易的。初始化偏置的方法必须和初始化权重的方法相协调,通常大部分情况下将偏置设置为0是可行的方案。当然,存在以下这些需要将初始化偏置为非0的情形:
- 偏置作为输出单元,初始化偏置以获得正确的输出边缘统计通常是有利的
- 有时需要选择偏置以避免初始化引起太大饱和
- 有时一个单元会控制其他单元能否参与到等式中
上面这些初始化模型参数为常数或者随机算法,实践中还可以利用机器学习来初始化网络参数。一个常用的策略是使用无监督模型训练出来的参数来初始化监督模型。 即使是在一个不相关的问题上运行监督训练,往往也会得到一个比随机初始化更快收敛的初始值(类似于迁移学习)。这些新式的初始化策略有时能够得到更好的泛化误差和更快的收敛速度,因为它们编码了模型初始参数的分布信息。之前的其他初始化策略效果也不错的原因主要在于设置了正确的参数范围,或者是设置不同单元计算互相不同的参数。
8.5 自适应学习率算法
学习速率对神经网络的性能有着显著的影响,损失通常高度敏感于参数空间的某些方向,而对其他因素不敏感。动量算法可以一定程度上缓解这个问题,但代价是引入了另一个超参数。如果我们相信方向敏感度在某种程度是轴对齐的,那么给每个参数设置不同的学习率,在模型学习训练过程中自动适应这些学习率是有道理的。早期的一个模型训练时候的启发式算法 Delta-bar-delta算法,基于简单的想法:如果损失对于某个给定模型参数的偏导符号保持不变,那么学习率应该增大,如果对于该参数的偏导的方向发生了变化,那么学习率应该减小。这种方法只适用于全批量优化中。本节将介绍最近提出的几种基于小批量的算法来自适应模型参数的学习率。
8.5.2 RMSProp
RMSProp由Hinton于2012年提出,用于修改AdaGrad以在非凸设定下效果更好,将梯度积累改变为指数加权的移动平均。AdaGrad设计以让凸问题能够快速的收敛。当应用于非凸函数训练神经网络时,学习轨迹可能穿过了很多不同的结构,最终到达一个局部是凸碗的结构。AdaGrad根据平方梯度的整个历史来收缩学习率,学习率很可能在到达这样的凸碗结构之前就变得太小。而RMSProp使用指数衰减平均,丢弃遥远过去的历史,使其能够在找到凸碗结构后快速收敛,该算法等效于一个初始化与该碗状结构的AdaGrad算法。实践中和经验上,RMSProp已经被证明是是一种有效而且实用的深度神经网络优化算法,目前是深度学习从业者经常采用的优化方法之一。
RMSProp的标准形式和结合Nesterov动量的形式如下图所示,相比AdaGrad,引入了一个新的超参数 rho ,用来控制移动平均的长度范围。
8.5.3 Adam
Adam (adaptive moments),在早期算法的背景下,最好被看成结合RMSProp和具有一些重要区别的动量的变种。首先,在Adam中动量直接并入了梯度一阶矩(指数加权)的估计。将动量加入RMSProp最直观的方法是将动量应用于缩放后的梯度。其次,Adam包括偏置修正,修正从原点初始化的一阶矩(动量项)和二阶矩(非中心项)。Adam通常被认为对超参数的选择相当鲁棒,尽管学习率有时需要从建议的默认值修改。
8.5.4 选择正确的优化算法
本节以上部分讨论了一系列通过自适应每个模型参数的学习率以解决优化深度模型中的难题,究竟在实践中该如何选择并没有定论。目前来说,最流行并且使用率很高的优化算法包括SGD,有动量的SGD,RMSProp,有动量的RMSProp,AdaDelta 和 Adam,选择哪一个算法主要取决于使用者对特定算法的熟悉程度以便调节超参数。
算法总结:基于动量和基于自适应学习率的优化算法都是从梯度下降SGD演化而来,算法的细节之处对比如下图:
8.6 二阶近似方法
本节会讨论用于训练深度神经网络的二阶方法。为简单起见,只讨论目标函数为经验风险(暂时不考虑正则化项)
8.6.1 牛顿法
与一阶方法相比,二阶方法使用二阶导数改进了优化,最广泛使用的是牛顿法。牛顿法是基于二阶泰勒级数展开在某点 theta_0 附近来近似 theta 的方法,忽略了更高级的导数
其中 H 是 J 相对于 theta 的Hessian矩阵在 theta_0 处的估计。如果我们基于上式求解这个函数的临界点,得到牛顿参数的更新规则
因此,对于局部的具有正定 H 的二次函数,用 H^{-1} 调整梯度,牛顿法会直接跳到极小值,如果目标函数是凸的但非二次,该更新将是迭代的,得到的相关算法如下。对于非二次的表面,只要Hessian矩阵保持正定,牛顿法就能够迭代应用。
牛顿法只适用于Hessian矩阵是正定的情况,而在深度学习中,目标函数的表面通常是非凸的,因此使用牛顿法是有问题的,这种情况下可以通过正则化Hessian矩阵来避免,常用的方法是在Hessian矩阵对角线上增加常数 alpha: