趋近智
大师班
微积分,特别是微分学,为优化神经网络(包括大型语言模型)所表示的复杂函数提供了数学工具。训练这些模型涉及使损失函数J(θ)最小化,该函数衡量模型在给定当前参数θ的情况下,在训练数据上的表现有多差。基于梯度的优化方法是进行这种最小化的标准方式,它们高度依赖于导数和梯度的观念。
对于一个单变量函数f(x),导数f′(x)或dxdf衡量函数输出相对于其输入的瞬时变化率。它告诉我们输入微小变化时输出的变化量。从几何上看,它代表了函数图在点x处的切线斜率。
然而,神经网络的损失函数依赖于数百万或数十亿个参数(权重和偏置),这些参数统称为向量θ。因此,我们需要明白当我们在微小调整一个特定参数(例如θi),同时保持所有其他参数不变时,损失J(θ)是如何变化的。这正是偏导数所衡量的,记作∂θi∂J。
考虑一个简单的函数f(x,y)=x2y。 对x的偏导数将y视为常量: ∂x∂f=2xy 对y的偏导数将x视为常量: ∂y∂f=x2
多变量函数(例如我们的损失函数J(θ))的梯度是一个包含其所有偏导数的向量。它记作∇J(θ)或∇θJ(θ)。如果θ=(θ1,θ2,...,θn),那么:
∇J(θ)=(∂θ1∂J,∂θ2∂J,...,∂θn∂J)
梯度向量∇J(θ)有一个非常重要的特性:它指向函数J在点θ处最陡峭上升的方向。相反,负梯度−∇J(θ)则指向最陡峭下降的方向。这是梯度下降优化的主要原理。为了使损失最小化,我们希望沿着与梯度相反的方向调整参数θ。
神经网络本质上是复杂的嵌套函数。一个层的输出成为下一层的输入。例如,预测一个词可能涉及将输入嵌入通过多个Transformer层,每个层执行矩阵乘法并应用激活函数,最终通过softmax函数计算出词汇表上的概率分布。
为了计算网络深处参数θ(例如,早期层中的权重)相对于最终损失J的梯度,我们需要链式法则。链式法则使我们能够计算复合函数的导数。
如果变量z依赖于y,而y又依赖于x(即z=f(y)且y=g(x)),链式法则阐明了x的变化如何影响z:
dxdz=dydz⋅dxdy
在神经网络的背景下,我们考虑一个简化的序列:输入x,第1层计算h=f1(x,θ1),第2层计算y=f2(h,θ2),损失为J=L(y)。为了找出损失J如何随第一层中的参数θ1变化,我们应用链式法则:
∂θ1∂J=∂y∂J⋅∂h∂y⋅∂θ1∂h
反向传播本质上是一种高效的算法,用于从最终损失开始,逐层向后遍历网络,递归地应用链式法则,以计算损失对所有参数的梯度。
两层网络中依赖关系的简化图示。反向传播通过从J向后应用链式法则来计算如∂θ1∂J的梯度。
一旦我们能够计算梯度∇θJ(θ),我们就可以使用它迭代更新模型参数以最小化损失。最简单的算法是梯度下降。
从参数θ0的初始估计开始,我们使用以下规则重复更新它们:
θt+1=θt−η∇θJ(θt)
这里:
这个过程会重复,直到损失收敛到最小值(或至少一个足够低的值),或者达到预设的迭代次数。实际上,我们通常不会计算整个数据集的梯度(那样就是批量梯度下降),因为大型语言模型的数据集非常庞大。取而代之的是,我们使用随机梯度下降(SGD)或小批量梯度下降,在每一步中仅使用一个或一小批训练样本来估计梯度。这会引入噪声,但在计算上效率更高,并且通常会带来更好的泛化能力。
现代深度学习框架如PyTorch提供了自动微分(autograd)。这意味着我们定义网络的前向传播(输入如何产生输出),而框架会自动计算反向传播所需的梯度,利用链式法则。
这里是一个展示梯度计算的最小PyTorch示例:
import torch
# 定义一些输入张量 x 和参数 w, b
# requires_grad=True 告知 PyTorch 追踪操作以进行梯度计算
x = torch.tensor([1.0, 2.0, 3.0], requires_grad=False)
w = torch.tensor([0.5, -0.1, 0.2], requires_grad=True)
b = torch.tensor(0.1, requires_grad=True)
# 定义一个简单的线性运算(前向传播)
y = torch.dot(w, x) + b
# y = w_1*x_1 + w_2*x_2 + w_3*x_3 + b
# 定义一个虚拟损失函数(例如,输出的平方)
loss = y.square()
# 计算梯度(反向传播)
loss.backward()
# 梯度存储在张量的 .grad 属性中
print(f"w 的梯度: {w.grad}")
print(f"b 的梯度: {b.grad}")
# w_1 的梯度计算示例检查:
# loss = (w_1*x_1 + w_2*x_2 + w_3*x_3 + b)^2
# d(loss)/dw_1 = 2 * (w_1*x_1 + w_2*x_2 + w_3*x_3 + b) * x_1
# d(loss)/dw_1 = 2 * y * x_1
y_val = (0.5 * 1.0 + (-0.1) * 2.0 + 0.2 * 3.0 + 0.1)
# 0.5 - 0.2 + 0.6 + 0.1 = 1.0
grad_w1_manual = 2 * y_val * x[0]
# 2 * 1.0 * 1.0 = 2.0
print(f"手动计算的 w_1 梯度: {grad_w1_manual}")
# 与 w.grad[0] 匹配
这种自动微分能力使工程师能够专注于设计复杂的模型架构和损失函数,而框架则处理优化所需的复杂梯度计算。然而,理解梯度和链式法则的根本原理对于设计高效模型、调试训练问题(如梯度消失或梯度爆炸)以及实现本课程后面将讨论的更高级优化方法仍然非常必要。
这部分内容有帮助吗?
© 2026 ApX Machine Learning用心打造