【深度学习】— 微积分—导数和微分 、导数的定义 、导数的数值计算 、导数的符号 、常用导数规则 、微分法则 、应用示例 、偏导数 、梯度 、梯度的常用公式 、链式法则
导数和微分
导数是深度学习优化算法中的关键步骤。我们通常选择对模型参数可微的损失函数,以便了解每个参数对损失的影响。
导数的定义
假设我们有一个函数
f
:
R
→
R
f : \mathbb{R} \to \mathbb{R}
f:R→R,它的导数定义为:
f
′
(
x
)
=
lim
h
→
0
f
(
x
+
h
)
−
f
(
x
)
h
f'(x) = \lim_{h \to 0} \frac{f(x + h) - f(x)}{h}
f′(x)=h→0limhf(x+h)−f(x)
如果
f
′
(
a
)
f'(a)
f′(a) 存在,则称
f
f
f 在
a
a
a 处是可微的。导数
f
′
(
x
)
f'(x)
f′(x) 表示
f
(
x
)
f(x)
f(x) 相对于
x
x
x 的瞬时变化率。
导数的数值计算
让我们用一个函数 f ( x ) = 3 x 2 − 4 x f(x) = 3x^2 - 4x f(x)=3x2−4x 进行实验,计算 f ′ ( 1 ) f'(1) f′(1):
import numpy as np
def f(x):
return 3 * x ** 2 - 4 * x
def numerical_lim(f, x, h):
return (f(x + h) - f(x)) / h
h = 0.1
for i in range(5):
print(f'h={h:.5f}, numerical limit={numerical_lim(f, 1, h):.5f}')
h *= 0.1
输出:
h=0.10000, numerical limit=2.30000
h=0.01000, numerical limit=2.03000
h=0.00100, numerical limit=2.00300
h=0.00010, numerical limit=2.00030
h=0.00001, numerical limit=2.00003
当 h h h 接近 0 时,数值结果接近 2 2 2。
导数的符号
给定
y
=
f
(
x
)
y = f(x)
y=f(x),以下导数符号是等价的:
f
′
(
x
)
=
y
′
=
d
y
d
x
=
d
f
d
x
=
d
d
x
f
(
x
)
=
D
f
(
x
)
=
D
x
f
(
x
)
f'(x) = y' = \frac{dy}{dx} = \frac{df}{dx} = \frac{d}{dx}f(x) = Df(x) = D_x f(x)
f′(x)=y′=dxdy=dxdf=dxdf(x)=Df(x)=Dxf(x)
常用导数规则
- D [ C ] = 0 D[C] = 0 D[C]=0 ( C C C 是常数)
- D [ x n ] = n x n − 1 D[x^n] = nx^{n-1} D[xn]=nxn−1 (幂律)
- D [ e x ] = e x D[e^x] = e^x D[ex]=ex
- D [ ln ( x ) ] = 1 x D[\ln(x)] = \frac{1}{x} D[ln(x)]=x1
微分法则
假设 f ( x ) f(x) f(x) 和 g ( x ) g(x) g(x) 都可微, C C C 是常数,则:
- 常数相乘法则:
d d x [ C f ( x ) ] = C d d x f ( x ) \frac{d}{dx}[Cf(x)] = C \frac{d}{dx}f(x) dxd[Cf(x)]=Cdxdf(x) - 加法法则: d d x [ f ( x ) + g ( x ) ] = d d x f ( x ) + d d x g ( x ) \frac{d}{dx}[f(x) + g(x)] = \frac{d}{dx}f(x) + \frac{d}{dx}g(x) dxd[f(x)+g(x)]=dxdf(x)+dxdg(x)
- 乘法法则: d d x [ f ( x ) g ( x ) ] = f ( x ) d d x [ g ( x ) ] + g ( x ) d d x [ f ( x ) ] \frac{d}{dx}[f(x)g(x)] = f(x) \frac{d}{dx}[g(x)] + g(x) \frac{d}{dx}[f(x)] dxd[f(x)g(x)]=f(x)dxd[g(x)]+g(x)dxd[f(x)]
- 除法法则:
d d x [ f ( x ) g ( x ) ] = g ( x ) d d x [ f ( x ) ] − f ( x ) d d x [ g ( x ) ] [ g ( x ) ] 2 \frac{d}{dx}\left[\frac{f(x)}{g(x)}\right] = \frac{g(x) \frac{d}{dx}[f(x)] - f(x) \frac{d}{dx}[g(x)]}{[g(x)]^2} dxd[g(x)f(x)]=[g(x)]2g(x)dxd[f(x)]−f(x)dxd[g(x)]
应用示例
对
f
(
x
)
=
3
x
2
−
4
x
f(x) = 3x^2 - 4x
f(x)=3x2−4x,我们可以应用上述规则计算其导数:
f
′
(
x
)
=
3
⋅
2
x
−
4
=
6
x
−
4
f'(x) = 3 \cdot 2x - 4 = 6x - 4
f′(x)=3⋅2x−4=6x−4
当
x
=
1
x = 1
x=1 时,
f
′
(
1
)
=
2
f'(1) = 2
f′(1)=2,与前面的实验结果一致。此导数也是曲线
u
=
f
(
x
)
u = f(x)
u=f(x) 在
x
=
1
x = 1
x=1 处切线的斜率。
偏导数
在深度学习中,函数通常依赖于多个变量,因此需要将导数的概念推广到多元函数上。
假设
y
=
f
(
x
1
,
x
2
,
…
,
x
n
)
y = f(x_1, x_2, \ldots, x_n)
y=f(x1,x2,…,xn) 是一个关于
n
n
n 个变量的函数,
y
y
y 关于第
i
i
i 个参数
x
i
x_i
xi 的偏导数定义为:
∂
y
∂
x
i
=
lim
h
→
0
f
(
x
1
,
…
,
x
i
−
1
,
x
i
+
h
,
x
i
+
1
,
…
,
x
n
)
−
f
(
x
1
,
…
,
x
i
,
…
,
x
n
)
h
\frac{\partial y}{\partial x_i} = \lim_{h \to 0} \frac{f(x_1, \ldots, x_{i-1}, x_i + h, x_{i+1}, \ldots, x_n) - f(x_1, \ldots, x_i, \ldots, x_n)}{h}
∂xi∂y=h→0limhf(x1,…,xi−1,xi+h,xi+1,…,xn)−f(x1,…,xi,…,xn)
为了计算 ∂ y ∂ x i \cfrac{\partial y}{\partial x_i} ∂xi∂y,我们可以将除 x i x_i xi 之外的其他变量视为常数,进而计算 y y y 关于 x i x_i xi 的导数。
偏导数的常用符号包括:
∂
y
∂
x
i
=
∂
f
∂
x
i
=
f
x
i
=
f
i
=
D
i
f
=
D
x
i
f
\frac{\partial y}{\partial x_i} = \frac{\partial f}{\partial x_i} = f_{x_i} = f_i = D_i f = D_{x_i} f
∂xi∂y=∂xi∂f=fxi=fi=Dif=Dxif
梯度
我们可以将多元函数对其所有变量的偏导数组合起来,形成该函数的梯度(gradient)向量。
假设函数
f
:
R
n
→
R
f : \mathbb{R}^n \to \mathbb{R}
f:Rn→R,其输入是一个
n
n
n 维向量
x
=
[
x
1
,
x
2
,
…
,
x
n
]
⊤
\mathbf{x} = [x_1, x_2, \ldots, x_n]^\top
x=[x1,x2,…,xn]⊤,输出是一个标量。函数
f
(
x
)
f(\mathbf{x})
f(x) 相对于
x
\mathbf{x}
x 的梯度是一个包含
n
n
n 个偏导数的向量:
∇
x
f
(
x
)
=
[
∂
f
(
x
)
∂
x
1
,
∂
f
(
x
)
∂
x
2
,
…
,
∂
f
(
x
)
∂
x
n
]
⊤
\nabla_{\mathbf{x}} f(\mathbf{x}) = \left[ \frac{\partial f(\mathbf{x})}{\partial x_1}, \frac{\partial f(\mathbf{x})}{\partial x_2}, \ldots, \frac{\partial f(\mathbf{x})}{\partial x_n} \right]^\top
∇xf(x)=[∂x1∂f(x),∂x2∂f(x),…,∂xn∂f(x)]⊤
通常情况下, ∇ x f ( x ) \nabla_{\mathbf{x}} f(\mathbf{x}) ∇xf(x) 简写为 ∇ f ( x ) \nabla f(\mathbf{x}) ∇f(x)。
梯度的常用公式
假设 x \mathbf{x} x 为 n n n 维向量,在微分多元函数时经常使用以下规则:
- 对于所有 A ∈ R m × n A \in \mathbb{R}^{m \times n} A∈Rm×n,有 ∇ x ( A x ) = A ⊤ \nabla_{\mathbf{x}} (A\mathbf{x}) = A^\top ∇x(Ax)=A⊤
- 对于所有 A ∈ R n × m A \in \mathbb{R}^{n \times m} A∈Rn×m,有 ∇ x ( x ⊤ A ) = A \nabla_{\mathbf{x}} (\mathbf{x}^\top A) = A ∇x(x⊤A)=A
- 对于所有 A ∈ R n × n A \in \mathbb{R}^{n \times n} A∈Rn×n,有 ∇ x ( x ⊤ A x ) = ( A + A ⊤ ) x \nabla_{\mathbf{x}} (\mathbf{x}^\top A \mathbf{x}) = (A + A^\top)\mathbf{x} ∇x(x⊤Ax)=(A+A⊤)x
- ∇ x ∥ x ∥ 2 = ∇ x ( x ⊤ x ) = 2 x \nabla_{\mathbf{x}} \|\mathbf{x}\|^2 = \nabla_{\mathbf{x}} (\mathbf{x}^\top \mathbf{x}) = 2\mathbf{x} ∇x∥x∥2=∇x(x⊤x)=2x
对于任意矩阵 X X X,也有 ∇ X ∥ X ∥ F 2 = 2 X \nabla_{X} \|X\|_F^2 = 2X ∇X∥X∥F2=2X。
这些梯度的计算在设计深度学习中的优化算法时非常有用。
链式法则
在深度学习中,函数通常是复合函数(composite function),因此直接对这些函数求导可能比较复杂。幸运的是,链式法则使我们能够有效地对复合函数进行微分。
单变量的链式法则
假设
y
=
f
(
u
)
y = f(u)
y=f(u) 和
u
=
g
(
x
)
u = g(x)
u=g(x) 都是可微的,根据链式法则,我们有:
d
y
d
x
=
d
y
d
u
⋅
d
u
d
x
\frac{dy}{dx} = \frac{dy}{du} \cdot \frac{du}{dx}
dxdy=dudy⋅dxdu
这意味着,我们可以先对 f ( u ) f(u) f(u) 关于 u u u 求导,然后对 g ( x ) g(x) g(x) 关于 x x x 求导,最后将两者相乘来获得 y y y 关于 x x x 的导数。
多变量的链式法则
现在,让我们考虑一个更一般的场景,即函数具有任意数量的变量。
假设可微函数 y y y 有 m m m 个变量 u 1 , u 2 , … , u m u_1, u_2, \ldots, u_m u1,u2,…,um,并且每个 u i u_i ui 都是 n n n 个变量 x 1 , x 2 , … , x n x_1, x_2, \ldots, x_n x1,x2,…,xn 的可微函数。注意, y y y 也是关于 x 1 , x 2 , … , x n x_1, x_2, \ldots, x_n x1,x2,…,xn 的函数。
根据链式法则,
y
y
y 关于
x
j
x_j
xj 的偏导数可以表示为:
∂
y
∂
x
j
=
∑
i
=
1
m
∂
y
∂
u
i
⋅
∂
u
i
∂
x
j
\frac{\partial y}{\partial x_j} = \sum_{i=1}^{m} \frac{\partial y}{\partial u_i} \cdot \frac{\partial u_i}{\partial x_j}
∂xj∂y=i=1∑m∂ui∂y⋅∂xj∂ui
这种多变量情况下的链式法则,使得我们可以对深度学习中的复杂复合函数进行微分。这也是反向传播算法在深度学习中有效求解梯度的基础原理。
对于函数 f ( x ) = 3 x 1 2 + 5 e x 2 2 f(\mathbf{x}) = 3x_1^2 + 5e^{x^2_2} f(x)=3x12+5ex22 求梯度
给定函数
f
(
x
)
=
3
x
1
2
+
5
e
x
2
2
f(\mathbf{x}) = 3x_1^2 + 5e^{x_2^2}
f(x)=3x12+5ex22
其中,
x
\mathbf{x}
x 是一个二维向量,
x
=
(
x
1
,
x
2
)
\mathbf{x} = (x_1, x_2)
x=(x1,x2)。
求梯度
梯度是对每个变量的偏导数所组成的向量:
- 对
x
1
x_1
x1 求偏导数:
∂ f ∂ x 1 = 6 x 1 \frac{\partial f}{\partial x_1} = 6x_1 ∂x1∂f=6x1 - 对
x
2
x_2
x2 求偏导数:
∂ f ∂ x 2 = 10 x 2 e x 2 2 \frac{\partial f}{\partial x_2} = 10x_2 e^{x_2^2} ∂x2∂f=10x2ex22
因此,梯度为:
∇
f
(
x
)
=
(
∂
f
∂
x
1
,
∂
f
∂
x
2
)
=
(
6
x
1
,
10
x
2
e
x
2
2
)
\nabla f(\mathbf{x}) = \left( \frac{\partial f}{\partial x_1}, \frac{\partial f}{\partial x_2} \right) = (6x_1, 10x_2 e^{x_2^2})
∇f(x)=(∂x1∂f,∂x2∂f)=(6x1,10x2ex22)
对于函数 f ( x ) = ∥ x ∥ 2 f(\mathbf{x}) = \|\mathbf{x}\|_2 f(x)=∥x∥2 求梯度
给定函数
f
(
x
)
=
∥
x
∥
2
f(\mathbf{x}) = \|\mathbf{x}\|_2
f(x)=∥x∥2
其中
∥
x
∥
2
\|\mathbf{x}\|_2
∥x∥2 是
x
\mathbf{x}
x 的
L
2
L_2
L2 范数,定义为:
∥
x
∥
2
=
x
1
2
+
x
2
2
+
⋯
+
x
n
2
\|\mathbf{x}\|_2 = \sqrt{x_1^2 + x_2^2 + \cdots + x_n^2}
∥x∥2=x12+x22+⋯+xn2
求梯度
梯度的计算公式是:
∇
f
(
x
)
=
x
∥
x
∥
2
\nabla f(\mathbf{x}) = \frac{\mathbf{x}}{\|\mathbf{x}\|_2}
∇f(x)=∥x∥2x
L2范数的梯度公式可以展开为向量的每个分量的梯度。对于向量 x = [ x 1 , x 2 , … , x n ] T \mathbf{x} = [x_1, x_2, \ldots, x_n]^T x=[x1,x2,…,xn]T,其L2范数为:
∥ x ∥ 2 = x 1 2 + x 2 2 + ⋯ + x n 2 \|\mathbf{x}\|_2 = \sqrt{x_1^2 + x_2^2 + \cdots + x_n^2} ∥x∥2=x12+x22+⋯+xn2
对L2范数求向量 x \mathbf{x} x 的梯度,我们得到:
∇ ∥ x ∥ 2 = [ ∂ ∥ x ∥ 2 ∂ x 1 , ∂ ∥ x ∥ 2 ∂ x 2 , … , ∂ ∥ x ∥ 2 ∂ x n ] T \nabla \|\mathbf{x}\|_2 = \left[ \frac{\partial \|\mathbf{x}\|_2}{\partial x_1}, \frac{\partial \|\mathbf{x}\|_2}{\partial x_2}, \ldots, \frac{\partial \|\mathbf{x}\|_2}{\partial x_n} \right]^T ∇∥x∥2=[∂x1∂∥x∥2,∂x2∂∥x∥2,…,∂xn∂∥x∥2]T
现在,我们对每个分量求偏导数:
∂ ∥ x ∥ 2 ∂ x i = ∂ ∂ x i ( x 1 2 + x 2 2 + ⋯ + x n 2 ) \frac{\partial \|\mathbf{x}\|_2}{\partial x_i} = \frac{\partial}{\partial x_i} \left( \sqrt{x_1^2 + x_2^2 + \cdots + x_n^2} \right) ∂xi∂∥x∥2=∂xi∂(x12+x22+⋯+xn2)
使用链式法则,我们有:
∂ ∥ x ∥ 2 ∂ x i = 1 2 x 1 2 + x 2 2 + ⋯ + x n 2 ⋅ 2 x i = x i x 1 2 + x 2 2 + ⋯ + x n 2 \frac{\partial \|\mathbf{x}\|_2}{\partial x_i} = \frac{1}{2\sqrt{x_1^2 + x_2^2 + \cdots + x_n^2}} \cdot 2x_i = \frac{x_i}{\sqrt{x_1^2 + x_2^2 + \cdots + x_n^2}} ∂xi∂∥x∥2=2x12+x22+⋯+xn21⋅2xi=x12+x22+⋯+xn2xi
因此,梯度向量的第 i i i 个分量是:
∂ ∥ x ∥ 2 ∂ x i = x i ∥ x ∥ 2 \frac{\partial \|\mathbf{x}\|_2}{\partial x_i} = \frac{x_i}{\|\mathbf{x}\|_2} ∂xi∂∥x∥2=∥x∥2xi
将所有分量放在一起,我们得到梯度向量:
∇ ∥ x ∥ 2 = [ x 1 ∥ x ∥ 2 , x 2 ∥ x ∥ 2 , … , x n ∥ x ∥ 2 ] T \nabla \|\mathbf{x}\|_2 = \left[ \frac{x_1}{\|\mathbf{x}\|_2}, \frac{x_2}{\|\mathbf{x}\|_2}, \ldots, \frac{x_n}{\|\mathbf{x}\|_2} \right]^T ∇∥x∥2=[∥x∥2x1,∥x∥2x2,…,∥x∥2xn]T
这就是L2范数的梯度向量,它指向 x \mathbf{x} x 方向的单位向量。