1.什么是梯度?
梯度可以理解为一个多变量函数的变化率,它告诉我们在某一点上,函数的输出如何随输入的变化而变化。更直观地说,梯度指示了最优化方向。
- 在机器学习中的作用:在训练模型时,我们的目标是最小化损失函数,以提高模型的准确性。损失函数是衡量模型预测值与真实值之间差距的函数。梯度告诉我们如何调整模型参数,以使损失函数的值减小。
2. 模型参数的优化
考虑一个简单的线性模型:
y=wx+b
- 其中,yy 是输出,xx 是输入,ww 是权重,bb 是偏置。
- 为了训练模型,我们使用损失函数(例如均方误差)来衡量模型输出与真实输出之间的差距。损失函数通常定义为:
Loss=1/N∑i=1N(ypred,i−ytrue,i)^2
- 这里 NN 是样本数,ypred是模型计算的预测值,ytrue是真实值。
3. 反向传播
反向传播是一种高效计算梯度的算法,尤其在深度学习中使用广泛。
3.1 前向传播
在前向传播中,我们将输入数据通过模型传递,计算出预测结果,并基于预测结果与真实结果计算损失。
3.2 计算梯度
反向传播通过链式法则计算梯度,以更新模型参数。通过反向传播,我们可以得到损失函数对每个参数(比如 ww 和 bb)的导数,这些导数就是梯度。
- 链式法则:假设有一个复合函数 z=f(g(x)),则其导数为:
dz/dx=dz/dg⋅dg/dx
这个法则帮助我们逐层计算梯度。
4. 梯度的累加
4.1 为什么会累加?
在训练过程中,我们可能会处理多个训练样本进行参数更新。如果连续调用多次 loss.backward()
,每次都会将计算的梯度值加到之前的梯度上。
- 这意味着如果我们不清零梯度,梯度会随着样本数的增加而不断增加,可能导致参数更新的步幅变得非常大,影响模型的收敛。
4.2 样例代码
让我们通过具体的代码示例来更好地理解梯度的累加和为什么需要清零。
import torch
import torch.nn as nn
import torch.optim as optim
# 定义简单线性模型
model = nn.Linear(1, 1) # 线性模型:1个输入,1个输出
optimizer = optim.SGD(model.parameters(), lr=0.01) # 使用 SGD 优化器