数值计算

花书上的第四章学习,做笔记一方面是为了打卡激励自己学习,一方面是为了让看的书多过一遍脑子,帮助记忆。希望有相同学习兴趣的小伙伴留言讨论,包括但不限于网络安全(本行)、深度学习(工具)以及其他纬度和层面的知识。

*****************************************************************************************************************************************

机器学习算法通常需要大量的数值计算。通常是指通过不断迭代更新解的估计值以得到一个损失更小的解,而不是通过形式化的公式推导来提供正确解的方法。

1. 上溢和下溢

连续数学在数字计算机上的根本困难是,我们企图用有限的位数去表示无限多的实数。因此几乎总会有近似误差的引入,在许多情况下,仅仅是舍入误差。舍入误差会导致一些问题,特别是当许多操作复合时,即使时理论上可行的算法,如果在设计时没有考虑最小化舍入误差的累积,在实际使用中也可能会导致算法的失效。

一种极具毁灭性的舍入误差是下溢(underflow)。当接近零的数被四舍五入为零时发生下溢。比如对数运算在自变量为0时没有定义,lim_{x \to 0} log(x) = - \infty,在计算机可能会被表示成一个非数字占位符(Not a number, NaN)。

另一种极具破坏力的数值错误形式是上溢(overflow)。当大量级的数被近似为\infty或-\infty时发生上溢。进一步的运算通常会导致这些无限值变为非数字。

必须对上溢和下溢进行稳定的一个例子是softmax函数,其经常用于预测与Multinoulli分布相关联的概率,定义为

                                                                  softmax(\mathrm x)_i = \frac{exp(x_i)}{\sum_{j=1}^{n}exp(x_j)}

可以通过计算softmax(z)同时解决上溢和下溢问题,其中z = x - max_ix_i

2. 病态条件

条件数指的是函数相对于输入的微小变化而变化的快慢程度。输入被轻微扰动而迅速改变的函数对于科学计算来说可能是有问题的,因为输入中的舍入误差可能导致输出的巨大变化。

函数f(x) = A^{-1}x。当A \in \mathbb R^{n \times n}具有特征值分解时,其条件数为

                                                                                   max_{i,j}| \frac{\lambda_i}{\lambda_j} |

这是最大和最小特征值的模之比。当该数很大时,矩阵求逆对输入的误差特别敏感。

3. 基于梯度的优化方法

我们把最小化或最大化的函数称为目标函数(objective function)或准则(criterion)。当我们对其进行最小化时,也将其称为代价函数(cost function)、损失函数(loss function)或误差函数(error function)。

通常使用一个上标*表示最小化或最大化函数的x值,记为x^* = argminf(x)

导数对于一个函数很有用,因为它告诉我们如何更改x来略微地改善y:y(x + \epsilon) \approx f(x) + \epsilon f^{'}(x)。例如,我们知道对于足够小的\epsilon来说,lim_{\epsilon \to 0}f(x - \epsilon sign(f^{'}(x))) < f(x)。因此,我们可以将x往导数的反方向移动一小步来减少f(x)。这种技术称为梯度下降(gradient descent)。

f^{'}(x) = 0时,导数无法提供该往哪个方向移动的信息,将f^{'}(x) = 0的点称为临界点(critical point)或驻点(stationary point)。有些临界点(局部极小点 or 局部极大点)既不是最小点也不是最大点,这些点称为鞍点(saddle point)。

使f(x)取得绝对的最小值的点是全局最小点(global minimum)。函数可能只有一个全局最小点,也可能存在多个全局最小点,还可能存在不是全局最优的全局极小点。

在深度学习中,我们经常优化具有多维输入的函数:f: \mathbb R^{n} \to \mathbb R。为了使“最小化”的概念有意义,输出必须是一维的(标量)。

对于多维输入的函数,需要用到偏导数(partial derivative)的概念。偏导数\frac{\partial}{\partial_{x_i}}f(x)衡量点x处只有x_i增加时f(x)如何变化。梯度(gradient)是相对一个向量求导的导数:f的导数是包含所有偏导数的向量,记为\nabla_{x}f(x)。梯度的第i个元素是f关于x_i的偏导数。在多维情况下,临界点是梯度中所有元素都为零的点。

\vec{u}(单位向量)方向的方向导数(directional derivative)是函数f在u方向的斜率。换句话说,方向导数是函数f(\vec x + \alpha \vec u)关于\alpha的导数(在\alpha=0时取得)。使用链式法则,我们可以看到当\alpha=0时,\frac{\partial}{\partial_{\alpha}}f(\vec x + \alpha \vec u) = \vec u^{\top} \nabla_{x}f(x)

为了最小化f,我们希望找到使得f下降得最快的方向。计算方向导数:

                                                  \min\limits_{\vec u, \vec u^{\top}\vec u=1}\vec{u}^{\top}\nabla_{\vec{x}}f(x)= \min\limits_{\vec u, \vec u^{\top}\vec u=1}||\vec{u}||_2||\nabla_{\vec{x}}f(\vec{x}})}||_2 cos\theta

