机器学习数学基础-优化(上)

线代专栏:https://zhuanlan.zhihu.com/p/30191876

概率统计:https://zhuanlan.zhihu.com/p/30314229

优化(上):https://zhuanlan.zhihu.com/p/30383127

优化(下):https://zhuanlan.zhihu.com/p/30486793

信息论及其他:https://zhuanlan.zhihu.com/p/30383356


 

掌握机器学习数学基础之优化[1](重点知识)

 

是的,你没有看错,本来计划四篇可以写完的,现在要不止了,优化部分分为一二,一主要是微积分的知识,二主要是约束优化,凸优化,对偶等知识。本来想一篇解决的,但文章之大,一篇放不下.......下面开始分节叙述:

  1. 计算复杂性与NP问题
  2. 上溢和下溢
  3. 导数,偏导数及两个特殊矩阵
  4. 函数导数为零的二三事
  5. 方向导数和梯度
  6. 梯度下降法
  7. 牛顿法

计算复杂性与NP问题

算法的复杂性:现实中大多数问题都是离散的数据集,为了反映统计规律,有时数据量很大,而且多数目标函数都不能简单地求得解析解。而为了记录在解决问题的算法的性能或者说好坏,就引入了算法的复杂性。

算法理论被认为是解决各类现实问题的方法论。而衡量算法理论的计算复杂度可分为:时间复杂度和空间复杂度,这是对算法执行所需要的两类资源——时间和空间的估算。其中,算法的时间复杂度是一个函数,它定性描述了该算法的运行时间,空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度

另为,一般的,衡量问题是否可解的重要指标是:该问题能否在 多项式时间内求解,还是只能在 指数时间内求解?在各类算法理论中,通常使用多项式时间算法即可解决的问题看作是易解问题,需要指数时间算法解决的问题看作是难解问题。

指数时间算法的计算时间随着问题规模的增长而呈指数化上升,这类问题虽然有解,但并不适用于大规模问题。所以当前算法研究的一个重要任务就是将指数时间算法变换为多项式时间算法。

确定性和非确定性 :除了问题规模与运算时间的比较,衡量一个算法还需要考虑确定性和非确定性的概念。

先说说自动机:是有限状态机(FSM)的数学模型。实际上是指一种基于状态变化进行迭代的算法。也就是在给定输入和状态时,自动机的状态会发生改变的模型。在算法领域常把这类算法看作一个机器,比较知名的有图灵机、玻尔兹曼机、支持向量机等。或者,在日常生活中的自动售卖机就是一种有限状态机。

确定性:所谓确定性,是指针对各种自动机模型,根据当时的状态和输入,若自动机的状态转移是唯一确定的,则称具有确定性;

非确定性:若在某一时刻自动机有多个状态可供选择,并尝试执行每个可选择的状态,则称具有不确定性。

换个说法就是:确定性是程序每次运行时产生下一步的结果是唯一的,因此返回的结果也是唯一的;非确定性是程序在每个运行时执行的路径是并行且随机的,所有路径都可能返回结果,也可能只有部分返回结果,也可能不返回结果,但是只要有一个路径返回结果,那么算法就结束。

NP问题:简单的说,存在多项式时间的算法的一类问题,称之为P类问题;在多项式时间内可由非确定机解决的一类问题,称之为NP问题。另外,很多人相信P类问题是NP问题的一个子集,但既没有人证明出有某个问题属于NP但不属于P,也没有人证明所有NP问题都能在多项式时间内有解,如图:

来自百度百科

P类问题:就是能够以多项式时间的确定性算法来对问题进行判定或求解,实现它的算法在每个运行状态都是唯一的,最终一定能够确定一个唯一的结果——最优的结果。

NP问题:是指可以用多项式时间的非确定性算法来判定或求解,即这类问题求解的算法大多是非确定性的,但时间复杂度有可能是多项式级别的。

对于上面的知识,我们只要了解知道他们的概念就好了,机器学习中多数算法都是针对NP问题(包括NP完全问题)的。

上溢和下溢

下溢:当接近零的数被四舍五入为零时发生下溢。许多函数会在其参数为零而不是一个很小的正数时才会表现出质的不同。例如,我们通常要避免被零除。

上溢(overflow):当大量级的数被近似为 +\infty 或者 -\infty 时发生上溢。进一步的运算通常将这些无限值变为非数字。

