往期回顾:
04——从传统机器学习走向深度学习
05——深度前馈网络、神经网络概述
06——深度学习中的正则化
介绍了神经网络的基本构件和正则化策略之后,学习一下深度模型中的优化。先说一说传统的纯优化与机器学习中的优化的异同,再介绍一下神经网络中优化的挑战,最后说说基本的优化算法。(参考《深度学习》第8章)
一、机器学习中的优化
传统的优化方法是纯优化最小化目标 J 本身,而机器学习的优化是间接作用的。在机器学习问题中,我们关注某些性能度量 P ,其定义于测试集上并且是不可解的。因此机器学习希望通过降低代价函数 J(θ)来间接提高 P 。
1. 经验风险最小化
机器学习算法的目标是降低期望泛化误差这被称为风险。此时数据取自真实的潜在分布,然而,我们遇到的问题通常并不清楚真实分布,只知道训练集中的样本。
我们将机器学习中的优化转换回一个优化问题的最简单方法就是最小化训练集上的期望损失,以训练集上的经验分布替代真实分布,此时我们最小化的就是经验风险。基于这种训练误差的训练过程称为经验风险最小化,此时机器学习仍然和传统的直接优化相似。
然而经验风险最小化很容易导致过拟合,因此深度学习中我们很少使用经验风险最小化,而是使用不同的方法。
2. 代理损失函数
有时,我们真正关心的损失函数并不能被高效的优化,例如0-1损失函数通常不可解。我们因此会优化代理损失函数,例如负对数似然通常用作 0-1 损失的替代。
在一些情况下,代理损失函数比原函数学的更多。例如,使用对数似然函数在训练集上的 0-1 损失达到 0 之后,测试集上的 0-1 损失还能持续下降很长时间。这是因为即使 0-1 损失的期望是 0 ,我们还能拉开不同类别的距离以改进分类器的鲁棒性,获得一个更强壮的分类器。
3.批量算法和小批量算法
机器学习算法和一般优化算法不同的一点是,机器学习算法的目标可以分解为训练样本上的求和。 机器学习中的优化算法在计算参数的每一次更新时通常仅使用整个代价函数的一部分项来估计代价函数的期望值。
例如最大似然估计问题可以在对数空间中分解为各个样本的总和,同时优化算法用到的目标函数 J 中大多数属性也是训练集上的期望。eg:准确计算这个期望的代价很大,因此我们可以从数据集中随机采样少量的样本,然后计算这些样本的平均值。
n 个样本均值的标准差是 。分母表明使用更多的样本估计梯度的方法是低于线性的,因此在计算量加倍的情况下,标准差只降低了根号倍,如果能够快速计算出梯度估计值,而不是缓慢计算准确值,那么大多数优化算法会收敛更快。
另外,大量样本很可能对于梯度都做出了非常相似的贡献,这种冗余也促使我们选择 。
使用整个训练集的优化算法称为批量(batch) 或确定性(deterministic) 梯度算法,因为它们会在一个大批量中同时处理所有样本。
每次只使用单个样本的优化算法称为随机(stochastic) 或 **在线(online)**梯度算法。
大多数深度学习算法介于两者之间,称为小批量(minibatch)。
小批量大小的决定:
- 更大的批量有更精确的梯度估计,但回报小于线性。
- 极小批量难以充分利用多核架构,因此我们会使用一些绝对最小批量,低于这个值的批量不会减少计算时间。
- 如果批量处理的所有样本可以并行的处理,那么内存消耗和批量大小会正比。
- 在某些硬件上使用特定大小的批量会减少运行时间。比如使用GPU是,通常使用2的幂数作为批量大小可以获得更少的运行时间。
- 由于在使用小批量进行加入了噪声,它们会有一定的正则化效果,且批量越小正则化效果越好,但因为梯度估计的高方差,小批量训练需要较小的学习率以保持稳定性。
小批量必须要随机抽取,我们希望两个连续的梯度估计是独立的,因此两个连续的小批量样本应该是彼此独立的。、
二、神经网络优化中的挑战
1. 病态
病态体现在随机梯度下降会“卡”在某些情况,此时即使很小的更新步长也会增加代价函数。而很多适用于其他情况的解决病态的技术并不适用于神经网络。例如,牛顿法在解决带有病态条件的 Hessian 矩阵的凸优化问题时是一个非常优秀的工具,但是应用于神经网络时需要很大的改动。
2. 局部极小值
对于如神经网络的非凸函数,由于模型可辨识性问题,神经网络和任意具有多个等效参数化潜变量模型都会具有多个局部极小值。如果一个足够大的数据集可以唯一确定一组模型参数,那么称该模型是可辨认的。而带有潜变量的模型通常是不可辨认的,因为相互交换潜变量的模型是等价的。这被称为权重空间对称性。
此外,在任意整流线性网络或 maxout 网络中,我们将传入权重和偏置扩大α倍,然后将传出权重扩大1/α倍, 此时模型仍是等价的。因此此类神经网络的每一个局部极小值点都在等价的局部极小值的(m x n)维双曲线上。但这些并不是由于非凸带来的问题,而是由不可辨识性产生的。
如果局部极小值拥有很大的代价,这会产生很大的隐患,对于实际中的神经网络,是否存在大量代价很高的局部极小值,优化算法是否会碰到这些局部极小值,都尚未解决。现在学者们猜想,对于足够大的神经网络而言,大部分局部极小值都具有很小的代价函数,因此我们能否找到真正的全局最小点并不重要,我们只需找一个代价很小的点。
3. 高原、鞍点和其他平坦区域
在高维空间中,除了局部极小点,很多其他结构也具有很小的梯度。并且事实上局部极小值远少于另一类梯度为零的点:鞍点。在鞍点处, Hessian 矩阵同时具有正负特征值。我们可以将鞍点视为代价函数某个横截面上的局部极小点,同时也可以视为代价函数某个横截面上的局部极大点。
鞍点对于只使用梯度信息的一阶优化的影响尚未明确,梯度下降在实验中可以在许多情况下逃离鞍点。
而对于牛顿法而言,鞍点就是很大的问题,因为它梯度为0,那么牛顿法会很容易就跳进鞍点。因此神经网络训练中二阶方法很少会使用,尽管有二阶优化的无鞍牛顿法但是难以扩展到大型网络,如果无鞍算法能够扩展,那么二阶优化很有希望。
除了点,还可能存在恒值的,宽且平坦的区域,此时梯度和 Hessian 矩阵都是零。这种退化的情形是所有数据优化算法的主要问题。对于一般的优化问题,这样的区域可能对应着目标函数中一个较高的值。
4. 悬崖和梯度爆炸
多层神经网络通常存在像悬崖一样斜率较大区域,这是由于几个较大的权重相乘导致的。此时梯度更新会很大程度的改变参数值,以至于完全跳过悬崖结构。
因此我们可以使用启发式的梯度截断来避免跳过悬崖可能导致的严重后果。基本思想是梯度并没有指明最佳步长,只是说明了最佳方向。当传统的梯度下降提议更新很大一步时,启发式梯度截断就会干涉来减少步长。
悬崖结构在循环神经网络的代价函数中很常见,因为它会涉及多个因子相乘。
5. 长期依赖
当计算图变得极深时,神经网络算法还会面临长期依赖问题——由于变深的结构使模型丧失了学习到先前信息的能力,让优化变得困难。尤其是循环神经网络,更会产生这种问题。
6. 非精确梯度
大多数优化算法的先决条件都是我们知道精确的梯度,但在实践中,梯度通常会有噪声,甚至是有偏的估计。
此外,如果我们的目标函数是难以处理的,通常其梯度也很难处理。我们只能近似梯度。
各种神经网络优化算法都考虑到了梯度估计的缺陷。我们可以选择代理损失函数来避免这个问题。
7. 局部和全局结构的弱对应
如图,如果局部表面没有指向全局解,基于局部下坡移动的优化可能就会失败。即使没有鞍点或局部极小值,图中的代价函数仅包含朝向低值而非极小值的渐近线。
造成这种现象的主要原因就是初始化在“山”错误的一侧,并且无法遍历。在高维空间中,学习算法通常会绕过高山,但相关的轨迹会很长,导致了过长的训练时间。
许多现有的解决办法是在求解具有困难全局结构的问题是,旨在寻找良好的初始点,而非开发非局部范围更新的算法。
除了上图梯度信息提供了完全相反的信息,还有在高原等平坦区域,梯度信息完全不能提供任何有用信息。两者都是当前研究的热点。
如果存在一个区域,我们遵循局部下降便能合理地直接到达某个解,并且我们能够在该良好区域上初始化学习,就可以避免这种问题。因此目前的解决方法就是有一个良好的初始化。
8. 优化的理论限制
一些理论研究表明,我们为任何神经网络设计的任何优化算法都有性能限制,但是,这样的理论上的性能限制并不影响神经网络在实践中的应用。寻找一个给定规模的网络的可行解是困难的,但在现实情况中,我们可以通过选择更大的网络,设置更多的参数,轻松找到可以接受的解。另外,在神经网络中实践中,我们不关注某个函数的精确的极小值点,只要求损失减到足够小以获得可以接受的泛化误差即可。理论研究优化算法的性能上界需要学术界更多的努力。
三、基本优化算法
1. 随机梯度下降
随机梯度下降(SGD)按照数据生成分布抽取 m 个小批量样本(独立同分布),通过计算它们的梯度均值,我们就可以得到梯度的无偏估计。具体算法如下:
SGD算法的关键参数就是学习率,在实践中,有必要随时间的推移逐渐降低学习率,因此我们将第 k 步迭代的学习率记作 。这是因为 SGD 中梯度估计引入的噪声源并不会在极小点处消失,而批量梯度下降可以使用固定的学习率。
保证 SGD 收敛的一个充分条件是且
因此我们一般会线性衰减学习率直到第次迭代:其中,在τ步之后学习率保持常数。
学习率可以通过实验和误差来选取,通常最好的办法是监测目标函数值随时间变化的学习曲线。其中主要要考虑的是初始学习率的选择,若太大,学习曲线会剧烈震荡,代价函数值会明显增加。温和的震荡是良好的。而学习率太小,学习过程会很缓慢,且容易卡在一个相当高的代价值。最好的方法是检测最早的几轮迭代,选择一个比在效果上表现最佳的学习率更大的学习率,但又不至于太大。
SGD 及相关的小批量和在线学习算法,一个重要的性质就是每一步更新的计算时间不依赖训练样本数目的多寡。即使训练样本数目很大,他们也能收敛。
研究优化算法的效率,一般会衡量额外误差(excess error) ,即当前代价函数超出最低可能代价的量。 SGD 应用于凸问题时, k 步迭代后额外误差量级为 ,批量梯度下降在理论上比随机梯度下降有更好的收敛率。然而,Cramér-Rao界限指出,泛化误差的下降速度不会快于,因此对于机器学习任务不值得寻找比这收敛更快的优化算法——会造成过拟合。此外,SGD 可以实现初始快速更新,远远超过了缓慢的批量梯度下降。
2. 动量
虽然 SGD 有诸多优点,但其学习过程有时会很缓慢。动量方法旨在加速学习,特别是处理高曲率、小但一致的梯度,或是带噪声的梯度。动量算法积累了之前梯度指数级衰减的移动平均,并且继续沿着该方向移动。效果如图:
动量算法引入了变量充当速度角色——代表参数在参数空间移动的方向和速率。速度被设为负梯度的指数衰减平均。动量来自物理,由牛顿运动规律,负梯度是移动参数空间中粒子的力。我们假设粒子是单位质量,因此速度向量可以看作粒子的动量。超参数是衰减率,决定了梯度的贡献衰减率。具体的更新规则为:
相对于越大,之前梯度对于现在方向的影响也越大。带动量的算法如下:
当许多连续的梯度指向相同的方向时,步长最大,最大速度为因此超参数可以理解为,当α为0.9时,对应着最大速度为梯度下降的10倍。α也可以随着时间的推移进行调整。
3. Nesterov 动量
这是动量算法的一个变种,更新规则为:它和标准动量之间的区别体现在梯度计算上,梯度计算在施加当前速度之后。因此 Nesterov 动量可以解释为添加了一个校正因子。
在凸批量梯度的情况下, Nesterov 动量将额外误差收敛率从 O(1/k)改进到O(1/k2 )。但是对于随机梯度,它并没有改进收敛效率。
四、参数初始化策略
深度学习中,初始点的选择非常重要,它能够决定算法是否收敛,收敛的速度,以及最终收敛的代价的高低。另外,代价差不多的点可以有区别极大的泛化误差,初始点也影响了泛化。
然而现代的初始化策略是简单的、启发式的。由于神经网络优化还未被很好地理解,因此设定改进的初始化策略是一项困难的任务。大多数初始化策略都是基于在神经网络初始化时实现一些很好的性质,但是这些性质在学习开始后在什么情况下还能保持仍不明确。此外,一些初始点对于优化是有利的,但是对于泛化是不利的。
目前我们只知道初始参数需要在不同单元间”破坏对称性“。相同的激活函数且接受两个相同输入的隐藏单元必须具有不同的初始参数,否则它们将一直以相同的方式更新。
通常情况下,我们可以为每个单元的偏置设置启发式挑选的常数,仅随机初始化权重。一般我们初始化模型的权重为高斯或均匀分布中随机抽取的值。初始分布的大小确实对优化过程的结果和网络泛化能力有很大的影响。
更大的初始权重具有更强的破坏对称性的作用,避免了冗余的单元。它们也有助于避免在每层线性成分的前向或反向传播中丢失信号。但如果初始权重太大,那么会出现数值上溢,梯度爆炸,并且使一些激活函数饱和。以上因素决定了权重的理想大小。
一些启发式的方法可用于选择权重的初始大小。如 Glorot 和 Bengio 建议标准初始化
但是这些准则并不能带来最佳效果。如之前所说,首先我们可能使用了错误的标准;其次初始化时强加的性质并不能在学习开始后保持;最后,标准可能提高了优化速度,但是增大了泛化误差。
更多关于权重初始化策略请看:
神经网络中的权重初始化一览:从基础到Kaiming
聊一聊深度学习的weight initialization
除了权重,其他参数的初始化通常更容易。
设置偏置的方法必须和设置权重的方法协调。设置偏执为 0 在大多数权重初始化方案中是可行的。存在一些非零情况:
- 偏置作为输出单元,初始化偏置以获得正确的输出边缘统计通常是有利的
- 有时需要选择偏置以避免初始化引起太大饱和
- 有时一个单元会控制其他单元能否参与到等式中
除了简单常数或随即方法,还有可能使用机器学习初始化模型参数。例如使用相同的输入数据集,用无监督模型训练出来的参数来初始化监督模型。而欧美让你也可以在另一个相关问题上使用监督训练,来得到一个比随机初始化有更快收敛率的初始值。
五、自适应学习率算法
学习率同样对于模型的性能有显著的影响。这里介绍一些增量的算法以自适应模型参数的学习率。
1. AdaGrad
算法如图所示:
缩放每个参数反比于其所有梯度历史平方值总和的平方根。具有损失最大偏导的参数相应的有一个快速下降的学习率,而具有较小偏导的参数在学习率上有相对较小的下降。净效果是在参数空间中更平缓的倾斜方向会取得更大的进步。
尽管 Adagrad 在凸优化中理论性质较好。但是经验上发现对于深度神经网络,从训练开始时积累梯度平方会导致有效学习率过早和过量的减小。
2. RMSProp
RMSProp 算法修改 AdaGrad 以在非凸设定下效果更好,改变梯度积累为指数加权的移动平均,使其能够在找到凸碗状结构后快速收敛。它的标准形式如图:
结合 Nesterov 动量的算法如图
RMSProp 经验上已经被证明是一种有效且实用的优化算法。
3.Adam
Adam 是另一种学习率自适应的优化算法。如图所示:
Adam 对于超参数的选择相当鲁棒,一般遵循建议。
对于自适应的学习率策略,更多请看:
Sebastian Ruder—An overview of gradient descent optimization algorithms
损失函数的等高图和不同算法的演化迭代收敛时间:
鞍点附近的各个算法的工作图,注意到红色的SGD路径在鞍点处花了很长时间才找到下降的方向,而RMSProp很快就找到了更快下降的方向:
4. 选择正确的优化算法
具有自适应的学习率的算法族表现得相当鲁棒,不分伯仲,因此没有最好的算法。使用哪个算法主要取决于使用者对于算法的熟悉程度(以调节超参数)。
六、二阶近似方法
1. 牛顿法
牛顿法是基于二阶泰勒级数展开在某点附近来近似的优化方法,其忽略了高阶导数:我们求解这个函数的临界点,得到牛顿参数更新规则:因此对于局部的二次函数(H 正定),用 H逆 来重新调整梯度,牛顿法会直接跳到极小值。若目标函数是凸的但非二次,该更新是迭代的。对于非二次的表面,只要 Hessian 矩阵保持正定,牛顿法就能迭代地应用。
然而在深度学习中,目标函数的表面通常非凸,如鞍点。因此使用牛顿法是有问题的。此时可以正则化 Hessian 矩阵来避免。常用的正则化策略是在 H 对角线上增加常数 α 。只要 Hessian 矩阵的负特征值仍然相对接近零,效果就会很好。
除了目标函数带来的挑战,牛顿法在大型神经网络训练中还受限制于庞大的计算负担。如果有 k 个参数,那么牛顿法需要计算 k×k 的矩阵的逆,计算的额复杂度是 O(k3)。另外由于每次训练迭代都要计算Hessian矩阵及其逆矩阵,所以只有参数很少的网络才能在实际中使用牛顿法。至于用于更大规模的网络训练,本节以下将讨论一些保持牛顿法优点,同时减小计算量的替代算法。
2. 共轭梯度
共轭梯度是一种通过迭代下降的共轭方向 以有效避免 Hessian 矩阵求逆计算的方法。在共轭梯度法中,我们寻求一个和先前线搜索方向共轭的搜索方向,即它不会撤销在该方向上的进展。在训练迭代 t 时,下一步的搜索方向为其中 β 的大小控制着我们应该沿方向 dt−1 上加回多少道当前搜索方向上。
如果则两个方向 和是共轭的。适应共轭的直接方法涉及 H 的特征向量的计算以选择 ,但我们可以不进行计算额得到共轭方向。有两种计算 βt 的方法,一种是 Fletcher-Reeves方法,另一种是 Polak-Ribiere 方法。具体的算法如图:
上面的算法是用于二次函数目标函数的共轭梯度法。在深度学习中,目标函数复杂得多,但共轭梯度却依然是适用的,但需要做一些修改。此时共轭方向不在保证以前方向上的目标仍是极小值。
3. BFGS
BFGS算法具有牛顿法的一些优点,但没有牛顿法的计算负担。拟牛顿法是使用矩阵 Mt 近似逆,迭代地更新精度以更好地近似 H-1,此时下降方向为,该方向上的线搜索决定该方向上的步长,参数最后更新为相比于共轭梯度,BFGS的优点是能花费较少的时间改进每个线搜索。但是BFGS算法必须要存储 Hessian 逆矩阵 M,需要的额外空间,不适用于大型深度学习模型。作为改进,存储受限的BFGS(或者称为L-BFGS)通过避免存储完整的Hessian逆近似M,使得存储代价显著降低。
七、优化策略和元算法
许多优化技术并不是真正的算法,而是一般化的模板。
1. 批标准化
批标准化是一个自适应的重参数化方法,试图解决训练非常深的模型的困难。重参数化显著减少了多层之间协调更新的问题,可以用于网络的任何输入层或者是隐藏层。设 H 是需要标准化的某层的小批量激活函数,排布为设计矩阵,每个样本的激活层出现在矩阵的每一行中。为了标准化 H ,我们将其替换为其中是包含每个单元均值的向量。是包含每个单元标准差的向量。此处的算术是基于广播向量应用于 H 的每一行。在每一行内运算是逐元素的。
在训练阶段,其中δ是很小的值。
我们反向传播这些操作,来计算均值和标准差,并应用它们于标准化 H 。
在测试阶段,和可以被替换为训练阶段收集到的运行均值,使得模型可以对单一样本评估。
标准化一个单元的均值和标准差会降低包含该单元的神经网络的表达能力,为了保持网络的表现力,通常会将批量隐藏单元激活替换为,允许新变量有任意的均值和标准差。新的参数均值仅取决于β,而旧的参数均值取决于下层复杂的关联。因此新参数很容易通过梯度下降来学习。
通常推荐将批标准化应用于变换后的激活值。
2. Polyak 平均
Polyak 平均会平均优化算法在参数空间访问轨迹中的几个点。如果 t 次迭代梯度下降访问了点那么 Polyak 算法的输出是对于凸的问题,这种方法拥有较强的保证。对于神经网络,它在实践中表现良好。基本想法是优化算法可能会来回穿过山谷好几次而没经过山谷底部,因此均值应该比较接近谷底。
应用于非凸问题时,通常会使用指数衰减计算平均值:
3.监督预训练
有时候,如果模型太复杂或是任务非常困难,直接训练模型太难。有时训练一个较简单的模型来求解问题,然后使模型更复杂会更有效。训练模型求解一个简化的问题,然后转移到最后的问题,有时也会更有效。这些方法统称为预训练。
贪心算法将问题分解成多个部分,然后独立的在每个部分求解最优值,虽然结合各个最佳的部分不能保证得到一个最佳的完整解,但贪心算法计算上更加高效,它的解也是可以接受的。并且可以紧跟一个精调阶段,联合优化算法搜索全问题的最优解。
贪心预训练在深度学习中普遍存在。具体是将监督学习问题分解成其他简化的监督学习问题的预训练算法。这种方法称为贪心监督预训练。这有助于更好地指导深层结构中间层的学习。一般情况下,预训练对于优化和泛化都是有帮助的。
另一个相关的工作线是 FitNets 方法。这种方法始于训练深度足够低和宽度足够大,同意训练的网络。然后这个网络成为第二个网络的老师。学生网络更深更窄,且在正常情况下很难用 SGD 训练。训练学生网络不仅需要预测原任务的输出,还需要预测教师网络的中间层的值。这样使得训练学生网络变得更容易。
4. 设计有助于优化的模型
在实践中,选择一族容易优化的模型比使用一个强大的算法更重要,神经网络学习在过去的大部分进步主要来自改善模型族。
现代神经网络的设计选择体现在层之间的线性变换,几乎处处可导的激活函数和大部分定义域都有明显梯度。创新的模型如 LSTM, ReLU , maxout 都比先前的模型使用更多的线性函数。现代神经网络的设计方案旨在使其局部梯度信息合理地对应着移向一个遥远的解。
其他的模型设计策略简化了优化,例如层之间的线性路径或是跳跃连接减少了从较低层参数到输出最短路径的长度,从而缓解了梯度消失的问题。此外还可以添加和网络中间隐藏层相连的输出的额外副本,如 GoogLeNet 和 深度监督网络。这些额外的输出于网络顶层输出相同的任务,以确保底层网络能接受较大的梯度。
5. 延拓法和课程学习
延拓法是一族通过挑选初始点使优化更容易的方法。以确保局部优化花费大部分时间在表现良好的空间。它的背后思想是构造一系列具有相同参数的目标函数。为了最小化代价函数,我们构建新的代价函数,这些代价函数的难度逐步提高。真正的代价函数驱动整个过程。 这里的难度是指在参数空间上表现良好的区域大小。这一系列代价函数设计为前一个解是后一个解的良好初始点。
这些连续的方法会通过“模糊”原来的代价函数来构造更容易的代价函数,有些非凸函数在模糊之后就变成了近似凸函数,而且这种模糊保留了关于全局极小值的足够信息以供算法学习。尽管局部极小值问题已不再是神经网络优化的主要问题了,延拓法仍然有所帮助。因为它引入的简化目标函数能够消除平坦区域,减少梯度估计方差,提高 Hessian 矩阵的条件数,使局部更新更容易计算。
Bengio 指出被称为课程学习或者塑造的方法可以被解释为延拓法。课程学习基于规划学习的想法,首先学习简单的概念,然后逐步学习依赖于这些简单概念的复杂概念。比如:教师通常会先展示更容易更典型的实例给学生,然后慢慢过渡到复杂的实例,在人类教学上,课程学习的策略比基于样本均匀采样的策略更为有效。
以上内容如有谬误还请告知。
来源:CSDN
作者:wby1905
链接:https://blog.csdn.net/wby1905/article/details/104132012