其中,\theta\vec{u}与梯度的夹角,带入\vec{u}的2范数为1,并忽略与\vec{u}无关的项,就能简化得到\min\limits_{\vec{u}}cos\theta。这在\vec{u}在梯度方向相反时取得最小。换句话说,梯度向量指向上坡,负梯度向量指向下坡。在负梯度方向上移动可以减少f。这被称为最速下降法(method of steepest descent)或梯度下降(gradient descent)。

最速下降建议新的点为

                                                                                {x}^{'} = x - \epsilon\nabla_{x}f(x)

其中,\epsilon学习率(learning rate),是一个确定步长大小的正标量。我们可以通过几种不同的方式选择\epsilon。普遍的方式是选择一个小常数。有时通过计算,选择使方向导数消失的步长。还有一种方法是根据几个\epsilon计算f(x - \epsilon\nabla_xf(x)),并选择其中能产生最小目标函数值的\epsilon。这种策略称为线搜索

最速下降在梯度的每一个元素为零时收敛(或在实践中,很接近零时)。在某些情况下,我们也许通过解方程\nabla_{x}f(x)=0直接跳到临界点从而避免运行该迭代算法。

虽然梯度下降被限制在连续空间中的优化问题,但不断向更好的情况移动一小步的一般概念可以推广到离散空间。递增带有离散参数的目标函数被称为爬山(hilll climbing)算法

3.1 梯度之上:Jacobian和Hessian矩阵

有时我们需要计算输入和输出都为向量的函数的所有偏导数。包含所有这样的偏导数的矩阵被称为Jacobian矩阵。具体来说,如果我们有一个函数f:\mathbb R^{m} \to \mathbb{R}^{n},f的Jacobian矩阵J \in \mathbb{R}^{n \times m}定义为J_{i, j} = \frac{\partial}{\partial_{x_j}}f(x)_{i}

有时,对二阶导数(second derivative)感兴趣。二阶导数告诉我们一阶导数将如何随着输入的变化而变化。表示梯度下降步骤是否会如我们预期的那样大的改善。

二阶导数=0,仅用梯度就可以预测。

二阶导数>0,说明一阶导数在逐渐上升,函数曲线向上凹陷,代价函数下降的比\epsilon小。

二阶导数<0,说明一阶导数在逐渐下降,函数曲线向下凹陷,代价函数下降的比\epsilon大。

当我们具有多维输入时,二阶导数也有很多。我们可以将这些导数合并成一个矩阵,称为Hessian矩阵。Hessian矩阵H(f)(x)

                                                                           H(f)(x)_{i, j} = \frac{\partial ^{2}}{\partial x_i \partial x_j}f(x)

Hessian矩阵等价于梯度的Jacobian矩阵。

微分算子在任何二阶偏导连续的点处可交换,即H_{i,j} = H_{j,i}

                                                                           \frac{\partial ^{2}}{\partial x_i \partial x_j}f(x) = \frac{\partial ^{2}}{\partial x_j \partial x_i}f(x)

因此,Hessian矩阵在这些点上是实对称的。我们可以将其分解为一组实特征值和一组特征向量的正交基。在特定方向d上的二阶导数可以写成d^{\top}Hd。当d是H的特征向量时,这个方向的二阶导数就是对应的特征值。对于其他的方向d,方向二阶导数是所有特征值的加权平均,权重在0~1之间,且与d夹角越小的特征向量权重越大。最大特征值确定最大二阶导数,最小特征值确定最小二阶导数。

我们可以通过(方向)二阶导数预期一个梯度下降步骤能表现的多好。我们在当前点x^{(0)}处做函数f(x)的近似二阶泰勒级数:

                                                    f(x) \approx f(x^{(0)}) + (x - x^{(0)})^{\top}g + \frac{1}{2}(x - x^{(0)})^{\top}H(x - x^{(0)})

其中,g是梯度,Hx^{(0)}点的Hessian。如果使用学习率\epsilon,那么新的点x将会是x^{(0)} - \epsilon g,代入上述的近似,可得

                                                               f(x^{(0)} - \epsilon g) \approx f(x^{(0)}) - \epsilon g^{\top}g + \frac{1}{2} \epsilon^2g^{\top}Hg

其中有三项:函数的原始值、函数斜率导致的预期改善和函数曲率导致的矫正。当最后一项太大时,梯度下降实际上可能是向上移动的。当g^{\top}Hg为零或负时,近似的泰勒级数表明增加\epsilon将永远使f下降。在实践中,泰勒级数不会在\epsilon大的时候也保持准确,因此在这种情况下必须采用更具启发式的选择。当g^{\top}Hg为正时,通过计算得,使近似泰勒级数下降最多的最优步长为

                                                                                \epsilon^{*} = \frac{g^{\top}g}{g^{\top}Hg}

最坏的情况下,gH的最大特征值\lambda_{max}对应的特征向量对齐,则最优步长时1/\lambda_{max}。当我们要最小化的函数能用二次函数很好的近似的情况下,Hessian的特征值决定了学习率的量级。

二阶导数还可以确定一个临界点是否是局部极大点、全局极小点或鞍点。

我们可以用Hessian矩阵的信息来指导搜索,其中最简单的是牛顿法(Newton's method)。牛顿法基于一个二阶泰勒展开来近似x^{(0)}附近的f(x):

                                            f(x) \approx f(x^{(0)}) + (x - x^{(0)})^{\top} \nabla_xf(x^{(0)}) + \frac{1}{2}(x - x^{(0)})^{\top}H(f)(x^{(0)})(x-x^{(0)})

接着通过计算,我们可以得到这个函数的临界点:

                                                                     x^* = x^{(0)} - H(f)(x^{(0)})^{-1}\nabla_{x}f(x^{(0)})

若f是一个正定二次函数,牛顿法只需要应用一次上式就能直接跳到函数的最小点。如果函数不是一个正定二次但是在局部可以近似为正定二次,牛顿法则需要多次迭代应用上式。

仅用梯度信息的优化算法称为一阶优化算法(first-order optimization algorithms),如梯度下降。使用Hessian矩阵的优化算法称为二阶最优化算法(second-order optimization algorithms),如牛顿法。

在深度学习的背景下,限制函数满足Lipschitz连续(Lipschitz continuous)或其导数Lipschitz连续可以获得一些保证。Lipschitz连续函数的变化速度以Lipschitz常数(Lipschitz constant)\mathcal L为界:

                                                                      \forall x, \forall y, |f(x) - f(y)| \leq \mathcal L ||x-y||_2

这个属性允许我们量化自己的假设——梯度下降等算法导致的输入的微小变化将使输出只产生微小的变化,因此是很有用的。Lipschitz连续性也是相当弱的约束,并且深度学习中很多优化问题经过相对较小的修改后就能变得Lipschitz连续。

最成功的特定优化领域或许是凸优化(Convex optimization)。凸优化通过更强的限制提供更多的保证。凸优化算法只对凸函数适用,即Hessian处处半正定的函数。因为这些函数没有鞍点且所有全局极小点必然是全局最小点,所以表现很好。

4. 约束优化

集合\mathbb S内的点x称为可行(feasible)点。

Karush-Kuhn-Tucker(KKT)方法是针对约束优化非常通用的解决方案。为介绍该方法,引入一个称为广义Lagrangian(generalized Lagrangian)或广义Lagrangian函数的新函数。

为了定义Lagrangian,先通过等式和不等式描述\mathbb S。希望通过m个函数g^{(i)}和n个函数h^{(j)}描述\mathbb S,则

                                                         \mathbb S = \{ x | \forall x, g^{(i)}(x) = 0\, and\, \forall j, h^{(j)}(x) \leq 0 \}

其中,涉及g^{(i)}的称为等式约束,涉及h^{(j)}的称为不等式约束。

我们为每个约束引入新的变量\lambda_i\alpha_j,这些新变量称为KKT乘子。广义Lagrangian可以定义为:

                                                      L(x,\lambda,\alpha) = f(x) + \sum\limits_i \lambda_i g^{(i)}(x) + \sum\limits_j \alpha_j h^{(j)}(x)

现在,可以通过优化无约束的广义Lagrangian解决约束最小化问题。只要存在至少一个可行点且f(x)不允许取\infty,那么

                                                                                \min\limits_x\max\limits_{\lambda}\max\limits_{\alpha,\alpha\geq0}L(x,\lambda,\alpha)

与如下函数具有相同的最优目标函数值和最优点集x

                                                                                              \min\limits_{x\in\mathbb S}f(x)

这是因为当约束满足时,

                                                                               \max\limits_{\lambda}\max\limits_{\alpha,\alpha \geq 0}L(x, \lambda, \alpha)=f(x)

而违反任意约束时,

                                                                                 \max\limitis_{\lambda}\max\limits_{\alpha,\alpha\geq 0}L(x, \lambda, \alpha) = \infty

这些性质保证不可行点不会是最佳的,且可行点范围内的最优点不变。

要解决约束最大化问题,可以构造-f(x)的广义Lagrangian函数,从而导致一下优化问题:

                                                            \min\limits_x\max\limits_{\lambda}\max\limits_{\alpha,\alpha \geq 0} -f(x) + \sum\limits_i{\lambda_i} g^{(i)}(x) + \sum\limits_j\alpha_j h^{(j)}(x)

也可以将其转化为在外层最大化的问题:

                                                            \max\limits_x\min\limits_{\lambda}\min\limits_{\alpha,\alpha \geq 0}f(x) + \sum\limits_i\lambda_ig^{(i)}(x)-\sum\limits_j\alpha_jh^{(j)}(x)

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值