为什么会下溢或者上溢:数字计算机上实现连续数学的基本困难是我们需要通过有限数量的位模式来表示无限多的实数,这意味着我们在计算机中表示实数时几乎都会引入一些近似误差。在许多情况下,这仅仅是舍入误差。如果在理论上可行的算法没有被设计为最小化舍入误差的累积,可能会在实践中失效,也就是可能产生下溢或者上溢

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

softmax(x)_{i}=\frac{exp(x_{i})}{\sum_{j=1}^{n}{exp(x_{j})}}

当式中的x_{i}都是很小的负数时,exp(x_{i} )就会发生下溢,这意味着上面函数的分母会变成0,导致结果是未定的;同理,当式中的x_{i}是很大的正数时,exp(x_{i} )就会发生上溢导致结果是未定的。

这个概念是比较重要的,我们需要了解清除!

导数和偏导数

导数: 当函数定义域和取值都在实数域中的时候,导数可以表示函数曲线上的切线斜率。 当然除了切线的斜率,导数还表示函数在该点的变化率。或者从物理意义来说,就是瞬时变化率。

上面是一维导数的定义式,其中涉及极限的知识,简单来说极限就是“无限靠近而永远不能到达”,当然,高中初中就学过导数,这个也可以用之前斜率的角度去理解,多维的话也就是在此之上的推广。

将上面的公式转化为下面图像为:

 

注意:在一元函数中,只有一个自变量变动,也就是说只存在一个方向的变化率,这也就是为什么一元函数没有偏导数的原因。

偏导数:偏导数是指对至少两个自变量或以上对其中一个变量进行的求导,以两个自变量为例, z=f(x,y) . 从导数到偏导数,也就是从曲线来到了曲面. 曲线上的一点,其切线只有一条。但是曲面的一点,切线有无数条。

从几何意义来说,偏导数就是指的是多元函数沿坐标轴的变化率.其中, f_{x}(x,y) 指的是函数在y方向不变,函数值沿着x轴方向的变化率。而 f_{y}(x,y) 指的是函数在x方向不变,函数值沿着y轴方向的变化率。
对应的图像形象表达如下:

x_{0}∈I 通过上图,一目了然的是: f_{x}(x,y) 指的就是曲面被平面所截得的曲面在点处的切线对x轴的斜率, f_{y}(x,y) 就是曲面被平面所截得的曲面在点处的切线对y轴的斜率。

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

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

注意:Hessian等价于梯度的Jacobian矩阵。

微分算子在任何二阶偏导连续的点处可交换,也就是它们的顺序可以互换:

这意味着 H_{i,j} = H_{j,i} , 因此也就是说Hessian矩阵在这些点上是对称的。

这些知识是前置知识,下面都要用到,记住两个特殊矩阵指的是什么?然后偏导数是什么?

函数导数为零的二三事

注意:为了便于理解,下面将详细分析导数为0在低维的情况,而在高维情况下都是类似的。下面先介绍一些概念:

极值的定义如下:若函数 f(x) 在 x_{0} 的一个邻域D有定义,且对D中除 x_{0} 的所有点,都有 f(x)<f(x_{0}) ,则称 f(x_{0}) 是函数 f(x) 的一个极大值。同理,若对D的所有点,都有 f(x)>f(x_{0}) ,则称f(x₀)是函数 f(x) 的一个极小值。

对应的,函数最值的定义如下:

最小值:设函数 y=f(x) 的定义域为 I ,如果存在实数M满足:①对于任意实数 x∈I ,都有 f(x)≥M ,②存在 x_{0}∈I 。使得 f (x_{0})=M ,那么,我们称实数M 是函数 y=f(x) 的最小值。

最大值:设函数 y=f(x) 的定义域为 I ,如果存在实数M满足:①对于任意实数 x∈I ,都有 f(x)≤M ,②存在 x_{0}∈I 。使得 f (x_{0})=M ,那么,我们称实数M 是函数 y=f(x) 的最大值

以上都是在一元函数中的定义,如下图所示,而二维或以上可简单推之:

 

鞍点 (saddle point): 目标函数在此点上的梯度(一阶导数)值为 0, 但从改点出发的一个方向是函数的极大值点,而在另一个方向是函数的极小值点。

为什么叫做鞍点?鞍点这词来自于不定二次型 x^2-y^2 的二维图形,它的形状就像马鞍,而鞍点就是中心那个点,图中x轴方向往上曲,在y轴方向往下曲。这样也让我们更容易理解。

