我们看一下式 (4.6) 表示的函数。虽然它只是一个计算参数的平方和的简单函数,但是请注意和上例不同的是,这里有两个变量。
def function_2(x):
return x[0] ** 2 + x[1] ** 2
# 或者return np.sum(x**2)
这里,我们假定向参数输入了一个 NumPy 数组。函数的内部实现比较简单,先计算 NumPy 数组中各个元素的平方,再求它们的和(np.sum(x**2) 也可以实现同样的处理)。我们来画一下这个函数的图像。结果如图 4-8 所示,是一个三维图像。
现在我们来求式(4.6)的导数。这里需要注意的是,式(4.6)有两个变量,所以有必要区分对哪个变量求导数,即对 x0 和 x1 两个变量中的哪一个求导数。另外,我们把这里讨论的有多个变量的函数的导数称为偏导数 。用数学式表示的话,可以写成
∂
f
∂
x
0
、
∂
f
∂
x
1
\frac{\partial f}{\partial x_0} 、\frac{\partial f}{\partial x_1}
∂x0∂f、∂x1∂f
怎么求偏导数呢?我们先试着解一下下面两个关于偏导数的问题。
问题 1 :求 x_0=3,x_1=4 时,关于 x_0 的偏导数 ∂ f ∂ x 0 \frac{\partial f}{\partial x_0} ∂x0∂f
import numpy as np
def numerical_diff(f, x):
h = 1e-4
return (f(x + h) - f(x - h)) / (2 * h)
def function(x):
return x[0] ** 2 + x[1] ** 2
# return np.sum(x**2)
def function_tmp1(x):
return x ** 2 + 4 ** 2
if __name__ == '__main__':
print(numerical_diff(function_tmp1, 3))
运行结果:
6.00000000000378
问题 2 :求 x_0=3,x_1=4 时,关于 x_1 的偏导数 ∂ f ∂ x 1 \frac{\partial f}{\partial x_1} ∂x1∂f
import numpy as np
def numerical_diff(f, x):
h = 1e-4
return (f(x + h) - f(x - h)) / (2 * h)
def function(x):
return x[0] ** 2 + x[1] ** 2
# return np.sum(x**2)
def function_tmp2(x):
return 3 ** 2 + x ** 2
if __name__ == '__main__':
print(numerical_diff(function_tmp2, 4))
运行结果:
7.999999999999119
在这些问题中,我们定义了一个只有一个变量的函数,并对这个函数进行了求导。例如,问题 1 中,我们定义了一个固定 x1 = 4 的新函数,然后对只有变量 x0 的函数应用了求数值微分的函数。从上面的计算结果可知,问题 1 的答案是 6.00000000000378,问题 2 的答案是 7.999999999999119,和解析解的导数基本一致。
像这样,偏导数和单变量的导数一样,都是求某个地方的斜率。不过,偏导数需要将多个变量中的某一个变量定为目标变量,并将其他变量固定为某个值。在上例的代码中,为了将目标变量以外的变量固定到某些特定的值上,我们定义了新函数。然后,对新定义的函数应用了之前的求数值微分的函数,得到偏导数。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)