首页人工智能7.数值微分与偏导数

7.数值微分与偏导数

为了找出尽可能小的损失函数的值,将会利用函数斜率的梯度法,神经网络的梯度求解的本质就是求导。

1.数值微分:

函数的导数公式如下:

$$
\frac{df\left( x \right)}{dx}=\lim_{h\rightarrow 0} \frac{f\left( x+h \right) -f\left( x \right)}{h}
$$

一般基于数学公式的求导过程称为“解析式求导/解析式求解”,比如求解y=x²的导数,可以通过

$$\frac{dy}{dx}=2x$$

解析性的求解出来,也就是说解析式求导过程得到的导数是不含误差的“真的导数”。

而利用微小的差分求导数的过程称为“数值微分(numerical differentiation)”,比如赋予下面h一个微小值就可以近似求出函数在某点的导数。

$$
\frac{f\left( x+h \right) -f\left( x \right)}{h}
$$

代码中的实现:

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

此处需要注意的是:

  • h的值不能使用过小的值,否则会产生“舍入误差(rounding error)”错误。
  • 因为数值微分求导含有误差,为了减小这个误差,应该采用中心差分(计算f(x)在(x+h)和(x-h)之间的差分),而不应该采用前向差分(计算f(x)在(x+h)和(x)之间的差分)。

2.数值微分实例:

采用数值微分的方法,对下面函数求导:

$$
y=0.01x^2+0.1x
$$

计算该函数在x=5处的导数

import numpy as np
import matplotlib.pylab as plt

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

def function_1(x):
    return 0.01*x**2 + 0.1*x 

def tangent_line(f, x):
    d = numerical_diff(f, x)
    print(d)
    y = f(x) - d*x
    return lambda t: d*t + y
     
x = np.arange(0.0, 20.0, 0.1)
y = function_1(x)
plt.xlabel("x")
plt.ylabel("f(x)")

tf = tangent_line(function_1, 5)
y2 = tf(x)

plt.plot(x, y)
plt.plot(x, y2)
plt.show()

运行得到结果:

0.1999999999990898

以及采用数值微分求解的值为斜率的直线:

另外通过解析式过程得到的函数解析解为:

$$
\frac{\text{d}f\left( x \right)}{\text{d}x}=0.02x+0.1
$$

进而求得,函数在x=5处的导数值为0.2.可以看出与采用数值微分求得的结果之间的误差非常小,两者近似相等。

3.偏导数:

现在来看下面这个函数,与上面的函数不同的是,该函数有两个变量。

$$
f\left( x_0,x_1 \right) =x_{0}^{2}+x_{1}^{2}
$$

对多变量函数的求导时要区分对哪个变量求导,有多个变量的函数的导数就称为“偏导数”,用数学式表达如下:

$$
\frac{\partial f}{\partial x_0}\text{、}\frac{\partial f}{\partial x_1}
$$

现在通过数值微分的方法来求解偏导数。

  • 求x0=3,x1=4时,关于x0的偏导数:
def numerical_differentiation(f,x):
	h = 1e-4
	return (f(x+h)-f(x-h)) / (2*h)

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

print(numerical_differentiation(function,3.0))

运行得到结果

6.00000000000378
  • 同理可以,求得x0=3,x1=4时,关于x1的偏导数:
def numerical_differentiation(f,x):
	h = 1e-4
	return (f(x+h)-f(x-h)) / (2*h)

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

print(numerical_differentiation(function,4.0))

运行得到结果

7.999999999999119

通过上述例子,可以看出偏导数和单变量的导数一样,都是求某个地方的斜率。不同的是,偏导数需要将多个变量中的某一个变量定位目标变量,并将其他变量固定为某个值,也就是说要对每个变量单独求导。

Reference:
《Deep Learning from Scratch》

Previous article6.神经网络的学习
Next article8.梯度
RELATED ARTICLES

欢迎留下您的宝贵建议

Please enter your comment!
Please enter your name here

- Advertisment -

Most Popular

Recent Comments