判断鞍点的一个充分条件是:函数在鞍点处的Hessian矩阵为不定矩阵。这样为什么在这里不做详细解释,有兴趣可以了解。

进入正题:当 f^\prime(x)=0 ,导数无法提供往哪个方向移动的信息。 f^\prime(x)=0 的点称为临界点或驻点。 一个局部极小点意味着这个点的 f(x) 小于所有邻近点,因此不可能通过移动无穷小的步长来减小 f(x) 。 一个局部极大点意味着这个点的 f(x) 大于所有邻近点,因此不可能通过移动无穷小的步长来增大 f(x) 。 有些临界点既不是极小点也不是极大点。这些点被称为鞍点。

图来自《deep learning》

上图列出临界点的类型。在一维情况下,三种临界点的示例。临界点是斜率为零的点。这样的点可以是 局部极小点(local minimum),其值低于相邻点; 局部极大点(local maximum),其值高于相邻点; 或鞍点,同时存在更高和更低的相邻点

使 f (x) 取得绝对的最小值(相对所有其他值)的点是 全局最小点(globalminimum)。函数可能有一个全局最小点或存在多个全局最小点,还可能存在不是全局最优的局部极小点。在机器学习和深度学习的背景下,我们要优化的函数可能含有许多不是最优的局部极小点,或者还有很多处于非常平坦的区域内的鞍点。尤其是当输入是多维的时候,所有这些都将使优化变得困难。因此,我们通常寻找使 f 非常小的点,但这在任何形式意义下并不一定是最小。方向导数和梯度方向导数和梯度

图来自《deep learning》

上图展示了近似最小化,当存在多个局部极小点或者平坦区域时,优化算法可能无法找到全局最小点,在机器学习和深度学习中,即使找到的解不是真正最小的,但只要它们对应于代价函数显著低的值,我们通常就能接受这样的解。

这些知识点都是基本知识,不做过多解释,低维的我们理解了,高维的就类推就行了,比如高维也临界点也有局部最优或者鞍点的情况。但在深度学习中优化算法比如SGD往往可以避免鞍点,然后使得其效果不错,这也是深度学习为什么可行的一个原因吧。

方向导数和梯度:

方向导数:在之前讲偏导数的时候,相信很多人已经看出,偏导数求的都是沿着坐标轴的变化率,不管多少维也好,都只是求的变化率,那现在问题来了,如果我想求在某个方向而不是沿着坐标轴方向的变化率怎么求呢?那方向导数,简单来说,就是我们指定任意一个方向,函数对对这个任意方向的变化率.

假设z=f(x,y)为一个曲面,p(x_{0} ,y_{0} )f定义域中一个点,单位向量u =cos\theta i+sin\theta j的斜率,其中\theta是此向量与x轴正向夹角.单位向量u可以表示对任何方向导数的方向.如下图:

 

那么我们来考虑如何求出u方向的斜率,可以类比于前面导数定义,得出如下:

f(x,y)为一个二元函数,u =cos\theta i+sin\theta j为一个单位向量,如果下列的极限值存在

\lim_{t \rightarrow 0}{\frac{f(x_{0}+tcos\theta ,y_{0}+tsin\theta )-f(x_{0},y_{0})}{t} }此方向导数记为D_{u}f

则称这个极限值是f沿着u方向的方向导数,那么随着\theta的不同,我们可以求出任意方向的方向导数.这也表明了方向导数的用处,是为了给我们考虑函数对任意方向的变化率.

或者说,如下图,我们知道在一维的时候,函数的导数就是在某点对应切线的斜率,那么对于函数f(x,y) 的A 点在这个方向上也是有切线的,其切线的斜率就是方向导数。当然,注意这个切线是任意的,这里我们要限定其方向,也就是图中中的矢量y的方向。

梯度:是一个矢量或者说是一个向量,其方向上的方向导数最大,其大小正好是此最大方向导数。

梯度的理解很重要,很重要,很重要!下面解决两个问题,梯度怎么求和梯度有什么用?

怎么算?--(介绍一种比较简单之间的方法)

方向导数可以如下的方法算:D_{u}f(x,y)=f_{x}(x,y)cos\theta +f_{y}(x,y)sin\theta,对于该式子的推导,我们可以自行了解,这里不做过多讨论。

回到正题:

D_{u}f(x,y)=f_{x}(x,y)cos\theta +f_{y}(x,y)sin\theta

A=(f_{x}(x,y) ,f_{y}(x,y)),I=(cos\theta ,sin\theta )

则得:

