Skip to content
简体中文

切换主题

数学与机器学习基础

机器是怎么“学习”的:一文讲懂损失函数与梯度下降

入门 18 分钟 适合: 初学者 / 开发者 / 研究者

本课要点

  • ▸机器学习就是调整模型的参数,让“损失”(衡量错得有多厉害的一个数)在示例数据上变小。
  • ▸梯度告诉你每个参数该往哪个方向动才能让损失下降;梯度下降就是沿着这个方向走很多小步。
  • ▸大模型训练是同一个循环的超大规模版本:损失是“下一个 token”的交叉熵,参数有几十亿个。
  • ▸目标不是在训练数据上考满分,而是在没见过的新数据上表现好(泛化)。

学习 = 让一个数字变小

传统软件是写规则:如果这样,就那样。机器学习反过来:你提供示例和一个带可调数字(参数)的模型,由算法去调这些数字,直到模型的输出和示例对得上。

“对得上”需要一个精确的标准,这就是损失函数:一个衡量模型在示例上错得有多厉害的公式。训练,就是寻找让损失尽量小的参数。你听说过的所有 AI 系统,图像识别、推荐系统、ChatGPT,都是这样训练出来的。

一个小例子

假设要根据面积预测房价,模型是一条直线:

房价 = w × 面积 + b

w 和 b 是两个参数。手上有三个样本:50 平方米 → 100 万,80 平方米 → 160 万,100 平方米 → 200 万。预测数值时常用的损失是均方误差:(预测值 − 真实值)² 的平均。

先随便猜,比如 w = 1, b = 0。预测出 50、80、100,都太低了,损失很大。接着问:如果把 w 调大一点,损失是变大还是变小? 这个变化率就是损失对 w 的导数;所有参数的导数合在一起叫梯度。这里梯度告诉我们“该把 w 调大”。朝这个方向走一小步,重新计算,再重复。走够多步之后,会到达 w ≈ 2, b ≈ 0,正好拟合数据。

flowchart LR
  A["参数(一开始是随机的)"] --> B["对一批样本做预测"]
  B --> C["损失:错了多少?"]
  C --> D["梯度:往哪边走损失会降?"]
  D --> E["更新:往下坡走一小步"]
  E --> A

同样的循环,用几行 Python(NumPy)写出来:

import numpy as np
x = np.array([50, 80, 100.]); y = np.array([100, 160, 200.])
w, b, lr = 1.0, 0.0, 1e-4
for step in range(2000):
    pred = w * x + b
    err = pred - y
    loss = (err ** 2).mean()
    dw = 2 * (err * x).mean()   # 损失对 w 的导数
    db = 2 * err.mean()         # 损失对 b 的导数
    w, b = w - lr * dw, b - lr * db
print(round(w, 3), round(b, 3), round(loss, 4))

每一步的大小 lr 叫学习率。太大,更新会冲过头、数值爆炸;太小,学得像蜗牛。

直观图景:在大雾里下山

把损失想象成一片地形:每个位置是一组参数取值,高度是损失。你站在浓雾里,只能感觉到脚下的坡度。梯度下降就是:感受坡度,往下坡迈一小步,再重复。 两个参数时,地形是一个三维曲面;大模型的地形有几十亿个维度,但规则完全一样。

要在大规模上用起来,还有三个改进:

  • 随机(小批量)梯度下降:用随机抽取的一小批样本估计坡度,而不是用全部数据,便宜得多(Ruder,2016)。
  • 更好的优化器:例如 Adam(Kingma & Ba,2014),为每个参数自适应步长,并加入动量。Adam 及其变体 AdamW 是训练大模型的默认选择。
  • 反向传播:用链式法则高效算出数百万个参数的梯度,见 神经网络与反向传播。

从一条直线到大模型

换成语言模型,套路一样,只改三处:

房价预测 大语言模型
模型 w × 面积 + b 几十亿参数的 Transformer
样本 (面积,房价) (前面的文本,真正的下一个 token)
损失 均方误差 交叉熵:−log(模型给正确的下一个 token 的概率)

如果模型给真正的下一个 token 分配了很高的概率,交叉熵就低;如果模型很“意外”,交叉熵就高。大模型的预训练,字面意义上就是在数万亿个 token 上跑上面这个循环,见 大模型如何学习。

真正的目标:泛化

模型完全可以靠死记硬背把训练损失降到 0,但面对新输入却毫无用处,这叫过拟合。所以实践中会把数据分成训练集、验证集和测试集,用模型没训练过的数据来评判它。在海量、多样的数据上训练的大模型泛化得出奇地好,但用新鲜、未被污染的数据做评测依然必不可少(怎样评测大模型)。

动手试试

运行上面的 Python 代码(可以用 uv 快速准备环境:uv run --with numpy python script.py)。再把 lr 改成 1e-3,看损失爆炸,你就亲身体验了最常见的训练失败。

常见问题

损失函数用一句话怎么解释?

损失函数是一个公式,把模型犯的错变成一个数字:0 表示完全预测正确,越大表示越差。训练就是寻找让这个数尽量小的参数。

学习率是什么?

学习率是梯度下降每一步的步长。太大,训练会冲过头甚至发散;太小,训练慢得没法用。现代训练会随时间调整学习率(先预热,再衰减)。

为什么叫“随机”梯度下降?

因为每一步只用随机抽取的一小批样本来估计梯度,而不是用全部数据。这样噪声更大,但便宜得多,而且噪声往往还有好处。

本课相关软件

出处与延伸阅读

  1. Goodfellow、Bengio、Courville,《深度学习》(MIT Press,2016)第 4–5 章
  2. Google,机器学习速成课程
  3. Kingma & Ba(2014),Adam: A Method for Stochastic Optimization
  4. Ruder(2016),An overview of gradient descent optimization algorithms
  5. 斯坦福 CS229 机器学习讲义

所属学习路线

数据更新于:学 AI 课程 · 课程相关新闻(北京时间)