1. 什么是梯度?
打个比方:想象你在一片黑暗的山丘上,手里有一盏灯,想找到山谷里最低的那一点(也就是模型的最优解)。梯度就像这盏灯的光束,它会告诉你:“往哪个方向走,能最快下山。”
• 数学定义:梯度是函数在某一点的“最陡上升方向”。但在机器学习中,我们通常需要找最小值,所以会朝梯度的反方向走(相当于“下山”)。
2. 为什么需要梯度?
• 目标:训练模型时,我们需要调整参数(比如房价预测中的“面积权重”“房间数权重”),让模型预测值尽量接近真实值。
• 问题:如果盲目的调整参数,可能会像无头苍蝇一样找不到方向。梯度就相当于给了你一张“地图”,告诉你每一步该往哪迈多大的步子。
3. 计算步骤
- 假设模型参数
- 给错误打分(损失函数)
- 计算梯度(找方向)
- 调整参数(开始“下山”)
4. 梯度的实际作用
• 指导方向:梯度指向损失函数下降最快的方向(即最优参数)。
• 控制步长:学习率决定调整幅度(太小会走太慢,太大容易“跳过”最优解)。
• 自动化实现:在PyTorch中,只需调用 .backward()
和 .step()
,它会自动计算梯度并更新参数。
案例
假设你想用机器学习预测房价,已知以下数据:
房屋面积(x1) | 房间数(x2) | 真实房价(y) |
---|
80㎡ | 2室 | 200万元 |
100㎡ | 3室 | 300万元 |
120㎡ | 4室 | 400万元 |
我们用线性模型 y=w1x1+w2x2+b 预测房价,目标是找到最优的 w1,w2,b。
步骤1:假设初始参数
假设模型参数为 w1=1,w2=1,b=0,预测房价为:
• 第一套房:80×1+2×1+0=82 万元(误差:200−82=118)
• 第二套房:100×1+3×1+0=103 万元(误差:300−103=197)
• 第三套房:120×1+4×1+0=124 万元(误差:400−124=276)
步骤2:计算损失函数
用均方误差(MSE)作为损失函数:
l=31[(200−82)2+(300−103)2+(400−124)2]=31(13924+38809+75696)=42,809.67
步骤3:计算梯度(公式应用)
公式1:损失对中间变量 y 的敏感度(v)
对每个预测值 yi 求偏导数得到梯度 v:
∂yi∂l=32(ypredi−yreali)
中间变量 y 是预测值,梯度 v 表示每个预测值对损失的直接影响:
v=∂y1∂l∂y2∂l∂y3∂l=2(82−200)/32(103−300)/32(124−400)/3=−78.67−131.33−184
公式2:中间变量 y 对参数 w1,w2,b 的敏感度(J)
雅可比矩阵 J 表示每个参数对预测值的影响:
J=∂w1∂y1∂w1∂y2∂w1∂y3∂w2∂y1∂w2∂y2∂w2∂y3∂b∂y1∂b∂y2∂b∂y3=x11x21x31x12x22x32111=80100120234111
• 解释:这是一个雅可比矩阵,描述了你的模型中三个参数(w1、w2、b)如何影响三个中间变量(y1、y2、y3)。
第一套房的预测值比真实值小118,导致损失增加约46单位。
矩阵中的每一行对应一个房屋样本,每一列对应参数的影响:
-
第一行(80㎡ 房子)
• ∂w1∂y1=80: 面积权重(w1)每增加1,预测房价增加80元。
• ∂w2∂y1=2: 房间数权重(w2)每增加1,预测房价增加2元。
• ∂b∂y1=1: 截距(b)每增加1,预测房价增加1元。
-
第二行(100㎡ 房子)
• ∂w1∂y2=100: 面积权重(w1)对这套房的影响更大。
• ∂w2∂y2=3: 房间数权重(w2)每增加1,房价增加3元。
-
第三行(120㎡ 房子)
• ∂w1∂y3=120: 面积权重(w1)对大房子影响最大。
• ∂w2∂y3=4: 房间数权重(w2)对大房子影响也更大。
最终梯度(链式法则)
损失对参数的梯度为
∂θ∂l=v⋅J
详细计算:
∂w1∂l∂w2∂l∂b∂l=(−78.67)×80+(−131.33)×100+(−184)×120=−6293.6−13133−22080=−41506.6=(−78.67)×2+(−131.33)×3+(−184)×4=−157.34−393.99−736=−1287.33=(−78.67)+(−131.33)+(−184)=−394
步骤4:更新参数
参数更新公式:
w′=w−α⋅∂w∂l
假设学习率 α=0.01,计算结果:
w1′w2′b′=1−0.01×(−41506.6)=1+415.066=416.066=1−0.01×(−1287.33)=1+12.8733=13.8733=0−0.01×(−394)=0+3.94=3.94
计算结果说明与分析
-
初始参数严重偏离最优值
初始参数 w1=1,w2=1,b=0 导致预测值远低于真实房价(如第一套房预测 82 万元 vs 真实 200 万元),误差极大。
后果:损失函数对参数的梯度绝对值极大(如 ∂w1∂l=−41506.6),学习率 α=0.01 乘以梯度后,参数更新量级达数百甚至数千。
-
学习率过高
当前学习率 α=0.01 与极大梯度相乘,导致参数更新幅度失控。
示例:
w1 从 1 变为 416.066,单次更新后预测值:
416.066×80+13.8733×2+3.94≈33,300 万元(远超真实值 200 万元)。
关键总结
-
梯度计算正确性:
• 雅可比矩阵维度为 样本数 × 参数数,链式法则推导无误。
• 参数更新公式明确展示负梯度如何转化为参数增大。
-
实践建议:
• 初始学习率不宜过高,避免单次更新幅度过大。
• 可通过多次迭代(如1000次)观察参数收敛过程。
-
自动化梯度计算:
在PyTorch中,只需以下两行代码即可自动完成上述所有计算:
model.backward()
optimizer.step()
实现代码
import torch
x1 = torch.tensor([80, 100, 120], dtype=torch.float32)
x2 = torch.tensor([2, 3, 4], dtype=torch.float32)
y_true = torch.tensor([200, 300, 400], dtype=torch.float32)
w1 = torch.tensor(1.0, requires_grad=True)
w2 = torch.tensor(1.0, requires_grad=True)
b = torch.tensor(0.0, requires_grad=True)
optimizer = torch.optim.SGD([w1, w2, b], lr=0.01)
optimizer.zero_grad()
y_pred = w1 * x1 + w2 * x2 + b
loss = torch.mean((y_pred - y_true) ** 2)
loss.backward()
optimizer.step()
print(f"损失值: {loss}")
print(f"输出梯度:")
print(f"w1: {w1.grad}")
print(f"w2: {w2.grad}")
print(f"b: {b.grad}")
print(f"更新参数:")
print(f"w1: {w1.item()}")
print(f"w2: {w2}")
print(f"b: {b}")