偏导数 -- 多变量函数逐个求导
之前的导数针对一元函数 f(x)。神经网络有数百万参数,需要对每个参数求导。
偏导数 = 多变量函数中,只对其中一个变量求导,其余视为常数。
概念解析
之前我们只处理了一元函数 f(x) 的导数。但真实世界中,事物的结果通常由 多个因素 共同决定。
比如:房价取决于面积、地段、楼层、房龄等多个因素。我们想知道「面积增加 1 平方米,房价涨多少」,就需要把其他因素固定住。
这就是偏导数的核心思想:一次只改变一个变量,观察它对结果的影响,其余变量暂时冻结。
对于 \( f(x, y) = x^2 + xy + y^2 \):
- 对 x 求偏导(y 当常数,y² 当常数后导数为 0,xy 中 y 当常数,x 的导数为 1):\( \frac{\partial f}{\partial x} = 2x + y + 0 \)
- 对 y 求偏导(x 当常数,同理):\( \frac{\partial f}{\partial y} = 0 + x + 2y \)
记号 \( \partial \)(读作"round d"或"partial")表示偏导数,区别于普通导数中的 d。
二阶偏导数
对偏导数再求偏导,得到二阶偏导数:
- \( \frac{\partial^2 f}{\partial x^2} \):对 x 求偏导后,再对 x 求偏导(衡量 x 方向上的曲率)
- \( \frac{\partial^2 f}{\partial x \partial y} \):先对 x 求偏导,再对 y 求偏导(交叉偏导,衡量两变量的交互影响)
神经网络训练的本质:对损失函数关于 每一个参数 求偏导,然后沿负梯度方向更新。
一个百万参数的模型,梯度就是一百万个偏导数的向量。
生活例子
一锅汤的味道
汤的味道取决于盐、酱油、醋等多种调料。你想知道「多放一勺盐,味道变化多大」?
把其他调料用量固定,只看盐的影响——这就是偏导数的思维:一次只改变一个变量。
数学定义
\[ \frac{\partial f}{\partial x} = \lim_{h \to 0} \frac{f(x+h, y) - f(x, y)}{h} \]y 保持不变,只让 x 变化。
Python 动手实践
实例
x, y = sp.symbols('x y')
f = x**2 + x*y + y**2
print(f"f(x,y) = {f}")
print(f"∂f/∂x = {sp.diff(f, x)}") # 2x + y
print(f"∂f/∂y = {sp.diff(f, y)}") # x + 2y
# 二阶偏导
print(f"∂²f/∂x² = {sp.diff(f, x, 2)}") # 2
print(f"∂²f/∂x∂y = {sp.diff(f, x, y)}") # 1
# 线性模型损失对参数的偏导
w, b, xi, yi = sp.symbols('w b x_i y_i')
loss = (w*xi + b - yi)**2
print(f"\nloss=(w·xi+b-yi)^2")
print(f"∂L/∂w = {sp.diff(loss, w)}")
print(f"∂L/∂b = {sp.diff(loss, b)}")
输出为:
f(x,y) = x**2 + x*y + y**2 ∂f/∂x = 2*x + y ∂f/∂y = x + 2*y ∂²f/∂x² = 2 ∂²f/∂x∂y = 1 loss=(w·xi+b-yi)^2 ∂L/∂w = 2*x_i*(b + w*x_i - y_i) ∂L/∂b = 2*b + 2*w*x_i - 2*y_i
AI 中的应用场景
神经网络训练 = 百万次偏导计算
一个百万参数的模型,损失是关于百万个变量的多元函数。每轮训练,自动微分引擎对每一个参数求偏导,得到百万个偏导数值拼成梯度向量,沿负梯度方向更新所有参数。
反向传播中的局部偏导
计算图中每个节点都需要计算局部偏导:加法节点 \( \\partial/\\partial x = 1 \)(梯度原样传回),乘法节点 \( \\partial(xy)/\\partial x = y \)(梯度乘对方值传回)。这些局部偏导沿计算图链式相乘,得到最终参数梯度。
冻结参数的迁移学习
迁移学习中常「冻结」预训练层——这些层的参数不求偏导、不更新。PyTorch 中设置 requires_grad=False,对应参数的偏导计算被跳过,大幅节省显存和计算量。
