第八部分 · 学习就是优化
往哪儿下坡:多元微积分与梯度
"学习"被我们逼成了一句话:调参数,把损失降到最低。可损失不是一条曲线,而是一片几百万维的地形。站在地形上的某一点,往哪个方向迈才下坡最快?回答这个问题的,是一支箭——梯度。
留下的问题:那件事,就是把损失降到最低。机器不会"顿悟",它只会一点点改参数,让损失一次比一次小——这就是优化。可问题来了:参数有成千上万个,损失是这成千上万个参数的一个函数,站在当前这组参数上,该往哪个方向、改多少,损失才掉得最快?
本课新增:把第 7 课的导数从"一个变量"推广到"很多变量"——偏导数量"只动一个参数时损失的变化率",把所有偏导排成一支向量,就是梯度 ∇L。它有一个惊人的性质:梯度指向损失上升最快的方向,于是 −∇L 就是下坡最快的方向。这是整个第八部分的指南针。
一元导数会了,可损失有很多个变量
第 7 课的导数解决的是"一个输入、一个输出":给 f(x),f′(x) 告诉你 x 动一点点、f 跟着动多少。可机器学习里的损失不长这样。哪怕是最简单的直线拟合 y ≈ w·x + b,损失 L 也同时依赖两个旋钮:斜率 w 和截距 b。一个真正的神经网络,旋钮(参数)动辄上百万个。损失是它们共同的函数:
训练的目标,就是在这片地形上找一个尽量低的山谷。难点在于:地形是几百万维的,你看不见全貌,只能站在当前这一点,靠脚底的坡度判断"往哪走会更低"。一元的 f′(x) 不够用了——它只懂"左右",而这里有几百万个方向。
偏导数:按住别人,只问一个
突破口其实很朴素:一次只动一个变量,其余全部按住不动。这样多变量函数就临时退化成一元函数,第 7 课的导数立刻能用。对 w₁ 这样做,得到的就是 L 对 w₁ 的偏导数:
它的含义干脆利落:只把第 1 个旋钮拧动一点点,损失变化的速率。如果 ∂L/∂w₁ > 0,增大 w₁ 会让损失上升(所以该减小它);如果 ∂L/∂w₁ < 0,增大 w₁ 反而让损失下降。每个参数都能这样问一次,得到 ∂L/∂w₁, ∂L/∂w₂, …, ∂L/∂w_d 一共 d 个数。
举个能心算的例子:L(w, b) = w² + 3b²。按住 b、只对 w 求导,得 ∂L/∂w = 2w(3b² 是常数,导数为 0);按住 w、只对 b 求导,得 ∂L/∂b = 6b。在点 (w, b) = (1, 1) 处,两个偏导分别是 2 和 6——沿 b 方向比沿 w 方向陡三倍。
梯度:把所有偏导排成一支箭
偏导分头告诉了我们每根轴上的坡度。把它们排成一个向量,就得到这一点的梯度,记作 ∇L(那个倒三角 ∇ 读"nabla"或"梯度算子"):
回到上面的例子,L(w,b)=w²+3b² 在 (1,1) 处的梯度是 ∇L = (2, 6)。它不只是两个数堆在一起,而是一支有方向的箭:它指向哪儿,长度多少,都有确切的几何意义——这正是下一节的主角。
核心命题:梯度指向最陡的上坡
这是整个第八部分最重要的一句话,请记牢:
为什么是它?这里给一个不用公式也能信的直觉。想象你站在地形上,环视四周所有方向,问每个方向"沿你走,海拔升多快"。可以证明:任意方向的坡度,等于梯度与那个方向的夹角的余弦关系——朝向越接近梯度,升得越快;正好顺着梯度,升得最快;正好逆着梯度(−∇L),降得最快;而和梯度垂直的方向,海拔一时不变(这正是等高线的方向)。所以梯度就像地形在每一点贴出的一块路牌:"最陡的上坡在这边,长度就是陡度。"
对训练来说,这块路牌价值千金。我们要的是下坡,那就逆着路牌走——朝 −∇L 迈一步,损失下降得最快。下一课(25)解决"梯度怎么算",再下一课(26)解决"逆着它怎么走、走多大步"。本课先把这支箭的几何看透。下面的小实验把它画在等高线上:拖动地形上的点,看梯度箭头永远垂直于等高线、指向上坡,并实时读出两个偏导和梯度长度。
方向导数:任意方向上的坡度
偏导只问"沿坐标轴"的坡度,可路牌告诉我们:每个方向都有自己的坡度。沿任意单位方向 u(读作"u,一个长度为 1 的方向向量")的坡度,叫方向导数,它有一个漂亮到不可思议的公式:
由内积的几何(第 20 课):点积在 u 与 ∇L 同向时最大、反向时最小。这就证明了上一节的命题——梯度方向上升最快,−∇L 方向下降最快,垂直方向(点积为 0)海拔不变。环环相扣:表示部分搭好的内积,在这里直接兑现成了"哪个方向最陡"。
雅可比与海森:各就各位
梯度是"标量函数(一个损失)对很多输入"的一阶导数。再往上还有两层,名字唬人,本质都是导数的推广,这里各安一句话,等到要用时(25 课、27 课)自然会回来:
- 雅可比矩阵:当函数不止输出一个数、而是输出一整个向量时(比如神经网络的一层把一组数变成另一组数),每个输出对每个输入都有一个偏导,排成一个矩阵,就是雅可比。它是"向量值函数"的梯度。反向传播(下一课)本质上就是把一串雅可比连乘起来。
- 海森矩阵:梯度的"再求一次导"——所有二阶偏导 ∂²L/∂wᵢ∂wⱼ 排成的矩阵。一阶梯度告诉你坡往哪倾,二阶海森告诉你地形是凹是凸(像碗还是像马鞍)。第 28 课判断"凸不凸、是不是全局最优"时,它会登场。
记住一条阶梯就够了:偏导 → 梯度(一阶,方向)→ 海森(二阶,弯曲)。眼下我们只需要一阶的那支箭。
几百万维的导数,凭什么还算得动
到这里你可能心里一紧:神经网络几百万个参数,难道要对每个参数都跑一遍"加 h、算损失、相减、除以 h"?那样光算一次梯度就要把整个网络正向跑几百万遍,根本训练不动。这正是梯度留下的新危机:定义会写,但照定义一个一个数值地算,慢到不可接受。
好消息是,这件事有救,而且救法优雅得惊人:它把第 7 课早就埋下的链式法则,顺着网络的"计算图"反着跑一遍,一次就拿到所有参数的偏导。这个算法,正是深度学习之所以能训练的引擎——下一课见。
常见误解
- "梯度是一个数。" 不是。导数(一元)是一个数,但梯度是一支向量——参数有几维,它就有几维。它既有方向(往哪上坡),也有长度(多陡)。
- "梯度指向最低点。" 不。梯度只懂当前这一点的局部坡度,指向最陡上升方向;要下坡得走 −∇L,而且它指的也只是"此刻最陡的下坡",不保证笔直通向谷底。沿着它一步步走、走到哪、会不会卡住,是第 27、28 课的事。
- "偏导和导数是两种东西。" 偏导就是导数,只不过求导时把其余变量按住当常数。把别的变量冻住,多元函数就退化成一元函数,第 7 课的整套定义原封不动地搬过来。
- "梯度为零就是到了最低点。" 梯度为零只说明此处各方向都平了——可能是谷底(极小),也可能是山顶(极大)或马鞍点。要分清得看二阶的海森。这道坎我们留到第 28 课凸优化里彻底解决。