Transformer 前置知识 03:导数与梯度下降
上一课讲了矩阵乘法:模型是怎么算的。这一课回答另一个问题:模型是怎么学会的?
答案藏在三个词里:导数、梯度、梯度下降。我们不从公式讲起,而是从一件很日常的小事说起:调洗澡水。
导数:拧一格,变多少
假设只有一个热水龙头。把它拧大一格,水温升高了 3 度。
这个 3,就是导数:
导数 = 参数变动一点点,结果会变多少。
- 导数大:这个旋钮很灵敏,稍微一拧,结果变化很大
- 导数小:拧了也没什么变化
- 导数是负数:越拧,结果反而越小
数学上写作:
读作”水温
偏导数:一次只动一个
现实中,旋钮通常不止一个。比如有热水
偏导数,就是一次只动一个,其他的按住不动:
- 冷水按住不动,只把热水拧大一格,水温升了 3 度
- 热水按住不动,只把冷水拧大一格,水温降了 2 度
所以:
符号
梯度:所有偏导数排成一排
把所有偏导数排成一排,就是梯度,记作
梯度可以看成一个箭头,它就像一张说明书:
照着箭头拧,水温升得最快;反着箭头拧,水温降得最快。
考考你:水太烫了,想尽快降温,两个龙头该怎么拧?
答案是反过来:
再想一个:如果梯度是
- 热水关小一格,水温降 10 度
- 冷水开大一格,水温只降 1 度
所以,偏导数的绝对值越大,说明这个参数影响越大,调它最有效。
为什么要找”谷底”
训练模型,本质上是在找误差最小的地方。为什么是”最小”?
假设你想要的水温是 40 度:
| 实际水温 | 差距 |
|---|---|
| 50 度 | 10 度 |
| 45 度 | 5 度 |
| 40 度 | 0 |
这个差距就叫误差,也叫损失(Loss),记作
模型也一样:误差,就是模型的答案和正确答案差了多少。我们习惯把目标定成”误差越小越好”,所以训练就是在找谷底。
梯度下降:反着箭头,一小步一小步走
把两个参数画成坐标,误差画成一圈圈等高线,就得到一张误差地形图,中心就是谷底。
梯度就是图上的一个箭头:它指向误差上升最快的方向,箭头的长度代表坡有多陡。
想让误差变小,就:
- 算出当前位置的梯度
- 沿着梯度的反方向走一小步
- 回到第 1 步,重复
每一步走多远,由学习率
:模型的参数(所有旋钮) :学习率,一个很小的数,比如 0.1 :误差对参数的梯度 - 减号:反着梯度走
注意图里的步子:越接近谷底,坡越缓,梯度越小,步子也就越小,最后稳稳停在谷底。
梯度下降的”下降”,指的是沿着梯度的反方向往下走,而不是”梯度变小了”。
用代码跑一遍
来看一个最简单的例子:误差
从
1 | w = 0.0 |
可以看到:
真实的大模型也是这么学的,只不过参数从 1 个变成了几十亿个。
学习率:步子太大或太小都不行
- 太小:走得很稳,但要走非常多步,训练很慢
- 太大:一步迈过了谷底,跳到对面山坡上,甚至越跳越远
在上面的例子里,如果把学习率改成 1.1,
小结
- 导数:调一个参数,结果变多少
- 偏导数:有多个参数时,一次只调一个,其他不动
- 梯度:所有偏导数排成的箭头,指向误差上升最快的方向
- 梯度下降:反着箭头,一小步一小步地走,直到谷底:
- 学习率:决定每一步迈多大
还剩一个问题:模型有几十层、几十亿个参数,每个参数的梯度怎么算?下一课讲链式法则与反向传播。