梯度计算

什么是梯度

梯度(Gradient)是用于描述多元函数在某一点的变化率最大的方向及其大小。在深度学习中,梯度被广泛用于优化模型参数(如神经网络的权重和偏置),通过梯度下降等算法最小化损失函数。

对于多元函数 f(x_1, x_2, \dots, x_n),其梯度是一个向量,由函数对每个变量的偏导数组成,记作:

\nabla f = \left( \frac{\partial f}{\partial x_1}, \frac{\partial f}{\partial x_2}, \dots, \frac{\partial f}{\partial x_n} \right)

其中:

  • $\nabla f$ 是梯度符号(读作“nabla f”)。
  • $\frac{\partial f}{\partial x_i}$ 是函数 $f$ 对变量 $x_i$ 的偏导数。

直观理解梯度

假设有一个二元函数 f(x, y) = x^2 + y^2,其梯度为:

\nabla f = \left( \frac{\partial f}{\partial x}, \frac{\partial f}{\partial y} \right) = (2x, 2y)

在点 (1, 1) 处,梯度为 (2, 2),表示函数在该点沿方向 (2, 2) 增长最快。

若想最小化 f(x, y),应沿着负梯度方向 -(2, 2) 移动,即更新参数:

x \leftarrow x - \alpha \cdot 2x

y \leftarrow y - \alpha \cdot 2y

其中 \alpha 是学习率。

梯度在机器学习中的作用

在机器学习中,梯度表示损失函数(Loss Function)对模型参数的敏感度。例如,对于模型参数 W(权重)和 b(偏置),梯度 \nabla L 包含两个分量:

\nabla L = \left( \frac{\partial L}{\partial W}, \frac{\partial L}{\partial b} \right)

通过沿着负梯度方向更新参数(即梯度下降),可以逐步降低损失函数的值。

梯度下降的示例

目标:最小化函数 (线性回归的损失函数)。

L(W, b) = (W \cdot x + b - y_{\text{true}})^2

假设

x = 2, \quad y_{\text{true}} = 4, \quad W = 1, \quad b = 0.5

计算预测值:

y_{\text{pred}} = W \cdot x + b = 1 \cdot 2 + 0.5 = 2.5

计算损失:

L = (y_{\text{pred}} - y_{\text{true}})^2 = (2.5 - 4)^2 = 2.25

计算梯度:

\frac{\partial L}{\partial W} = 2 (y_{\text{pred}} - y_{\text{true}}) \cdot x = 2 (2.5 - 4) \cdot 2 = -6.0

\frac{\partial L}{\partial b} = 2 (y_{\text{pred}} - y_{\text{true}}) = 2 (2.5 - 4) = -3.0

梯度为

\nabla L = (-6.0, -3.0)

参数更新(学习率 (\alpha = 0.1))

W_{\text{new}} = W - \alpha \cdot \frac{\partial L}{\partial W} = 1 - 0.1 \cdot (-6.0) = 1.6

b_{\text{new}} = b - \alpha \cdot \frac{\partial L}{\partial b} = 0.5 - 0.1 \cdot (-3.0) = 0.8

梯度计算推导

这个公式是梯度计算中的一部分,计算的是损失函数 (L) 对参数 (W) 的偏导数。我们来一步步推导这个公式。

假设损失函数为:

L(W, b) = (W \cdot x + b - y_{\text{true}})^2

其中W是权重,b是偏置,x是输入,y_{\text{true}}是真实的标签。我们要计算的是损失函数 L 对权重 W的偏导数\frac{\partial L}{\partial W}

步骤 1: 定义损失函数

损失函数是预测值和真实值之间的误差的平方,定义为:

L(W, b) = (y_{\text{pred}} - y_{\text{true}})^2

其中,y_{\text{pred}} = W \cdot x + b是模型的预测值。这个损失函数是一个二次函数,目标是最小化它。

步骤 2: 使用链式法则求梯度

我们需要对损失函数 (L) 关于 (W) 求偏导数。首先可以应用链式法则:

\frac{\partial L}{\partial W} = \frac{\partial L}{\partial y_{\text{pred}}} \cdot \frac{\partial y_{\text{pred}}}{\partial W}

步骤 3: 计算每一部分的偏导数

  1. 第一部分: 计算 \frac{\partial L}{\partial y_{\text{pred}}}

由于损失函数是平方误差形式:

L = (y_{\text{pred}} - y_{\text{true}})^2

y_{\text{pred}}求导,得到:

\frac{\partial L}{\partial y_{\text{pred}}} = 2(y_{\text{pred}} - y_{\text{true}})

  1. 第二部分: 计算 \frac{\partial y_{\text{pred}}}{\partial W}

由于 y_{\text{pred}}= W \cdot x + b,对W求导,得到:

\frac{\partial y_{\text{pred}}}{\partial W} = x

步骤 4: 合并结果

现在将两部分结果结合起来:

\frac{\partial L}{\partial W} = 2(y_{\text{pred}} - y_{\text{true}}) \cdot x

步骤 5: 将具体数值代入

根据给定的数值 x = 2,y_{\text{true}} = 4, W = 1, 和 b = 0.5,我们首先计算预测值y_{\text{pred}}

y_{\text{pred}} = W \cdot x + b = 1 \cdot 2 + 0.5 = 2.5

然后代入到梯度公式中:

\frac{\partial L}{\partial W} = 2(2.5 - 4) \cdot 2 = 2(-1.5) \cdot 2 = -6.0

所以,损失函数LW的偏导数是 -6.0

总结:对于复杂的梯度计算可以利用链式法则。在该示例中,先令 y_{\text{pred}}= W \cdot x + b。对W求偏导,就可以转化为,\frac{\partial L}{\partial W} = \frac{\partial L}{\partial y_{\text{pred}}} \cdot \frac{\partial y_{\text{pred}}}{\partial W},然后可以先求\frac{\partial L}{\partial y_{\text{pred}}},再求\frac{\partial y_{\text{pred}}}{\partial W},这样计算就没有这么复杂了。根据公式\frac{\partial L}{\partial y_{\text{pred}}} = 2(y_{\text{pred}} - y_{\text{true}}),而\frac{\partial y_{\text{pred}}}{\partial W} = x,所以\frac{\partial L}{\partial W} = 2(y_{\text{pred}} - y_{\text{true}}) \cdot x,因此知道预测值、真实值、输入值、当前的权重和偏置即可算出偏导。同理b也可以用类似方法,继而算出损失函数的梯度\nabla L = \left( \frac{\partial L}{\partial W}, \frac{\partial L}{\partial b} \right)

pytorch示例

在pytorch中通过自动微分Autograd自动计算梯度,示例如下:

import torch

# 定义参数(启用梯度追踪)
W = torch.tensor(1.0, requires_grad=True)
b = torch.tensor(0.5, requires_grad=True)

# 输入数据
x = torch.tensor(2.0)
y_true = torch.tensor(4.0)

# 前向传播
y_pred = W * x + b
loss = (y_pred - y_true) ** 2

# 反向传播计算梯度
loss.backward()

# 输出梯度
print(f"dL/dW: {W.grad}")  # 输出 tensor(-6.0)
print(f"dL/db: {b.grad}")  # 输出 tensor(-3.0)
概念 数学表达 意义
梯度定义 ∇f = (∂f/∂x₁, …) 多元函数变化最快的方向及其速率
梯度下降 W ← W − α ⋅ ∂L/∂W 沿负梯度方向更新参数以最小化损失函数
PyTorch自动微分 loss.backward() 通过反向传播自动计算所有参数的梯度并存储在 .grad 中