数值微分:导数,偏导

导数

导数就是表示某个瞬间的变化量。它可以定义成下面的式子:请添加图片描述
左边的符号df(x)/dx表示f(x)关于x的导数,即f(x)相对于x的变化程度。式表示的导数的含义是,x的“微小变化”将导致函数f(x)的值在多大程度上发生变化。其中,表示微小变化的h无限趋近0,表示为 lim h→0。Python简单实现导数如下:

# 不好的实现示例
def numerical_diff(f, x):
    h = 10e-50
    return (f(x + h) - f(x)) / h

函数numerical_diff(f, x)的名称来源于数值微分A 的英文numerical differentiation。这个函数有两个参数,即“函数f”和“传给函数f的参数x”。乍一看这个实现没有问题,但是实际上这段代码有两处需要改进的地方。在上面的实现中,因为想把尽可能小的值赋给h(可以话,想让h无限接近0),所以h使用了10e-50(有50个连续的0的“0.00 … 1”)这个微小值。但是,这样反而产生了舍入误差(rounding error)。所谓舍入误差,是指因省略小数的精细部分的数值(比如,小数点第8位以后的数值)而造成最终的计算结果上的误差。也就是说,使用过小的值会造成计算机出现计算上的问题。这是第一个需要改进的地方,即将微小值h改为10−4。使用10−4就可以得到正确的结果。
第二个需要改进的地方与函数f的差分有关。虽然上述实现中计算了函数f在x+h和x之间的差分,但是必须注意到,这个计算从一开始就有误差。如图所示,
在这里插入图片描述
“真的导数”对应函数在x处的斜率(称为切线),但上述实现中计算的导数对应的是(x + h)和x之间的斜率。因此,真的导数(真的切线)和上述实现中得到的导数的值在严格意义上并不一致。这个差异的出现是因为h不可能无限接近0。如图4-5所示,数值微分含有误差。为了减小这个误差,我们可以计算函数f在(x + h)和(x − h)之间的差分。因为这种计算方法以x为中心,计算它左右两边的差分,所以也称为中心差分(而(x + h)和x之间的差分称为前向差分)。Python实现如下:

def numerical_diff(f, x):
    h = 1e-4  # 0.0001
    return (f(x + h) - f(x - h)) / (2 * h)

偏导数

我们来看下式表示的函数,它有两个变量。
在这里插入图片描述
这个式子可以用Python实现如下:

def function_2(x):
    return x[0] ** 2 + x[1] ** 2
    # 或者return np.sum(x**2)

它的图像是一个三维图像:
在这里插入图片描述
在我们来求上式的导数。这里需要注意的是,上式有两个变量,所以有必要区分对哪个变量求导数,即对x0和x1两个变量中的哪一个求导数。另外,我们把这里讨论的有多个变量的函数的导数称为偏导数。我们试着解一下下面两个问题:
求x0 = 3, x1 = 4时,关于x0的偏导数。
求x0 = 3, x1 = 4时,关于x1的偏导数 。

def function_tmp1(x0):
    return x0 * x0 + 4.0 ** 2.0


def function_tmp2(x1):
    return 3.0 ** 2.0 + x1 * x1


def numerical_diff(f, x):
    h = 1e-4  # 0.0001
    return (f(x + h) - f(x - h)) / (2 * h)


print(numerical_diff(function_tmp1, 3.0))  # 6.00000000000378
print(numerical_diff(function_tmp2, 4.0))  # 7.999999999999119

在这些问题中,我们定义了一个只有一个变量的函数,并对这个函数进行了求导。例如,问题1中,我们定义了一个固定x1 = 4的新函数,然后对只有变量x0的函数应用了求数值微分的函数。从上面的计算结果可知,问题1的答案是6.00000000000378,问题2的答案是7.999999999999119,和解析解的导数基本一致。像这样,偏导数和单变量的导数一样,都是求某个地方的斜率。不过,偏导数需要将多个变量中的某一个变量定为目标变量,并将其他变量固定为某个值。在上例的代码中,为了将目标变量以外的变量固定到某些特定的值上,我们定义了新函数。然后,对新定义的函数应用了之前的求数值微分的函数,得到偏导数。

猜你喜欢

转载自blog.csdn.net/weixin_43912621/article/details/127290684