计算神经网络中梯度的核心机制 - 反向传播(backpropagation)算法(1)
flyfish
链式法则在深度学习中的主要应用是在反向传播(backpropagation)算法中。
从简单的开始 ,文本说的就是链式法则
R \mathbb{R} R
- 英文:The set of real numbers
- 解释:符号 R \mathbb{R} R 表示所有实数的集合,包括所有正数、负数和零。在英语中,这个符号称为 “the set of real numbers” 或简称 “the reals”。
- 读作:实数集
- 含义:符号 R \mathbb{R} R 表示所有实数的集合。在数学中,这个符号用来指代从负无穷到正无穷的所有实数。
f ∘ g f \circ g f∘g
- 读作: f f f 复合 g g g
- 含义:符号
∘
\circ
∘ 表示函数的复合。复合函数
f
∘
g
f \circ g
f∘g 表示先应用函数
g
g
g,然后将
g
g
g 的输出作为函数
f
f
f 的输入。形式上,这可以写作:
( f ∘ g ) ( x ) = f ( g ( x ) ) (f \circ g)(x) = f(g(x)) (f∘g)(x)=f(g(x))
例子
假设我们有两个函数
g
(
x
)
=
2
x
+
3
g(x) = 2x + 3
g(x)=2x+3 和
f
(
u
)
=
u
3
f(u) = u^3
f(u)=u3,复合函数
f
∘
g
f \circ g
f∘g 表示为:
(
f
∘
g
)
(
x
)
=
f
(
g
(
x
)
)
=
f
(
2
x
+
3
)
=
(
2
x
+
3
)
3
(f \circ g)(x) = f(g(x)) = f(2x + 3) = (2x + 3)^3
(f∘g)(x)=f(g(x))=f(2x+3)=(2x+3)3
箭头符号的意义
- f : A → B f: A \to B f:A→B 表示函数 f f f 将集合 A A A 中的每个元素映射到集合 B B B 中的一个元素。
- x ↦ f ( x ) x \mapsto f(x) x↦f(x) 表示 x x x 经过函数 f f f 的映射得到 f ( x ) f(x) f(x)。
例子
- 简单映射:
设 f : R → R f: \mathbb{R} \to \mathbb{R} f:R→R 表示一个从实数集合到实数集合的函数。具体的映射可以是:
f ( x ) = x 2 f(x) = x^2 f(x)=x2
这里, f f f 将每个实数 x x x 映射到它的平方 x 2 x^2 x2。 - 复合函数的映射:
如果有两个函数 g g g 和 f f f:
- g : R → R g: \mathbb{R} \to \mathbb{R} g:R→R
-
f
:
R
→
R
f: \mathbb{R} \to \mathbb{R}
f:R→R并且
g
(
x
)
=
2
x
+
3
g(x) = 2x + 3
g(x)=2x+3,
f
(
u
)
=
u
3
f(u) = u^3
f(u)=u3,那么复合函数
f
∘
g
f \circ g
f∘g 可以表示为:
( f ∘ g ) ( x ) = f ( g ( x ) ) (f \circ g)(x) = f(g(x)) (f∘g)(x)=f(g(x))
具体的映射是:
g : x ↦ 2 x + 3 g: x \mapsto 2x + 3 g:x↦2x+3
f : u ↦ u 3 f: u \mapsto u^3 f:u↦u3
结合起来:
( f ∘ g ) : x ↦ ( 2 x + 3 ) 3 (f \circ g): x \mapsto (2x + 3)^3 (f∘g):x↦(2x+3)3
函数的映射关系
在数学中,函数的定义和使用广泛应用于各种映射关系中。箭头符号帮助我们清晰地描述这些关系。更具体地:
- 箭头 → \to → 用于描述集合之间的映射关系。
- 箭头 ↦ \mapsto ↦ 用于描述具体的元素如何被映射。
复合函数的表示
复合函数的映射关系可以通过箭头符号更直观地表示:
- g : A → B g: A \to B g:A→B
- f : B → C f: B \to C f:B→C
- 复合函数
f
∘
g
f \circ g
f∘g 的映射关系为
f
∘
g
:
A
→
C
f \circ g: A \to C
f∘g:A→C
假设 g g g 将 x x x 映射到 u u u,即 g : x ↦ u g: x \mapsto u g:x↦u,并且 f f f 将 u u u 映射到 y y y,即 f : u ↦ y f: u \mapsto y f:u↦y。那么复合函数 f ∘ g f \circ g f∘g 将 x x x 直接映射到 y y y,即:
( f ∘ g ) : x ↦ f ( g ( x ) ) (f \circ g): x \mapsto f(g(x)) (f∘g):x↦f(g(x))
复合函数的概念
如果我们有两个函数:
- g : A → B g: A \to B g:A→B
-
f
:
B
→
C
f: B \to C
f:B→C
其中,函数 g g g 将集合 A A A 中的元素映射到集合 B B B,而函数 f f f 将集合 B B B 中的元素映射到集合 C C C。那么,复合函数 f ∘ g f \circ g f∘g 将集合 A A A 中的元素直接映射到集合 C C C,即:
( f ∘ g ) ( x ) = f ( g ( x ) ) (f \circ g)(x) = f(g(x)) (f∘g)(x)=f(g(x))
例子
- 简单的复合函数:
设 g ( x ) = x 2 g(x) = x^2 g(x)=x2 和 f ( u ) = sin ( u ) f(u) = \sin(u) f(u)=sin(u)。复合函数 ( f ∘ g ) ( x ) (f \circ g)(x) (f∘g)(x) 表示为:
( f ∘ g ) ( x ) = f ( g ( x ) ) = sin ( x 2 ) (f \circ g)(x) = f(g(x)) = \sin(x^2) (f∘g)(x)=f(g(x))=sin(x2)
在这个例子中,先计算内部函数 g ( x ) = x 2 g(x) = x^2 g(x)=x2,然后将结果代入到外部函数 f ( u ) = sin ( u ) f(u) = \sin(u) f(u)=sin(u)。 - 其他例子:
设 g ( x ) = 2 x + 3 g(x) = 2x + 3 g(x)=2x+3 和 f ( u ) = u 3 f(u) = u^3 f(u)=u3。复合函数 ( f ∘ g ) ( x ) (f \circ g)(x) (f∘g)(x) 表示为:
( f ∘ g ) ( x ) = f ( g ( x ) ) = ( 2 x + 3 ) 3 (f \circ g)(x) = f(g(x)) = (2x + 3)^3 (f∘g)(x)=f(g(x))=(2x+3)3
假设我们有两个函数 g ( x ) g(x) g(x) 和 f ( u ) f(u) f(u):
- 先绘制 g ( x ) g(x) g(x) 的图形。例如, g ( x ) = x 2 g(x) = x^2 g(x)=x2 是一个抛物线。
- 然后将
g
(
x
)
g(x)
g(x) 的输出代入
f
(
u
)
f(u)
f(u),绘制
f
(
g
(
x
)
)
f(g(x))
f(g(x)) 的图形。例如,
f
(
u
)
=
sin
(
u
)
f(u) = \sin(u)
f(u)=sin(u),将
u
=
x
2
u = x^2
u=x2 代入,得到
sin
(
x
2
)
\sin(x^2)
sin(x2) 的图形。
import numpy as np
import matplotlib.pyplot as plt
# 定义两个函数
def g(x):
return x**2
def f(u):
return np.sin(u)
# 生成x的值
x = np.linspace(-2, 2, 400)
y_g = g(x)
y_f = f(y_g)
# 初始化图形
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(8, 12))
# 绘制函数 g(x)
ax1.plot(x, y_g, label=r'$g(x) = x^2$', color='blue')
ax1.set_title('Function $g(x)$')
ax1.set_xlabel('$x$')
ax1.set_ylabel('$g(x)$')
ax1.legend()
# 绘制函数 f(u)
u = np.linspace(0, 4, 400)
ax2.plot(u, f(u), label=r'$f(u) = \sin(u)$', color='green')
ax2.set_title('Function $f(u)$')
ax2.set_xlabel('$u$')
ax2.set_ylabel('$f(u)$')
ax2.legend()
# 绘制复合函数 h(x) = f(g(x))
ax3.plot(x, y_f, label=r'$h(x) = \sin(x^2)$', color='red')
ax3.set_title('Composite Function $h(x) = f(g(x))$')
ax3.set_xlabel('$x$')
ax3.set_ylabel('$h(x)$')
ax3.legend()
# 调整子图之间的间距
plt.subplots_adjust(hspace=0.5)
# 显示图形
plt.show()
链式法则(Chain Rule)是微积分中一个重要的求导法则,它用于求复合函数的导数。复合函数是指一个函数的输入是另一个函数的输出,形式上可以写作 y = f ( g ( x ) ) y = f(g(x)) y=f(g(x))。链式法则告诉我们如何求这种复合函数的导数。
如果我们有两个函数
f
f
f 和
g
g
g,其中
y
=
f
(
u
)
y = f(u)
y=f(u) 且
u
=
g
(
x
)
u = g(x)
u=g(x),那么根据链式法则,复合函数
y
=
f
(
g
(
x
)
)
y = f(g(x))
y=f(g(x)) 对
x
x
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
用更直观的方式理解,链式法则表明:
- 首先求出内部函数 u = g ( x ) u = g(x) u=g(x) 对 x x x 的导数,即 d u d x \frac{du}{dx} dxdu。
- 然后求出外部函数 y = f ( u ) y = f(u) y=f(u) 对 u u u 的导数,即 d y d u \frac{dy}{du} dudy。
- 最后将这两个导数相乘,得到复合函数 y = f ( g ( x ) ) y = f(g(x)) y=f(g(x)) 对 x x x 的导数。
例子
假设有函数 y = sin ( x 2 ) y = \sin(x^2) y=sin(x2),我们希望求 y y y 对 x x x 的导数。
- 首先,我们将 y = sin ( x 2 ) y = \sin(x^2) y=sin(x2) 看作两个函数的复合,即 y = sin ( u ) y = \sin(u) y=sin(u) 和 u = x 2 u = x^2 u=x2。
- 对内部函数 u = x 2 u = x^2 u=x2 求导: d u d x = 2 x \frac{du}{dx} = 2x dxdu=2x
- 对外部函数 y = sin ( u ) y = \sin(u) y=sin(u) 求导: d y d u = cos ( u ) \frac{dy}{du} = \cos(u) dudy=cos(u)
- 将这两个结果相乘:
d
y
d
x
=
d
y
d
u
⋅
d
u
d
x
=
cos
(
x
2
)
⋅
2
x
\frac{dy}{dx} = \frac{dy}{du} \cdot \frac{du}{dx} = \cos(x^2) \cdot 2x
dxdy=dudy⋅dxdu=cos(x2)⋅2x
所以, y = sin ( x 2 ) y = \sin(x^2) y=sin(x2) 对 x x x 的导数为:
d y d x = 2 x cos ( x 2 ) \frac{dy}{dx} = 2x \cos(x^2) dxdy=2xcos(x2)
微分符号 d d d 的含义
- 导数的定义:
导数表示函数在某一点的变化率。对于函数 y = f ( x ) y = f(x) y=f(x),它在 x x x 处的导数定义为: d y d x = lim Δ x → 0 Δ y Δ x \frac{dy}{dx} = \lim_{\Delta x \to 0} \frac{\Delta y}{\Delta x} dxdy=limΔx→0ΔxΔy这里, Δ y \Delta y Δy 和 Δ x \Delta x Δx 分别表示 y y y 和 x x x 的增量。当这些增量趋近于零时,我们用 d y dy dy 和 d x dx dx 来表示这些非常小的变化量。 - 微分表示法:
微分符号 d d d 用于表示一个函数的微小变化。例如, d x dx dx 表示变量 x x x 的一个非常小的变化量。同样地, d y dy dy 表示函数 y y y 的一个非常小的变化量。如果 y = f ( x ) y = f(x) y=f(x),那么 d y dy dy 表示 y y y 对 x x x 的微小变化,可以表示为: d y = f ′ ( x ) ⋅ d x dy = f'(x) \cdot dx dy=f′(x)⋅dx这里, f ′ ( x ) f'(x) f′(x) 是函数 f ( x ) f(x) f(x) 的导数,表示 x x x 处的变化率。
链式法则中的 d d d
在链式法则中, d d d 表示不同变量的微小变化。例如:
-
d u du du 表示变量 u u u 的微小变化量。
-
d x dx dx 表示变量 x x x 的微小变化量。
-
d y dy dy 表示函数 y y y 的微小变化量。
链式法则告诉我们,当我们有复合函数 y = f ( g ( x ) ) y = f(g(x)) y=f(g(x)) 时, y y y 对 x x x 的变化可以分解为 y y y 对 u u u 的变化以及 u u u 对 x x 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
这里,每个 d d d 都表示相应变量的微小变化。例如: -
d y d x \frac{dy}{dx} dxdy 表示 y y y 对 x x x 的变化率。
-
d y d u \frac{dy}{du} dudy 表示 y y y 对 u u u 的变化率。
-
d u d x \frac{du}{dx} dxdu 表示 u u u 对 x x x 的变化率。
通过这样分解,我们可以更容易地计算复合函数的导数。
基于极限和增量来理解链式法则
- 定义复合函数和导数:
- 设 y = f ( u ) y = f(u) y=f(u),其中 u = g ( x ) u = g(x) u=g(x)。
- 我们需要求 y = f ( g ( x ) ) y = f(g(x)) y=f(g(x)) 对 x x x 的导数。
- 增量表示:
- 令 Δ x \Delta x Δx 是 x x x 的一个非常小的增量。
- 相应的, u u u 有一个非常小的增量 Δ u \Delta u Δu,其中 Δ u = g ( x + Δ x ) − g ( x ) \Delta u = g(x + \Delta x) - g(x) Δu=g(x+Δx)−g(x)。
- y y y 的增量表示为 Δ y = f ( g ( x + Δ x ) ) − f ( g ( x ) ) \Delta y = f(g(x + \Delta x)) - f(g(x)) Δy=f(g(x+Δx))−f(g(x))。
- 导数的定义: d y d x = lim Δ x → 0 Δ y Δ x \frac{dy}{dx} = \lim_{\Delta x \to 0} \frac{\Delta y}{\Delta x} dxdy=limΔx→0ΔxΔy
- 应用链式法则的思想: Δ y = f ( g ( x + Δ x ) ) − f ( g ( x ) ) \Delta y = f(g(x + \Delta x)) - f(g(x)) Δy=f(g(x+Δx))−f(g(x))可以表示为: Δ y Δ x = f ( g ( x + Δ x ) ) − f ( g ( x ) ) Δ x \frac{\Delta y}{\Delta x} = \frac{f(g(x + \Delta x)) - f(g(x))}{\Delta x} ΔxΔy=Δxf(g(x+Δx))−f(g(x))
- 拆分增量:
由于 u = g ( x ) u = g(x) u=g(x),我们可以引入 Δ u \Delta u Δu: Δ y Δ x = f ( g ( x + Δ x ) ) − f ( g ( x ) ) g ( x + Δ x ) − g ( x ) ⋅ g ( x + Δ x ) − g ( x ) Δ x \frac{\Delta y}{\Delta x} = \frac{f(g(x + \Delta x)) - f(g(x))}{g(x + \Delta x) - g(x)} \cdot \frac{g(x + \Delta x) - g(x)}{\Delta x} ΔxΔy=g(x+Δx)−g(x)f(g(x+Δx))−f(g(x))⋅Δxg(x+Δx)−g(x) - 极限过程:
当 Δ x → 0 \Delta x \to 0 Δx→0,我们有 Δ u → 0 \Delta u \to 0 Δu→0,因此: d y d x = lim Δ x → 0 ( f ( g ( x + Δ x ) ) − f ( g ( x ) ) g ( x + Δ x ) − g ( x ) ⋅ g ( x + Δ x ) − g ( x ) Δ x ) \frac{dy}{dx} = \lim_{\Delta x \to 0} \left( \frac{f(g(x + \Delta x)) - f(g(x))}{g(x + \Delta x) - g(x)} \cdot \frac{g(x + \Delta x) - g(x)}{\Delta x} \right) dxdy=Δx→0lim(g(x+Δx)−g(x)f(g(x+Δx))−f(g(x))⋅Δxg(x+Δx)−g(x))根据导数的定义,我们有: d y d x = ( lim Δ u → 0 Δ y Δ u ) ⋅ ( lim Δ x → 0 Δ u Δ x ) \frac{dy}{dx} = \left( \lim_{\Delta u \to 0} \frac{\Delta y}{\Delta u} \right) \cdot \left( \lim_{\Delta x \to 0} \frac{\Delta u}{\Delta x} \right) dxdy=(Δu→0limΔuΔy)⋅(Δx→0limΔxΔu) - 导数表示:
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其中,
d
y
d
u
=
lim
Δ
u
→
0
Δ
y
Δ
u
\frac{dy}{du} = \lim_{\Delta u \to 0} \frac{\Delta y}{\Delta u}
dudy=Δu→0limΔuΔy 和
d
u
d
x
=
lim
Δ
x
→
0
Δ
u
Δ
x
\frac{du}{dx} = \lim_{\Delta x \to 0} \frac{\Delta u}{\Delta x}
dxdu=Δx→0limΔxΔu。
因此复合函数的导数可以表示为外层函数的导数乘以内层函数的导数。
可视化:
- g(x):定义了内层函数 sin ( x ) \sin(x) sin(x)。
- f(u):定义了外层函数 exp ( u ) \exp(u) exp(u)。
- g_prime(x) 和 f_prime(u):定义了对应的导数。
- h(x):复合函数 e sin ( x ) e^{\sin(x)} esin(x)。
- h_prime(x):复合函数的导数,使用链式法则 f ′ ( g ( x ) ) ⋅ g ′ ( x ) f'(g(x)) \cdot g'(x) f′(g(x))⋅g′(x)。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
# 定义两个函数及其导数
def g(x):
return np.sin(x)
def f(u):
return np.exp(u)
def g_prime(x):
return np.cos(x)
def f_prime(u):
return np.exp(u)
# 复合函数及其导数
def h(x):
return f(g(x))
def h_prime(x):
return f_prime(g(x)) * g_prime(x)
# 生成x的值
x = np.linspace(0, 2 * np.pi, 400)
y_g = g(x)
y_f = f(y_g)
y_h = h(x)
# 初始化图形
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(8, 12))
# 绘制函数 g(x)
ax1.plot(x, y_g, label=r'$g(x) = \sin(x)$', color='blue')
ax1.set_title('Function $g(x)$')
ax1.set_xlabel('$x$')
ax1.set_ylabel('$g(x)$')
ax1.legend()
# 绘制函数 f(u)
u = np.linspace(-1, 1, 400)
ax2.plot(u, f(u), label=r'$f(u) = e^{u}$', color='green')
ax2.set_title('Function $f(u)$')
ax2.set_xlabel('$u$')
ax2.set_ylabel('$f(u)$')
ax2.legend()
# 绘制复合函数 h(x) = f(g(x))
ax3.plot(x, y_h, label=r'$h(x) = e^{\sin(x)}$', color='red')
ax3.set_title('Composite Function $h(x) = f(g(x))$')
ax3.set_xlabel('$x$')
ax3.set_ylabel('$h(x)$')
ax3.legend()
plt.subplots_adjust(hspace=0.5)
# 初始化点和切线
point1, = ax1.plot([], [], 'ro') # 点
tangent_line1, = ax1.plot([], [], 'r--') # 切线
point2, = ax2.plot([], [], 'ro') # 点
tangent_line2, = ax2.plot([], [], 'r--') # 切线
point3, = ax3.plot([], [], 'ro') # 点
tangent_line3, = ax3.plot([], [], 'r--') # 切线
def init():
point1.set_data([], [])
tangent_line1.set_data([], [])
point2.set_data([], [])
tangent_line2.set_data([], [])
point3.set_data([], [])
tangent_line3.set_data([], [])
return point1, tangent_line1, point2, tangent_line2, point3, tangent_line3
def animate(i):
x0 = i * 2 * np.pi / 100 # 从 0 开始,步长为 2π / 100
y0_g = g(x0)
y0_h = h(x0)
# 绘制 g(x) 的点和切线
slope_g = g_prime(x0)
point1.set_data([x0], [y0_g])
tangent_x1 = np.array([x0 - 0.5, x0 + 0.5])
tangent_y1 = y0_g + slope_g * (tangent_x1 - x0)
tangent_line1.set_data(tangent_x1, tangent_y1)
# 绘制 f(g(x)) 的点和切线
u0 = y0_g
y0_f = f(u0)
slope_f = f_prime(u0)
point2.set_data([u0], [y0_f])
tangent_x2 = np.array([u0 - 0.5, u0 + 0.5])
tangent_y2 = y0_f + slope_f * (tangent_x2 - u0)
tangent_line2.set_data(tangent_x2, tangent_y2)
# 绘制 h(x) = f(g(x)) 的点和切线
slope_h = h_prime(x0)
point3.set_data([x0], [y0_h])
tangent_x3 = np.array([x0 - 0.5, x0 + 0.5])
tangent_y3 = y0_h + slope_h * (tangent_x3 - x0)
tangent_line3.set_data(tangent_x3, tangent_y3)
return point1, tangent_line1, point2, tangent_line2, point3, tangent_line3
ani = animation.FuncAnimation(fig, animate, frames=100, init_func=init, blit=True)
# 保存为gif
ani.save('chain_rule_animation.gif', writer='imagemagick')
# 显示动画
plt.show()