D_{u}f(x,y)=A\bullet I=\left| A \right| *\left| I \right| cos\alpha(\alpha为向量A与向量I之间的夹角)

则当\alpha为0度的时候,也就是向量I(这个方向是一直在变,在寻找一个函数变化最快的方向)与向量A(这个方向当点固定下来的时候,它就是固定的)平行的时候,那么此时如果D_{u}f(x,y)要取得最大值。这个时候,我们也就求得梯度:A(这其中的A向量)

梯度有什么用?

简单的讲,假如你在一座山上,蒙着眼睛,但是你必须到达山谷中最低点的湖泊,你该怎么办?然后我们想到一个简单的方法,在每走一步时,都是走那个离谷底最近的那个方向,那怎么求才能使得每一步都下降更大的高度,这个时候我们就完全可以用梯度来帮助我们,就可以完成任务啦!

当然了,我们是在写机器学习数学基础呐,你会说下山有什么用,我们看这篇文章又不是为了下山的。Emmm...别急,下面我们就讲梯度的大用处

不知道讲清楚没有,这两个概念非常重要,下面的优化算法的前提就是梯度,要重点理解

梯度下降法

大多数机器学习或者深度学习算法都涉及某种形式的优化。 优化指的是改变 x 以最小化或最大化某个函数 f(x) 的任务。 我们通常以最小化 f(x) 指代大多数最优化问题。 最大化可经由最小化算法最小化 -f(x) 来实现。

我们把要最小化或最大化的函数称为目标函数或准则。 当我们对其进行最小化时,我们也把它称为代价函数、损失函数或误差函数

下面,我们假设一个损失函数为 J(\theta)=\frac{1}{2}\sum_{i=1}^{m}({h_\theta(x)-y})^2 ,其中 h_θ(x)=θ_0+θ_1x_1+θ_{2}x_2....+θ_{n}x_n 然后要使得最小化它。

注意:这里只是假设,不用知道这个目标函数就是平方损失函数等等,然后肯定有人问既然要最小化它,那求个导数,然后使得导数等于0求出不就好了吗?Emmmm...是的,有这样的解法,可以去了解正规方程组求解。说下这里不讲的原因,主要是那样的方式太难求解,然后在高维的时候,可能不可解,但机器学习或深度学习中,很多都是超高维的,所以也一般不用那种方法。总之,梯度下降是另一种优化的不错方式,比直接求导好很多。

梯度下降:我们知道曲面上方向导数的最大值的方向就代表了梯度的方向,因此我们在做梯度下降的时候,应该是沿着梯度的反方向进行权重的更新,可以有效的找到全局的最优解。这个 \theta_i 的更新过程可以描述为

[a表示的是步长或者说是学习率(learning rate)]

好了,怎么理解?在直观上,还是下山,我们可以这样理解,看下图,一开始的时候我们随机站在一个点,把他看成一座山,每一步,我们都以下降最多的路线来下山,那么,在这个过程中我们到达山底(最优点)是最快的,而上面的a,它决定了我们“向下山走”时每一步的大小,过小的话收敛太慢,过大的话可能错过最小值,扯到蛋...)。这是一种很自然的算法,每一步总是寻找使J下降最“陡”的方向(就像找最快下山的路一样)。

当然了,我们直观上理解了之后,接下来肯定是从数学的角度,我们可以这样想,先想在低维的时候,比如二维,我们要找到最小值,其实可以是这样的方法,具体化到1元函数中时,梯度方向首先是沿着曲线的切线的,然后取切线向上增长的方向为梯度方向,2元或者多元函数中,梯度向量为函数值f对每个变量的导数,该向量的方向就是梯度的方向,当然向量的大小也就是梯度的大小。现在假设我们要求函数的最值,采用梯度下降法,结合如图所示:

