这篇回答节选自我的专栏《机器学习中的数学:微积分与最优化》,和大家一起谈谈方向导数和梯度。
欢迎关注我的知乎账号 @石溪 ,将持续发布机器学习数学基础及算法应用等方面的精彩内容。
在程序当中,利用数值方法求出各个自变量偏导数的近似解,其方法和步骤同前面讲过的导数的数值解求法并无二致:把其余的自变量固定,就将偏导数的求解方法等价为了导数的数值求解方法,我们以简单的二元函数 为例,分别来看看如何利用python求解偏导数 和 ,并实际获取点 处的数值解:
代码片段:
def f(x,y): return x**2-y**2 def grad_x(f, x, y): h = 1e-4 return (f(x + h/2, y) - f(x - h/2, y)) / h def grad_y(f, x, y): h = 1e-4 return (f(x, y + h/2) - f(x, y - h/2)) / h print(grad_x(f, -1, -1)) print(grad_y(f, -1, -1))
运行结果:
-2.000000000002 2.000000000002
因此,我们非常轻松的获取了函数 ,在点 处的偏导数 和 。
在前一讲的内容中,我们知道了,二元函数中的梯度概念可以说是一元函数中导数概念的一个延伸和拓展。
他们之间的区别是一元函数的导数 是一个数,而梯度 则是一个向量,对于二元函数 ,梯度对应的向量就是 ,向量的概念大家都很熟悉,他是一个有方向、有大小的量。
那么很显然的,对于一个二元函数 ,在他的定义域内,如果我们把每一个点的梯度都求出来,将每个点的梯度向量和各个点的位置联系起来进行集中展示,就形成了一个梯度场,场的概念是一个比较新的概念,我们还是针对二元函数 来实际展示一下:
代码片段:
import numpy as np import matplotlib.pyplot as plt def f(x, y): return x**2-y**2 def grad_x(f, x, y): h = 1e-4 return (f(x + h/2, y) - f(x - h/2, y)) / h def grad_y(f, x, y): h = 1e-4 return (f(x, y + h/2) - f(x, y - h/2)) / h def numerical_gradient(f,P): grad = np.zeros_like(P) for i in range(P[0].size): grad[0][i] = grad_x(f, P[0][i], P[1][i]) grad[1][i] = grad_y(f, P[0][i], P[1][i]) return grad x = np.arange(-2, 2, 0.25) y = np.arange(-2, 2, 0.25) X, Y = np.meshgrid(x, y) X = X.flatten() Y = Y.flatten() grad = numerical_gradient(f, np.array([X, Y])) plt.quiver(X, Y, grad[0], grad[1])#grad[0]是一个1*X.size的数组 plt.xlim([-2, 2]) plt.ylim([-2, 2]) plt.xlabel('x') plt.ylabel('y') plt.grid() plt.show()
运行结果:
上面这段代码我们简要分析一下:
在 坐标轴上,从-2到2,按照0.25的间隔,我们一共生成了16个点, 坐标也是同理,一共也是有16个点,这样就对应表示出了平面上的256个点。
通过:
X, Y = np.meshgrid(x, y)
进行网格化,得到的 是一个二维数组,16行16列,对应表示平面上的256个点的横坐标,同样 也是一个二维数组,16行16列,依次的对应表示上面那256个点的纵坐标。
X = X.flatten() Y = Y.flatten()
上面的这两行代码将这两个二维数组展平成一维数组, 和 都变成含有256个元素的一维数组,其中 和 分别对应表示这256个点中第 个点的横纵坐标。
def numerical_gradient(f,P): grad = np.zeros_like(P) for i in range(P[0].size): grad[0][i] = grad_x(f, P[0][i], P[1][i]) grad[1][i] = grad_y(f, P[0][i], P[1][i]) return grad
上面 这个函数,则用于求取整个定义域上的梯度,传入的 是一个 的数组, 就是所有点的 坐标构成的一维数组 ,而 就是所有点的 坐标构成的二维数组 ,我们利用数值求解的方法求取各个点的偏导数 和 ,同样存储在一个 的二维数组 当中,其中 和 分别代表了第 个点的 和 ,因此向量 所表示的就是第 个点的梯度。
最后我们利用 将所有点的梯度用箭头的形式绘制出来, , 表示箭头的起点, , 表示的是箭头的方向。
对于一个二元函数 而言,偏导数 的几何意义是表示沿着平行于 轴方向上的函数值的变化率,相应的偏导数 则表示的是沿着平行于 轴方向上的函数值的变化率。
我们用向量来表示这个求导的过程,就会更加清晰的展现其几何意义:
我们用向量 表示所求偏导的对应点 ,即 ,一般我们用 和 分别表示平行于 轴和 轴的单位向量,那么我们可以分别重新用向量来表示偏导数 和 :
,我们将其记作:
,类似的,我们将其记作是:
很显然,我们用向量来表示出了沿着 轴方向的偏导数 以及沿着 轴方向的偏导数 ,但这只是反映了函数沿特殊方向上的变化率。那么我们最终来看一般化的情况,如何表示沿着任意方向的方向导数?
我们设对于任意方向上的单位向量 ,依照定义,二元函数 在 处沿着方向 的方向导数为:
,当然前提条件是这个极限得存在。他反映了函数值沿着方向向量 的变化率。
实际上,根据前面所讲过的内容,二元函数 如果在点 处可微,那么一定满足如下的式子:
,其中 是任意方向上的单位向量。
那么,当 时, ,那么上式就变成了:
而此时,我们仔细一看,这个表达式的左侧 正是函数 在 点处沿着方向向量 的方向导数 ,因此我们得到了我们想要看到的一个结论:
,他说明了函数 在点 处沿方向向量 的方向导数(也就是函数值的变化率) 等于该点处的梯度向量与方向向量 的点积。
5.1.梯度与最大变化率的关系
这个点积的式子,他里面的内涵非常丰富。我们把点积的式子进一步展开后得到:
,其中 是梯度向量 和方向向量 的夹角,那么如果我们想知道在哪个方向上的ff的函数值变化最快,该怎么去分析?
由于 ,显然 ,也就是说:
当 ,即方向向量 和梯度向量 同向时,变化率的取值最大,即增长的最快,为 ,由于 是单位向量,因此变化速率为 。
当 ,即方向向量 和梯度向量 反向时,变化率的取值最小,即下降的最快,变化率为 。
总结起来就是在 点的函数值沿着梯度的方向增加的最快,逆着梯度的方向函数值减小的最快。大家请记住,这个结论非常的重要,在后面的优化方法里还会用到。
5.2.梯度与等位线的关系
那么梯度和等位线之间又有什么样的关系呢?
我们知道,同一等位线上的函数值都是相等的,因此 点处等位线切线方向(我们令单位向量 沿着等位线的切线方向)上函数值的变化率 显然应该为0,那么就有:
,即:点 处的梯度向量和过 点的等位线的切线方向向量 的点积为0,这就说明函数 在点 处的梯度和经过该点的等位线是相互垂直的。
我们实际观察一下,我们绘制函数 的等位线,然后随机在定义域内选取三个点 ,并绘制其梯度向量,观察是否满足和对应点处等位线的垂直关系:
代码片段:
import numpy as np import matplotlib.pyplot as plt def f(x, y): return y**2-x**2 def grad_x(f, x, y): h = 1e-4 return (f(x + h/2, y) - f(x - h/2, y)) / h def grad_y(f, x, y): h = 1e-4 return (f(x, y + h/2) - f(x, y - h/2)) / h x = np.arange(-2, 2, 0.01) y = np.arange(-2, 2, 0.01) X, Y = np.meshgrid(x, y) #添加等高线 C = plt.contour(X, Y, f(X, Y), 36) #增加各等高线的高度值 plt.clabel(C, inline=True, fontsize=12) plt.quiver(-1.5, -1, grad_x(f, -1.5, -1), grad_y(f, -1.5, -1)) plt.quiver(1.0, 0, grad_x(f, 1.0, 0), grad_y(f, 1.0, 0)) plt.quiver(-1.5, 1.5, grad_x(f, -1.5, 1.5), grad_y(f, -1.5, 1.5)) plt.grid() plt.show()
运行结果:
同样的,我们再来看一个二元函数 的等位线和梯度向量的垂直关系:
我们围绕多元函数梯度的概念,对其全面展开了介绍。学习了如何利用程序获取多元函数某一点处的偏导数以及梯度的数值近似解,通过梯度场对梯度有了直观的认识。并从偏导数 和 切入,过渡到任意方向上函数变化率的求法,揭示了梯度与函数值变化率的关系。梯度的概念非常重要,他直接服务于最优化的相关内容。
当然还有《机器学习中的数学(全集)》系列专栏,欢迎大家阅读,配合食用,效果更佳~
有订阅的问题可咨询微信:zhangyumeng0422