上一篇讲损失函数时留了个钩子:模型预测完,损失函数给预测「扣了分」,可模型怎么根据这个分数去调整自己?答案就是梯度下降(gradient descent)——它告诉模型「每个参数该往哪个方向调、调多少,扣分才能变小」。一句话定义:沿着损失下降最快的方向,一步一步地更新参数,直到走到损失最小的位置。
最贴切的类比是「蒙着眼下山」。想象你站在半山腰,被蒙住了眼,看不见全貌,目标是走到谷底。你只能怎么做?用脚探一探——感受脚下哪个方向最陡,朝着最陡的下方迈出一步;到了新位置再探一次,再迈一步……如此反复,直到脚下变平(再也感觉不到下坡),就到了谷底。梯度下降做的就是这件事:山是损失函数的曲面,你是算法,脚感的「陡度」就是梯度,迈出的步幅是学习率,谷底就是损失最小的那组参数。
它在 AI 体系里的位置
梯度下降属于机器学习的核心优化算法——「优化」在 AI 里就是「把损失往下压」的统称。上一篇说过训练的三步循环是「损失函数打分 → 梯度下降指方向 → 优化器迈步子」,梯度下降正是「指方向 + 迈步子」这一步的主角。
它和几个概念紧密绑定:
- 损失函数:梯度下降要最小化的对象,没有损失就没有「山」可下。
- 反向传播(backpropagation):算梯度的具体方法——深度学习里梯度不是手算的,而是用反向传播自动算出来,再交给梯度下降去用。
- 学习率(learning rate):公式里的步长,下文单独讲——它是梯度下降能不能正常工作最关键的一颗螺丝。
「梯度」是什么?把损失函数想成一个曲面,站在某一点,梯度就是一个箭头,指向上升最快的方向,长度等于最陡的陡度。我们要让损失下降,所以取它的反方向走——这就是「梯度下降」里「下降」二字的由来。
核心公式:一行更新规则
梯度下降的全部动作,浓缩成一个更新公式:
符号解读:
(theta)—— 模型的参数(那些待拧的「旋钮」,如神经网络的权重和偏置)。它可以是一个数,也可以是一组数(更新时整组同时换) (eta)—— 学习率,一个预先设好的小数(比如 0.01),就是「每步迈多远」 —— 损失函数 在参数 处的梯度,也就是「每个参数方向上,损失上升最快的方向和陡度」 - 中间的减号 —— 最关键的一笔!梯度指向「上升最快」,可我们要的是「下降」,所以取反方向(用减号)
(乘号)—— 学习率乘上梯度,两者的乘积就是这一步实际迈出的步长大小
通俗理解:蒙着眼站在山上,梯度告诉你「脚下哪个方向最陡地往上」;你偏要反着来、往最陡地往下走,于是迈出
图 1:公式里的减号,就是把「指向上坡」的梯度翻转成「指向谷底」的迈步方向。
一个计算示例:手算三步看它怎么走
拿一个能心算的例子:假设损失函数就是
梯度就是对
| 第几步 | 当前 | 梯度 | 更新 | 新 |
|---|---|---|---|---|
| 1 | 3.000 | 6.000 | 2.400 | |
| 2 | 2.400 | 4.800 | 1.920 | |
| 3 | 1.920 | 3.840 | 1.536 |
自检:
图 2:三步迭代让 w 从 3 一路降到 1.54,步长随梯度变缓而自动缩短,稳步逼近谷底。
学习率:最关键的一颗螺丝
公式里那个
- 太大(比如
): ,一步直接跨到对面山坡,损失不降反升,来回震荡甚至越走越远(术语叫发散)。 - 太小(比如
):每步只挪 ,要走成千上万步才到谷底,训练慢到没法用。 - 合适:稳定下坡、又不太久——这正是训练模型时反复要调的「手感」,也是「调参」这个词最常指的东西。
一句话记住学习率:步子迈太大会摔跟头,步子迈太小走不到。
一个家族:从最朴素到实战主流
实际训练里很少用「最朴素」的梯度下降,而是用它的一堆改进版,统称优化器(optimizer)。它们的内核都是上面那个更新公式,区别在于「怎么迈步」:
- 批量梯度下降(BGD):每次用全部样本算梯度,方向最准但每步最慢。
- 随机梯度下降(SGD):每次只用 1 个样本,每步最快但方向抖动大。
- 小批量梯度下降(Mini-batch GD):每次用一小批(如 32 或 64 个),兼顾速度与稳定,是实战主流。
- 自适应优化器(Momentum / Adam 等):在梯度基础上再记一份「惯性」或「历史趋势」,走得更聪明,目前 Adam 用得最多。
不用被名字吓到——它们都是梯度下降的「徒子徒孙」,把祖师爷那个公式理解透,后面这些只是工程上的精修。
图 3:三种变体的差别只在「每步用多少样本算梯度」——全用、只用一个、还是用一小批。
PyTorch 里怎么写
在 PyTorch 里,梯度下降被封装进「优化器」对象,三行就能跑完一轮更新:
opt = torch.optim.SGD(model.parameters(), lr=0.01) # 优化器:封装梯度下降,lr 就是公式里的 η
loss.backward() # 反向传播:自动算出梯度 ∇L(不用手算)
opt.step() # 按公式 θ := θ - η·∇L 把所有参数更新一遍backward() 算梯度、step() 走一步——这两行就是梯度下降公式在代码里的对应。
完整代码
接着上一篇的玩法,继续教模型学会「
import torch
import torch.nn as nn
# ===== 任务:教模型学会「y = 2x」 =====
torch.manual_seed(42)
x_train = torch.linspace(1, 10, 20).reshape(-1, 1) # 输入:1 到 10 的 20 个数
y_train = 2 * x_train # 真实答案:每个数的两倍
# ===== 搭一个最简单的线性模型 y = w·x + b =====
model = nn.Linear(1, 1) # nn.Linear(输入1维, 输出1维):内置线性变换
opt = torch.optim.SGD(model.parameters(), lr=0.01) # 优化器:随机梯度下降,lr 是学习率 η
loss_fn = nn.MSELoss() # 损失函数:均方误差(上一篇讲的那把回归标尺)
# ===== 训练:梯度下降循环——预测 → 扣分 → 算梯度 → 迈一步 =====
for epoch in range(300):
pred = model(x_train) # 前向:模型预测
loss = loss_fn(pred, y_train)# 用 MSE 算损失(扣分)
opt.zero_grad() # 清空上一轮残留的梯度
loss.backward() # 反向传播:自动算出梯度 ∇L
opt.step() # 梯度下降迈一步:θ := θ - η·∇L
# ===== 看看模型学会了没 =====
print(f"学到的权重 w:{model.weight.item():.3f}(标准答案 2)")
print(f"学到的偏置 b:{model.bias.item():.3f}(标准答案 0)")
print(f"训练结束时的 loss:{loss.item():.4f}")运行输出约为 w:2.000,b:0.000,loss:0.0000——模型从一组随机的 model.weight、model.bias 想成那两个旋钮,整个训练过程就是梯度下降在反复「探坡 → 迈步」,直到旋钮拧到最优。
小结
一句话浓缩:梯度下降是让模型「沿着损失下降最快的方向、一步一步调参数」的优化算法,公式就是
参考资料
- 动手学深度学习(李沐等)- 7.2 梯度下降和随机梯度下降:系统讲解学习率作用与 BGD/SGD/小批量变体 https://zh-v1.d2l.ai/chapter_optimization/gd-sgd.html
- 3Blue1Brown - Gradient descent, how neural networks learn:经典动画讲解,直观展示梯度下降如何在损失曲面上「下坡」 https://www.3blue1brown.com/lessons/gradient-descent/
- IBM - 什么是梯度下降?:官方科普,介绍梯度下降作为训练神经网络的核心优化算法 https://www.ibm.com/cn-zh/think/topics/gradient-descent