第4章 数值计算
基本概念
- softmax函数,解决上溢和下溢
- 病态条件,函数相对于输入的微小变化而剧烈变化。【条件数指的是函数相对于输入的微小变化而变化的快慢程度】
- 目标函数:在求解机器学习问题时需要最大化或者最小化的函数目标。记作 。【损失函数:最小化函数目标】
- 导数:对于单变量函数f(x)来说,其导数f′(x)表示在f(x)在x的斜率大小(函数在x的变化率)。
- 偏导数:多变量函数针对某单一变量的导数,例如f(x,y)相对与x的偏导数为 。
- 梯度:梯度是一个向量,向量中的元素是函数的偏导数,对于f(x,y)来说,其梯度∇f=(
,
)。梯度表示函数在当前变化最快的方向。
- 一维情况下,
临界点
是斜率为零的点。 - 多维情况下,
临界点
是梯度中所有元素都为零的点。
- 一维情况下,
- 梯度下降法:根据导数的计算公式,可以有f(x+ϵ)≈f(x)+ϵf′(x),为了求到目标函数的最小值,我们可以将x向梯度的相反方向移动一小段距离来进行逼近。
- 一阶优化算法:仅适用梯度信息的优化算法,如梯度下降法。
- 二阶优化算法:使用海森矩阵进行优化的算法,如牛顿法。
- 雅克比矩阵(Jacobian Matrix):对于函数f:Rm→Rn,其雅克比矩阵J∈Rn×m被定义为 。
雅可比矩阵是一阶偏导数以一定方式排列成的矩阵
雅可比矩阵重要之处在于它能够体现一个可微方程与给出点(设该点为点A)的最优线性逼近,因此雅可比行列式可用于求解点A的微分方程组(多变数向量函数)的近似解。
雅可比矩阵就是微分映射的坐标表示。微分映射本身也是一个线性映射,既然是线性映射我们就可以把它坐标化成一个矩阵,这就是雅可比矩阵。
注意:微分的值域f(x)dx ,导数的值域f(x)
函数f(x)微分是f(x)在点x处曲线的切线,导数是f(x)在点x处切线的斜率
- 海森矩阵(Hessian Matrix):对于函数f:Rn→R,其海森矩阵H是多元函数二阶导数组成的矩阵,被定义为 。描述了函数的局部曲率。
海森矩阵常用于牛顿法解决优化问题,利用海森矩阵可判定多元函数的极值问题。在工程实际问题的优化设计中,所列的目标函数往往很复杂,为了使问题简化,常常将目标函数在某点邻域展开成泰勒多项式来逼近原函数,此时函数在某点泰勒展开式的矩阵形式中会涉及到海森矩阵。
- Hessian等价于梯度的Jacobian矩阵
- 极值点&鞍点:当对于函数f(x)f(x)来说,其导数等于0的点可能会存在的情况如下图所示,x=0点对图中三个函数来说分别是极大值点、极小值点、鞍点(非极值点)。对于多层的神经网络来说,鞍点是非常常见的,在迭代优化的时候需要使用一些方法跳出。
- 全局最小点:在函数的定义域上取得全局最小值的点,这通常来说是许多机器学习问题所要寻找的优化目标点。对神经网络中问题的
损失函数
来说,可能存在很多的的局部最小点,它们与全局的最小点差距不大,应此通常也可以作为问题的解(因为要求出全局最小点是一个几乎不可能的任务,所以我们一般选择局部的最优值即可),下面是一个示例。
- 约束优化:在求解优化目标时,可能需要在函数定义域的某个子集中得到极值,这种条件下的优化问题被称为约束优化,一般使用构造拉格朗日函数利用KKT条件的方法求解。
正文
机器学习算法通常需要大量的数值计算。
这里的数值计算是指通过迭代过程更新解的估计值来解决数学问题的算法(数值解),而不是通过解析过程推导出公式来提供正确解的方法(解析解)。
常见的操作包括优化(找到最小化或最大化函数值的参数)和线性方程组的求解。对数字计算机来说,实数无法在有限内存下精确表示,因此仅仅是计算涉及实数的函数也是困难的。
【补充】
对于机器学习中的问题,有一部分可以通过数学推导的方式直接得到用公式表达的解析解
analytical solution。但对绝大多数的问题来说,解析解是不存在的,需要使用迭代更新的方法求数值解
numerical solution。然而实数的精度是无限的,计算机能够表达的精度是有限的,这就涉及到许多数值计算方法的问题。
解析解(analytical solution)就是一些严格的公式,给出任意的自变量就可以求出其因变量,也就是问题的解, 他人可以利用这些公式计算各自的问题. 解析解,又称为闭式解,是可以用解析表达式来表达的解。
解析解是一种包含分式、三角函数、指数、对数甚至无限级数等基本函数的解的形式。
数值解(numerical solution)是采用某种计算方法,如有限元的方法, 数值逼近,插值的方法, 得到的解.别人只能利用数值计算的结果, 而不能随意给出自变量并求出计算值. 当无法由微积分技巧求得解析解时,这时便只能利用数值分析的方式来求得其数值解了。数值方法变成了求解过程重要的媒介。在数值分析的过程中,首先会将原方程式加以简化,以利后来的数值分析。例如,会先将微分符号改为差分符号等。然后再用传统的代数方法将原方程式改写成另一方便求解的形式。这时的求解步骤就是将一独立变量带入,求得相依变量的近似解。因此利用此方法所求得的相依变量为一个个分离的数值(discrete values),不似解析解为一连续的分布,而且因为经过上述简化的动作,所以可以想见正确性将不如解析法来的好。
总结:数值解是在特定条件下通过近似计算得出来的一个数值,而解析解为该函数的解析式解析解就是给出解的具体函数形式,从解的表达式中就可以算出任何对应值。
例:等式x2=5
解析解:x=sqrt(5)
数值解:x=2.236
上溢和下溢
连续数学在数字计算机上的根本困难是,我们需要通过有限数量的位模式来表示无限多的实数。这意味着我们在计算机中表示实数时,几乎总会引入一些近似误差。在许多情况下,这仅仅是舍入误差
。
舍入误差会导致一些问题,特别是当许多操作复合时,即使是理论上可行的算法,如果在设计时没有考虑最小化舍入误差的累积,在实践时也可能会导致算法失效。
一种极具毁灭性的舍入误差是下溢(underflow)。当接近零的数被四舍五入为零时发生下溢。许多函数在其参数为零而不是一个很小的正数时才会表现出质的不同。
例如,我们通常要避免被零除(一些软件环境将在这种情况下抛出异常,有些会返回一个非数字(nota-number,NaN)的占位符)或避免取零的对数(这通常被视为−∞,进一步的算术运算会
使其变成非数字)。
另一个极具破坏力的数值错误形式是上溢(overflow)。当大量级的数被近似为∞或−∞时发生上溢。进一步的运算通常会导致这些无限值变为非数字。
必须对上溢和下溢进行数值稳定的一个例子是softmax函数
(softmax function)。
softmax函数经常用于预测与Multinoulli【多项分布-离散型随机变量概率分布】分布相关联的概率,定义为
考虑一下当所有xi都等于某个常数c时会发生什么?
从理论分析上说,我们可以发现所有的输出都应该为
。从数值计算上说,当c量级很大时,这可能不会发生。
- 如果c是很小的负数,exp(c)就会下溢。这意味着softmax函数的分母会变成0,所以最后的结果是未定义的。
- 当c是非常大的正数时,exp(c)的上溢再次导致整个表达式未定义。
(这是原书中的解释,不理解,还是看补充部分通俗易懂)
这两个困难能通过计算softmax(z)同时解决,其中z = x - maxi xi。
简单的代数计算表明,softmax解析上的函数值不会因为从输入向量减去或加上标量而改变。
减去maxi xi导致exp的最大参数为0,这排除了上溢的可能性。同样地,分母中至少有一个值为1的项,这就排除了因分母下溢而导致被零除的可能性。
还有一个小问题。分子中的下溢仍可以导致整体表达式被计算为零。这意味着,如果我们在计算log softmax(x)时,先计算softmax再把结果传给log函数,会错误地得到−∞。相反,我们必须实现一个单独的函数,并以数值稳定的方式计算log softmax。我们可以使用相同的技巧来稳定log softmax函数。
【关于softmax函数补充说明】
做过多分类任务的同学一定都知道softmax函数。
softmax函数,又称归一化指数函数。它是二分类函数sigmoid在多分类上的推广,目的是将多分类的结果以概率的形式展现出来。
下图展示了softmax的计算方法:
下面为大家解释一下为什么softmax是这种形式。
首先,我们知道概率有两个性质:1)预测的概率为非负数;2)各种预测结果概率之和等于1。
softmax就是将在负无穷到正无穷上的预测结果按照这两步转换为概率的。
1)将预测结果转化为非负数
下图为y=exp(x)的图像,我们可以知道指数函数的值域取值范围是零到正无穷。
softmax第一步就是将模型的预测结果转化到指数函数上,这样保证了概率的非负性。
2)各种预测结果概率之和等于1
为了确保各个预测结果的概率之和等于1。我们只需要将转换后的结果进行归一化处理。方法就是将转化后的结果除以所有转化后结果之和,可以理解为转化后结果占总数的百分比。这样就得到近似的概率。
例,假如模型对一个三分类问题的预测结果为-3、1.5、2.7。我们要用softmax将模型结果转为概率。步骤如下:
1)将预测结果转化为非负数
y1 = exp(x1) = exp(-3) = 0.05
y2 = exp(x2) = exp(1.5) = 4.48
y3 = exp(x3) = exp(2.7) = 14.88
2)各种预测结果概率之和等于1
z1 = y1/(y1+y2+y3) = 0.05/(0.05+4.48+14.88) = 0.0026
z2 = y2/(y1+y2+y3) = 4.48/(0.05+4.48+14.88) = 0.2308
z3 = y3/(y1+y2+y3) = 14.88/(0.05+4.48+14.88) = 0.7666
总结一下softmax如何将多分类输出转换为概率,可以分为两步:
1)分子:通过指数函数,将实数输出映射到零到正无穷。
2)分母:将所有结果相加,进行归一化。
病态条件
条件数指的是函数相对于输入的微小变化而变化的快慢程度。
当一线性系统受到极微小的扰动即可引发方程解剧烈变化时,我们将无从信任计算结果,便称它是病态系统。
求解方程组时如果对数据进行较小的扰动,则得出的结果具有很大波动,这样的矩阵称为病态矩阵。
输入被轻微扰动而迅速改变的函数对于科学计算来说可能是有问题的,因为输入中的舍入误差可能导致输出的巨大变化。
考虑函数
。当
具有特征值分解时,其条件数为
这是最大和最小特征值的模之比。当该数很大时,矩阵求逆对输入的误差特别敏感。
这种敏感性是矩阵本身的固有特性,而不是矩阵求逆期间舍入误差的结果。即使我们乘以完全正确的矩阵逆,病态条件的矩阵也会放大预先存在的误差。在实践中,该错误将与求逆过程本身的数值误差进一步复合。
【补充-病态条件】
求解线性方程组Ax=b时,设A是n阶非奇异矩阵,‖‖表示对矩阵取某一种范数。那么
称为矩阵A的条件数,其中A-1是A的逆矩阵。
当条件数 Cond(A) 比较大时,A和b的小扰动会引起解的较大误差,所以条件数 Cond(A) 刻画了方程组Ax=b的性态。
如果条件数比较大,就说方程组是“病态
”的;如果条件数比较小,就说方程组是“良态
”的;当然,病态和良态是相对的。
基于梯度的优化方法
大多数深度学习算法都涉及某种形式的优化。
优化指的是改变x以最小化或最大化某个函数f(x)的任务。
我们通常以最小化f(x)指代大多数最优化问题。最大化可经由最小化算法最小化−f(x)来实现。
我们把要最小化或最大化的函数称为目标函数(objective function)或准则(criterion)。
当我们对其进行最小化时,也把它称为代价函数(cost function)、损失函数(loss function)或误差函数(error function)
我们通常使用一个上标∗表示最小化或最大化函数(目标函数)的x值,记 。
假设有一个函数y =f(x),其中x和y是实数。这个函数的导数(derivative)记为f′ (x)或
。
导数f′ (x)表示f(x)在点x处的斜率
。换句话说,它表明如何缩放输入的小变化才能在输出获得相应的变化:
因此导数对于最小化一个函数很有用,因为它告诉我们如何更改x来略微地改善y 。
例如,我们知道对于足够小
的来说,f(x−sign(f′ (x)))是比f(x)小的。因此我们可以将x往导数的反方向移动一小步来减小f(x)。这种技术称为梯度下降(gradient descent)。
观察上图。梯度下降算法如何使用函数导数的示意图,即沿着函数的下坡方向(导数反方向)直到最小。
当f′ (x)=0时,导数无法提供往哪个方向移动的信息。f′ (x)=0的点称为临界点
(critical point)或驻点
(stationary point)。
一个局部极小点
(local minimum)意味着这个点的f(x)小于所有邻近点,因此不可能通过移动无穷小的步长来减小f(x)。
一个局部极大点
(local maximum)意味着这个点的f(x)大于所有邻近点,因此不可能通过移动无穷小的步长来增大f(x)。
有些临界点既不是最小点也不是最大点,这些点称为鞍点
(saddle point)。
下图给出了各种临界点的例子。
上图是一维情况下,3种临界点的示例。临界点
是斜率为零的点。这样的点可以是:局部极小点(local minimum),其值低于相邻点;局部极大点(local maximum),其值高于相邻点;鞍点,同时存在更高和更低的相邻点
使f(x)取得绝对的最小值(相对所有其他值)的点是全局最小点
(global minimum)。
函数可能只有一个全局最小点或存在多个全局最小点,还可能存在不是全局最优的全局极小点。
【在深度学习的背景下】我们要优化的函数可能含有许多不是最优的全局极小点,或者还有很多处于非常平坦的区域内的鞍点。尤其是当输入是多维的时候,所有这些都将使优化变得困难。因此,我们通常寻找使f非常小的点,但这在任何形式意义下并不一定是最小。
上图表示了一种近似最小化。当存在多个全局极小点或平坦区域时,优化算法可能无法找到全局最小
点。
【在深度学习的背景下】
我们经常最小化具有多维输入的函数: 。为了使“最小化”的概念有意义,输出必须是一维的(标量)。
针对具有多维输入的函数,我们需要用到偏导数
(partial derivative)的概念。
偏导数
衡量点x处只有xi增加时f(x)如何变化。
梯度(gradient)是相对一个向量求导的导数:f的导数是包含所有偏导数的向量,记为∇xf(x)。梯度的第i个元素是f关于xi的偏导数。在多维情况下,临界点
是梯度中所有元素都为零的点。
在 (单位向量)方向的方向导数是函数 在 方向的斜率。 换句话说,方向导数是函数 关于 的导数(在 时取得)。 使用链式法则,我们可以看到当 时, 。
为了最小化
,我们希望找到使
下降得最快的方向。
计算方向导数:
其中
是
与梯度的夹角。 将
代入,并忽略与
无关的项,就能简化得到
这在
与梯度方向相反时取得最小。 换句话说,梯度向量指向上坡,负梯度向量指向下坡。 我们在负梯度方向上移动可以减小
。 这被称为最速下降法
(method of steepest descent)或梯度下降
。
最速下降在梯度的每一个元素为零时收敛(或在实践中,很接近零时)。在某些情况下,我们也许能够避免运行该迭代算法,并通过解方程∇xf(x)=0直接跳到临界点。
虽然梯度下降被限制在连续空间中的优化问题,但不断向更好的情况移动一小步(即近似最佳的小移动)的一般概念可以推广到离散空间。递增带有离散参数的目标函数称为爬山算法
(hill climbing)。
雅克比Jacobian矩阵
有时我们需要计算输入和输出都为向量的函数的所有偏导数。包含所有这样的偏导数的矩阵被称为Jacobian矩阵。
假设有一个函数f:Rm→Rn,其雅克比Jacobian矩阵J∈Rn×m被定义为 。
有时,我们也对导数的导数感兴趣,即二阶导数
(second derivative)。
例如,有一个f:Rm→R函数,f的一阶导数(关于xj)关于xi的导数记为
。
在一维情况下,我们可以将二阶导数
记为f’’(x)。
二阶导数告诉我们,一阶导数将如何随着输入的变化而改变。它表示只基于梯度信息的梯度下降步骤是否会产生如我们预期的那样大的改善,因此它是重要的。我们可以认为,二阶导数是对曲率的衡量。
假设我们有一个二次函数(虽然很多实践中的函数都不是二次的,但至少在局部可以很好地用二次近似)。
- 如果这样的函数具有
零二阶导数
,那就没有曲率,也就是一条完全平坦的线,仅用梯度就可以预测它的值。我们使用沿负梯度方向大小为 的下降步,当该梯度是1时,代价函数(目标函数)将下降 。 - 如果二阶导数是负的,函数曲线向下凹陷(向上凸出),因此代价函数将下降得比 多。
- 如果二阶导数是正的,函数曲线向上凹陷(向下凸出),因此代价函数将下降得比 少。
下图看出不同形式的曲率如何影响基于梯度的预测值与真实的代价函数值的关系。
观察上图二阶导数确定函数的曲率。这里我们展示具有各种曲率的二次函数。
虚线表示我们仅根据梯度信息进行梯度下降后预期的代价函数值。
- 对于负曲率,代价函数实际上比梯度预测下降得更快。
- 没有曲率时,梯度正确预测下降值。
- 对于正曲率,代价函数比预期下降得更慢,并且最终会开始增加,因此太大的步骤实际上可能会无意地增加函数值
海森Hessian矩阵
当我们的函数具有多维输入时,二阶导数也有很多。
我们可以将这些导数合并成一个矩阵,称为Hessian矩阵。Hessian矩阵H(f)(x)定义为
Hessian等价于梯度的Jacobian矩阵。
微分算子在任何二阶偏导连续的点处可交换,也就是它们的顺序可以互换。
这意味着Hi,j=Hj,i,因此Hessian矩阵在这些点上是对称的。
【在深度学习背景下】我们遇到的大多数函数的Hessian几乎处处都是对称的。因为Hessian矩阵是实对称的,我们可以将其分解成一组实特征值和一组特征向量的正交基。
- 在特定方向d上的二阶导数可以写成 。当d是H的一个特征向量时,这个方向的二阶导数就是对应的特征值。
- 对于其他的方向d,方向二阶导数是所有特征值的加权平均,权重在0和1之间,且与d夹角越小的特征向量的权重越大。最大特征值确定最大二阶导数,最小特征值确定最小二阶导数。
我们可以
。
我们在当前点x(0)处做函数f(x)的近似二阶泰勒级数:
其中g是梯度,H是x(0)点的Hessian。
如果我们使用学习率
,那么新的点x将会是
。
代入上述的近似,可得
公式中有3项:函数的原始值、函数斜率导致的预期改善和函数曲率导致的校正。
- 当最后一项太大时,梯度下降实际上是可能向上移动的。
- 当g⊤Hg为零或负时,近似的泰勒级数表明增加 将永远使f下降。在实践中,泰勒级数不会在 大的时候也保持准确,因此在这种情况下我们必须采取更具启发式的选择。
- 当g⊤Hg为正时,通过计算可得,使近似泰勒级数下降最多的最优步长为 。最坏的情况下,g与H最大特征值λmax对应的特征向量对齐,则最优步长是
当我们要最小化的函数能用二次函数很好地近似的情况下,Hessian的特征值决定了学习率的量级。
二阶导数还可以用于确定一个临界点是否是局部极大点、全局极小点或鞍点。
利用Hessian的特征值分解,我们可以将二阶导数测试扩展到多维情况。
在临界点
处,我们通过检测Hessian的特征值来判断该临界点是一个局部极大点、全局极小点还是鞍点。
- 当Hessian是正定的(所有特征值都是正的),则该临界点是
全局极小点
。因为方向二阶导数在任意方向都是正的,参考单变量的二阶导数测试就能得出此结论。 - 当Hessian是负定的(所有特征值都是负的),这个点就是
局部极大点
。 - 在多维情况下,实际上我们可以找到确定该点是否为
鞍点
的积极迹象(某些情况下)。如果Hessian的特征值中至少一个是正的且至少一个是负的,那么x是f某个横截面的局部极大点,却是另一个横截面的全局极小点。如下图函数f(x)=x12+x22(既有正曲率,又有负曲率的鞍点)。
上图中函数沿x1轴向上弯曲。x1轴是Hessian的一个特征向量,并且具有正特征值。函数沿x2轴向下弯曲。该方向对应于Hessian负特征值的特征向量。名称“鞍点”源自该处函数的鞍状形状。这是具有鞍点函数的典型示例。维度多于一个时,鞍点不一定要具有0特征值:仅需要同时具有正特征值和负特征值。我们可以想象这样一个鞍点(具有正负特征值)在一个横截面内是局部极大点,而在另一个横截面内是全局极小点。
最后,多维二阶导数测试可能像单变量版本那样是不确定的。当所有非零特征值是同号的且至少有一个特征值是0时,这个检测就是不确定的。这是因为单变量的二阶导数测试在零特征值对应的横截面上是不确定的。
多维情况下,单个点处每个方向上的二阶导数是不同的。Hessian的条件数衡量这些二阶导数的变化范围。
当Hessian的条件数很差时,梯度下降法也会表现得很差。这是因为一个方向上的导数增加得很快,而在另一个方向上增加得很慢。梯度下降不知道导数的这种变化,所以它不知道应该优先探索导数长期为负的方向。
病态条件也导致很难选择合适的步长。步长必须足够小,以免冲过最小而向具有较强正曲率的方向上升。这通常意味着步长太小,以至于在其他较小曲率的方向上进展不明显。
上图表面梯度下降无法利用包含在Hessian矩阵中的曲率信息。
这里我们使用梯度下降来最小化Hessian矩阵条件数为5的二次函数f(x)。这意味着最大曲率方向具有比最小曲率方向多5倍的曲率。
在这种情况下,最大曲率在[1,1]T方向上,最小曲率在[1,-1]T方向上。红线表示梯度下降的路径。这个非常细长的二次函数类似一个长峡谷。梯度下降把时间浪费于在峡谷壁反复下降,因为它们是最陡峭的特征。
由于步长有点大,有超过函数底部的趋势,因此需要在下一次迭代时在对面的峡谷壁下降。与指向该方向的特征向量对应的Hessian的大的正特征值表示该方向上的导数快速增加,因此基于Hessian的优化算法可以预测,在此情况下最陡峭方向实际上不是有前途的搜索方向。
我们可以使用Hessian矩阵的信息来指导搜索,以解决这个问题。其中最简单的方法是牛顿法(Newton’s method)。当附近的临界点是最小点(Hessian的所有特征值都是正的)时牛顿法才适用,而梯度下降不会被吸引到鞍点(除非梯度指向鞍点)。
仅使用梯度信息的优化算法称为一阶优化算法(first-order optimization algorithms),如梯度下降
。使用Hessian矩阵的优化算法称为二阶最优化算法(second-order optimization algo-rithms),如牛顿法
。
约束优化
有时候,在x的所有可能值下最大化或最小化一个函数f(x)不是我们所希望的。相反,我们可能希望在x的某些集合S中找f(x)的最大值或最小值。这称为约束优化(constrained optimization)。在约束优化术语中,集合内的点x称为可行(feasible)点。
约束优化:在求解优化目标时,可能需要在函数定义域的某个子集中得到极值,这种条件下的优化问题被称为约束优化,一般使用构造拉格朗日函数利用KKT条件的方法求解。
Karush-Kuhn-Tucker(KKT)方法是针对约束优化非常通用的解决方案。为介绍KKT方法,我们引入一个称为广义Lagrangian
(generalized Lagrangian)或广义Lagrange函数(generalized Lagrange function)的新函数。
我们可以使用一组简单的性质来描述约束优化问题的最优点。这些性质称为Karush-Kuhn-Tucker(KKT)条件。这些是确定一个点是最优点的必要条件,但不一定是充分条件。这些条件是:
- 广义Lagrangian的梯度为零。
- 所有关于x和KKT乘子的约束都满足。
- 不等式约束显示的“互补松弛性”: 。
实例:线性最小二乘
假设我们希望找到最小化下式的x值
在这里我们尝试使用基于梯度的优化
来解决这个问题。
求解过程参加原书
实例:利用梯度下降法求解
假设有一些样本点X和对应的目标y,已知y可以由f(x)=w⋅x+b加上噪音生成,求解函数f的参数w和b。
首先定义f(x)相对于y的损失函数(这里一般使用均方误差,比较预测值和真实值的差距)
那么损失函数相对于参数w和b的导数分别为:
根据梯度下降法的公式可以得到参数的更新公式: