最近在学习机器学习的时候,对于梯度这个概念的理解比较模糊,网上找到了这篇文章帮我比较好的理顺了对梯度的理解,原文地址:https://www.v2ex.com/t/397822

原文中对数学公式的显示(Latex)支持不好,很难阅读,我这里整理了以后转载到自己博客这边来。

以下是原文


这几天看机器相关的书籍,对一些概念有了新的理解,分享给大家,欢迎大家批评指正。

V2EX 似乎不能显示 Latex,可以在以下两个网址查看原文:

原文链接一: https://cent.metaquant.org/2017/grad.html

原文链接二: https://coding.net/u/metaquant/p/blog/topic/360699

以下为正文:


在机器学习中,我们通常需要对问题进行建模,然后可以得到一个成本函数(cost function),通过对这个成本函数进行最小化,我们可以得到我们所需要的参数,从而得到具体的模型。这些优化问题中,只有少部分可以得到解析解(如最小二乘法),而大部分这类优化问题只能迭代求解,而迭代求解中两种最常用的方法即梯度下降法与牛顿法。为了使用这两种方法,我们需要计算成本函数的梯度与海森矩阵,这篇文章简要说明了如何使用 python 的符号计算库 sympy 来计算特定函数的梯度与海森矩阵,求解机器学习中的最优化问题。

对梯度的直观理解


梯度概念是建立在偏导数与方向导数概念基础上的。所谓偏导数,简单来说是对于一个多元函数,选定一个自变量并让其他自变量保持不变,只考察因变量与选定自变量的变化关系。数学上说,是指对于多元函数y=f(x1,x2,...xn)y=f(x1,x2,...xn)y=f(x_1,x_2,...x_n),假设其偏导数都存在,则该函数共有nnn个偏导数,可以表示为:

fx1=∂y∂x1,fx2=∂y∂x2...fxn=∂y∂xn" role="presentation" style="text-align: center; position: relative;">fx1=∂y∂x1,fx2=∂y∂x2...fxn=∂y∂xnfx1=∂y∂x1,fx2=∂y∂x2...fxn=∂y∂xn

{f_{{x_1}}} = {{\partial y} \over {\partial {x_1}}},{f_{{x_2}}} = {{\partial y} \over {\partial {x_2}}}...{f_{{x_n}}} = {{\partial y} \over {\partial {x_n}}}

偏导数只能表示多元函数沿某个坐标轴方向的导数,如对于二元函数z=x2+y2z=x2+y2z=x^2+y^2 ,∂z∂x=2x∂z∂x=2x{{\partial z} \over {\partial x}} = 2x表示函数沿XXX轴方向的导数,而∂z∂y=2y" role="presentation" style="position: relative;">∂z∂y=2y∂z∂y=2y{{\partial z} \over {\partial y}} = 2y表示函数沿YYY轴方向的导数。

除开沿坐标轴方向上的导数,多元函数在非坐标轴方向上也可以求导数,这种导数称为方向导数。很容易发现,多元函数在特定点的方向导数有无穷多个,表示函数值在各个方向上的增长速度。一个很自然的问题是:在这些方向导数中,是否存在一个最大的方向导数,如果有,其值是否唯一?为了回答这个问题,便需要引入梯度的概念。

一般来说,梯度可以定义为一个函数的全部偏导数构成的向量(这一点与偏导数与方向导数不同,两者都为标量)。一般将函数f" role="presentation" style="position: relative;">fff的梯度记为∇f∇f\nabla f,即:

事实上,梯度向量的方向即为函数值增长最快的方向,为什么会如此,可以从几个角度去理解。

在上图中,我们可以看到,为了找到方向导数中的最大值,我们可以将其投影到xyxyxy平面来理解,这种投影方式对应的便是等高线图。如对于一个二元函数z=f(x,y)z=f(x,y)z=f(x,y),我们可以画出它的等高线图如下:

该函数的等高线图为圆心在原点的一系列圆,等高线的值由里向外逐渐增加。点B(x,y)B(x,y)B(x,y)为点(x,y,z)(x,y,z)(x,y,z)在xyxyxy平面上的投影,可以看到向量AB→AB→\vec{AB}即为函数在点(x,y,z)(x,y,z)(x,y,z)处的梯度向量。根据方向导数的定义,方向导数Duf=fxcosθ+fysinθDuf=fxcos⁡θ+fysin⁡θ{D_u}f = {f_x}\cos \theta + {f_y}\sin \theta,其中θθ\theta为此向量与XXX正方向的夹角。由于梯度向量为u=(fx,fy)" role="presentation" style="position: relative;">u=(fx,fy)u=(fx,fy)u = ({f_x},{f_y}),单位向量w=(cosθ,sinθ)w=(cosθ,sin⁡θ)w = (cos\theta ,\sin \theta ),则方向导数的大小可以表述为梯度向量与此单位向量的数量积,即:

Duf=fxcosθ+fysinθ=u⃗⋅w⃗=|u|⋅|w|⋅cosα=|u|⋅cosαDuf=fxcos⁡θ+fysin⁡θ=u→⋅w→=|u|⋅|w|⋅cos⁡α=|u|⋅cos⁡α

{D_u}f = {f_x}\cos \theta + {f_y}\sin \theta = \vec u \cdot \vec w = |u| \cdot |w| \cdot \cos \alpha = |u| \cdot \cos \alpha

其中αα\alpha为梯度向量与单位向量之间的夹角,即∠BAD∠BAD\angle BAD。可以看出,方向导数的大小可以看作梯度向量在指示方向导数方向的单位向量上的投影,即线段AEAEAE的长度。显而易见,线段AEAEAE的长度小于线段ABABAB的长度,也即梯度向量的模总是大于等于方向导数向量的模。这就解释了为什么沿着梯度向量方向是函数值增长最快的方向,而它正是函数所有偏导数构成的向量。

在上图中也可以看出,梯度向量垂直于等高线,这为我们提供了另一个观察梯度向量的角度。如对于函数f(x,y)=xyf(x,y)=xyf(x,y) = xy,其等高线图与梯度向量如下:

我们可以两个角度考虑:第一,在特定函数点,固定每次移动的步长,向哪个方向移动函数值增长最快?第二,固定需要增加的函数值,向哪个方向需要移动的步长最短?

在左图中,固定移动的步长,我们可以看到垂直于等高线图的方向即为函数值增长最快的方向,也就是梯度向量指示的方向。在右图中,假设函数值有一个固定的微小的增长,则明显梯度向量指示的方向所需要的步长最短,而这个向量也是垂直于等高线的。

梯度下降或上升法正是基于梯度指示函数值增长最快的方向而产生的,利用这个方法,我们可以使用迭代的方法计算函数的最大或最小值,从而解决机器学习中遇到的最优化问题。

使用 sympy 计算函数的梯度与海森矩阵


sympy 是 python 的开源符号计算库,它的主要功能与 Mathematica 类似,但相比于 Mathematica 它也有一些优势:它是免费的,而 Mathematica 相当昂贵;轻量,对于日常符号计算,它提供的功能已经够用,而安装起来也很容易;它是一个 python 库,这意味着你可以与你其它的 python 程序一起使用,任意扩展它的功能。对于 sympy 的使用,完整的介绍可以阅读它的文档,这里只简要介绍它的基本用法。

与 mathematica 不同,sympy 在使用符号前需要先创建,如下

from sympy import *
x, y, z = symbols('x y z')

然后你可以利用这些符号创建其它的表达式,如函数f(x,y)=x2+y2f(x,y)=x2+y2f(x,y) = {x^2} + {y^2}:

f = x^2 + y^2

你可以利用这个表达式生成新的表达式:

g = f + 1
h = f**2

则g(x,y)=x2+y2+1g(x,y)=x2+y2+1g(x,y) = {x^2} + {y^2} + 1,而h(x,y)=x4+2x2y2+y4h(x,y)=x4+2x2y2+y4h(x,y)=x^{4} + 2 x^{2} y^{2} + y^{4}。我们可以求函数的微分:

diff(f,x)
diff(f,y)
diff(f,x,x)
diff(f,x,2)

分别表示∂f∂x∂f∂x{{\partial f} \over {\partial x}},∂f∂y∂f∂y{{\partial f} \over {\partial y}},∂2f∂x2∂2f∂x2{{{\partial ^2}f} \over {\partial {x^2}}},∂2f∂x2∂2f∂x2{{{\partial ^2}f} \over {\partial {x^2}}},可以看出二阶导数可以有两种写法。

当我们求出表达式后,我们可能想要代入数值计算,这可以使用lambdify函数来实现:

u = lambdify((x,y),f)
u(1,1)

这表示f(1,1)=2f(1,1)=2f(1,1) = 2。

为了求函数的梯度与海森矩阵,我们需要引入向量微分的概念,即我们可以将梯度看作一个数量函数对自变量向量的上阶导数,而海森矩阵为数量函数对自变量量向量的二阶导数,设函数为f(x1,x2,x3,⋯xn)f(x1,x2,x3,⋯xn)f({x_1},{x_2},{x_3}, \cdots {x_n}),则自变量向量为x⃗=(x1,x2,x3,⋯xn)x→=(x1,x2,x3,⋯xn)\vec x = ({x_1},{x_2},{x_3}, \cdots {x_n}),则梯度与海森矩阵可以分别表述为∇f=dfdx⃗∇f=dfdx→\nabla f = {{df} \over {d\vec x }}与H=d2fdx⃗2H=d2fdx→2H = {{{d^2}f} \over {d{{\vec x }^2}}}。

在 sympy 中,可以通过函数derive_by_array实现上述计算:

from sympy.tensor.array import derive_by_array
grad = Matrix(derive_by_array(f,(x,y)))
hessian = Matrix(derive_by_array(grad,(x,y))).reshpae(2,2)

其中Matrix类可以将结果表达为 sympy 中的矩阵形式。上面的计算结果分别为:∇f=[2x2y]∇f=[2x2y]\nabla f=\left[\begin{matrix}2 x\\2 y\end{matrix}\right], H=[2002]H=[2002]H=\left[\begin{matrix}2 & 0\\0 & 2\end{matrix}\right],分别为函数的梯度向量与海森矩阵。

为了简化计算梯度与海森矩阵的代码,可以编写一个自定义函数对相应功能进行封装,如下:

def grad(f,*args):from sympy.tensor.array import derive_by_arraygradient = Matrix(derive_by_array(f,args))return gradientdef hessian(f,*args):from sympy.tensor.array import derive_by_arrayn = len(args)gradient = Matrix(derive_by_array(f,args))hessian = Matrix(derive_by_array(gradient, args)).reshape(n,n)return hessian

如对于函数f(x,y)=exy+sin(x+2z)−z3f(x,y)=exy+sin⁡(x+2z)−z3f(x,y) = {e^{xy}} + \sin (x + 2z) - {z^3},则有:

grad(f,x,y,z)
hessian(f,x,y,z)

则梯度为:

∇f=⎡⎣⎢⎢⎢yexy+cos(x+2z)xexy−3z2+2cos(x+2z)⎤⎦⎥⎥⎥∇f=[yexy+cos⁡(x+2z)xexy−3z2+2cos⁡(x+2z)]

\nabla f=\left[\begin{matrix}y e^{x y} + \cos{\left (x + 2 z \right )}\\x e^{x y}\\- 3 z^{2} + 2 \cos{\left (x + 2 z \right )}\end{matrix}\right]

则海森矩阵为:

H=⎡⎣⎢⎢⎢y2exy−sin(x+2z)xyexy+exy−2sin(x+2z)xyexy+exyx2exy0−2sin(x+2z)0−6z−4sin(x+2z)⎤⎦⎥⎥⎥H=[y2exy−sin⁡(x+2z)xyexy+exy−2sin⁡(x+2z)xyexy+exyx2exy0−2sin⁡(x+2z)0−6z−4sin⁡(x+2z)]

H=\left[\begin{matrix}y^{2} e^{x y} - \sin{\left (x + 2 z \right )} & x y e^{x y} + e^{x y} & - 2 \sin{\left (x + 2 z \right )}\\x y e^{x y} + e^{x y} & x^{2} e^{x y} & 0\\- 2 \sin{\left (x + 2 z \right )} & 0 & - 6 z - 4 \sin{\left (x + 2 z \right )}\end{matrix}\right]

可以看出,使用 sympy 计算函数的梯度与海森矩阵相当便捷,省去了繁琐易错的手工微分过程。对于以上计算结果,我们只需要使用lambdify函数代入数值就可以得到梯度向量与海森矩阵的数值结果,从而为实现梯度下降法与牛顿法提供基础。

对梯度概念的直观理解相关推荐

  1. 梯度的直观理解_关于梯度、旋度和散度的直观理解

    关于梯度.旋度和散度的直观理解 散度为零,说明是无源场:散度不为零时,则说明是有源场(有正源或负源) 若你的场是一个流速场,则该场的散度是该流体在某一点单位时间流出单位体积的净流量. 如果在某点,某场 ...

  2. 梯度的直观理解_BP反向传播算法的思考和直观理解 -卷积小白的随机世界

    本篇文章,本来计划再进一步完善对CNN卷积神经网络的理解,但在对卷积层反向传播算法的理解中,越发觉得之前对于BP反向传播算法的理解是不到位的.小白近日觉得,对于深度神经网络,"反向传播&qu ...

  3. 虚拟内存和物理内存的直观理解(概念、区别与联系)

    基本概念 操作系统中有虚拟内存与物理内存的概念. 首先理解一下什么叫物理内存?什么叫虚拟内存? 物理内存是指由于安装内存条而获得的临时储存空间.主要作用是在计算机运行时为操作系统和各种程序提供临时储存 ...

  4. 如何直观理解交叉熵及其优势?

    导语 在统计学中,损失函数是一种衡量系统错误程度的函数.而在有监督学习模型里,损失函数则是衡量模型对样本预测值与样本真实标签之间差异程度的方法.最近用到了交叉熵,觉得有必要弄明白交叉熵到底是什么原理及 ...

  5. BP反向传播算法的思考和直观理解 -卷积小白的随机世界

    https://www.toutiao.com/a6690831921246634504/ 2019-05-14 18:47:24 本篇文章,本来计划再进一步完善对CNN卷积神经网络的理解,但在对卷积 ...

  6. [ML]--梯度下降 GD 的理解和探究

    文章目录 1. Content 2. References 1. Content 2. References 深度理解机器学习"梯度下降" jianshu 一文读懂梯度下降算法 c ...

  7. 3.10 直观理解反向传播-深度学习-Stanford吴恩达教授

    ←上一篇 ↓↑ 下一篇→ 3.9 神经网络的梯度下降法 回到目录 3.11 随机初始化 直观理解反向传播 (Backpropagation Intuition (Optional)) 这个视频主要是推 ...

  8. SVM支持向量机【直观理解】

    转载文章:https://baijiahao.baidu.com/s?id=1607469282626953830&wfr=spider&for=pc 如果你曾经使用机器学习解决分类问 ...

  9. 深度学习与计算机视觉(四)反向传播及其直观理解

    四.反向传播及其直观理解 4.1 引言 问题描述和动机: 大家都知道,其实我们就是在给定的图像像素向量x和对应的函数f(x)f(x)f(x),然后我们希望能够计算fff在x上的梯度∇f(x)" ...

  10. 如何直观理解AUC评价指标?

    导语 最近一直在思考如何直观理解AUC,查了维基百科的以及网上的讲解描述,感觉仍然很难把这个概念表述得通俗易懂,直到昨天周会后拿笔在纸上画了画,感觉似乎找到了一种比较有意思的理解方法,下面就请各位看官 ...

最新文章

  1. SSH: 使用ssh推送github代码
  2. 基于 SpringBoot2 + MybatisPlus 的商城管理系统(附源码)
  3. 计算机专业毕业生管理制度,管理制度建设
  4. dax 计算某一列重复出现次数
  5. 2012.12.26日学习笔记
  6. 手把手JDK环境变量配置
  7. 中国剩余定理(模板+代码)
  8. 现有产品的三种发展战略
  9. Java NIO之缓冲区Buffer
  10. cad2012打开后闪退_【电脑安装好cad一打开闪退】cad安装完打开闪退_cad2012打开闪退...
  11. 2013应届毕业生“艺龙旅行网”校招应聘总结
  12. 唐宋边塞诗词中的古灵州
  13. 湖南大学工训创新大作业——改进电子音乐
  14. mysql数据库查询工具''_数据库查询工具
  15. C++ Point类求两点距离
  16. vscode 代码出现波浪线
  17. 路由器恢复出厂设置上网方式服务器无响应,路由器恢复出厂设置后不能联网了如何解决...
  18. springboot校园兼职系统毕业设计源码463450
  19. 晓说2017-定期持续更新
  20. 字节跳动 前端校招 一二三面+hr面(2020-03)

热门文章

  1. 人人网主页登录_“人人”归来!有人想找前女友,有人想删“黑历史”
  2. JAMA Psychiatry:老年抑郁症患者的神经影像学、认知、临床症状和遗传学的异质性表征
  3. python 断言方法
  4. ubuntu查看磁盘分区使用情况命令df
  5. 格子刷油漆c++dp(最详细)
  6. 【毕业设计】STM32智能药箱系统 - 单片机 嵌入式 物联网
  7. 多功能计算机器在线,多功能数学计算器(RedCrab The Calculator)
  8. 怎么用计算机算lnx,ln计算(log计算器在线)
  9. XTU OJ 1395
  10. oracle工程师 的职业,数据库工程师的职业规划