如图所示,我们假设函数是  y=x^2+1 ,那么如何使得这个函数达到最小值呢,简单的理解,就是对x求导,得到  y‘=\frac{1}{2}x ,然后用梯度下降的方式,如果初始值是(0的左边)负值,那么这是导数也是负值,用梯度下降的公式,使得x更加的靠近0,如果是正值的时候同理。 注意:这里的梯度也就是一元函数的导数,高维的可以直接类推之
  • 批量梯度下降:在每次更新时用所有样本,要留意,在梯度下降中,对于 \theta_i 的更新,所有的样本都有贡献,也就是参与调整 \theta .其计算得到的是一个标准梯度,也肯定可以达到一个全局最优。因而理论上来说一次更新的幅度是比较大的。如果样本不多的情况下,当然是这样收敛的速度会更快啦。但是很多时候,样本很多,更新一次要很久,这样的方法就不合适啦。下图是其更新公式

  • 随机梯度下降:在每次更新时用1个样本,可以看到多了随机两个字,随机也就是说我们用样本中的一个例子来近似我所有的样本,来调整θ,因而随机梯度下降是会带来一定的问题,因为计算得到的并不是准确的一个梯度,容易陷入到局部最优解中,但是相比于批量梯度,这样的方法更快,更快收敛,虽然是局部最优,但很多时候是我们可以接受的,所以这个方法用的也比上面的多。下图是其更新公式

  • mini-batch梯度下降:在每次更新时用b个样本,其实批量的梯度下降就是一种折中的方法,他用了一些小样本来近似全部的,其本质就是我1个指不定不太准,那我用个30个50个样本那比随机的要准不少了吧,而且批量的话还是非常可以反映样本的一个分布情况的。在深度学习中,这种方法用的是最多的,因为这个方法收敛也不会很慢,收敛的局部最优也是更多的可以接受!

}

梯度下降算法是机器学习或者深度学习中经典算法,现在绝大部分算法都是这个,就算是改进,也是在此基础上做出的改进,所以,要知道这个算法是什么,了解它的思想,甚至推荐直接看论文。

牛顿法

先来讲怎么找一个函数的零点(也就是函数值为0的点),我们提出如下公式。

该公式的大概流程为:先做对 θ 做一次猜测 θ=θ_1 ,然后过 f(θ_1) 做 f 的切线,切线交横轴于点 θ_2 (也就是切线函数值的零点),此时更新 θ_2 ,再过 f(θ_2) 做 f 的切线,这样θ就可以逼近使函数值为零的θ取值,下面是牛顿法图解:

在最左的图中为函数 f 的图像,我们希望找到零 f(θ)=0 的点,从图中看这个点大约取在1.3附近。假设我们初始化算法时猜测 θ(0)=4.5 ,牛顿法会计算出函数 f 在 (4.5, f(4.5)) 点的切线并解出切线的零点(即切线与 y=0 的焦点,如中图所示)。这就是第二次猜测的起点,在图中 θ(1) 大约在2.8附近。而最右侧的图像显示了再一次迭代的结果,这使得 θ(2) 取到了1.8附近。在几轮迭代之后,θ会快速向1.3附近收敛,得到零点

牛顿法:从之前讲的知道极值点就是导数为0的地方,但直接求导数等于0得到最优解在很多时候是不可行的,那我们现在试一下用就用上面的方式来求得极值点,也就是求导数的零点,也上面的方法应用到求导数为0时的点来求最值的方法就叫做牛顿法,对应的,牛顿方法的迭代规则如下:

当参数θ不止一个时,牛顿方法的迭代规则:

其中H是一个n阶方阵(如果算上截距项应该是n+1阶方阵)的Hessian矩阵(两个特殊矩阵)。

相较于批量梯度下降,牛顿方法通常来说有更快的收敛速度,只需要少得多的迭代次数就能得到很接近最小值的结果。但是当模型的参数很多时(参数个数为n)Hessian矩阵的计算成本将会很大,导致收敛速度变慢,所以在深度学习中也很少使用牛顿法,就是因为计算Hessian矩阵太麻烦了,但是当参数个数不多时,牛顿方法通常又是比梯度下降快得多的。这也是他的优势吧

伪牛顿法:上述的牛顿法需要计算Hessian矩阵的逆矩阵,运算复杂度太高。在动辄百亿、千亿量级特征的大数据时代,模型训练耗时太久。因此,很多牛顿算法的变形出现了,这类变形统称拟牛顿算法。拟牛顿算法的核心思想用一个近似矩阵B替代逆Hessian矩阵H−1。不同算法的矩阵B的计算有差异,但大多算法都是采用迭代更新的思想在tranning的没一轮更新矩阵B。

由于这些伪牛顿法比较复杂,而且在机器学习中也较少用,所以在这里先不细讲了,有兴趣的小伙伴可以看下 这篇博文
牛顿法在基础机器学习中有用到,但在深度学习中很少用,我们知道是什么,基本了解就好

熬夜写完一,可能有些错别字,见谅!接下来就是二了,二比较烧脑了,写的也比较多,坚持!写的有什么不好,有任何建议可以大胆提出,感谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值