2.4 梯度下降进阶:从山谷到沟壑
给山加一个维度
0.4 节里你已经蒙着眼下过一次山——那座山只有一个方向可走(一个参数)。可是上一节的训练三件套里,随便一个小网络就有几十个参数,GPT 更是有几千亿个:每个参数都是一个可以移动的方向。
几千亿维的山没人画得出来,但从 1 维升到 2 维,已经足够暴露出一批一维世界里根本看不到的新麻烦。这次你不再站在山坡上,而是从上帝视角俯瞰整片地形:颜色越浅的地方损失 越低,两个白圈就是谷底。
请按顺序做四个实验:
实验 ①:经典之字形。 保持默认起点和学习率 η = 0.1,点「▶ 自动下山」。仔细看橙色足迹:纵向(陡的方向)小球一步就冲过头、下一步又弹回来,来回横跳;横向(缓的方向)却每步只挪一点点。整条路径呈之字形——先在陡壁间弹够了,才慢悠悠沿着谷底爬向白圈。
实验 ②:一步跨进另一条谷。 点「↺ 重置」,把 η 调到 0.5 再自动下山。第一步就大得离谱——小球直接从右边山坡飞越中间山脊,掉进了左边的谷底。步子太大时,你甚至不知道自己会落在哪条谷里。
实验 ③:干脆飞出地图。 再重置,把 η 拉到最大(0.8)。这次连「换条谷」的运气都没有:每一步都跨得比整条沟还宽,越荡越高,💥 直接发散——0.4 节的 loss 爆炸,在高维地形里只会来得更容易。
实验 ④:手抖反而是好事。 重置后勾选「随机梯度噪声(SGD)」,用 η = 0.1 自动下山。足迹变得歪歪扭扭,但大方向不变,照样能进谷底——有时还能靠抖动翻过小坡换到更好的谷。
为什么会走出之字形?
这片地形是一条沟壑:纵向坡度陡,横向坡度缓。而学习率只有一个,两个方向只能共用——
- 想让陡方向不震荡,η 就得 调小;
- η 一小,缓方向就挪不动。
学习率只能迁就最陡的方向,于是缓方向被拖累,整体进度慢得令人心焦。数学上「最陡方向和最缓方向的陡峭比」有个名字叫条件数,条件数越大,之字形越严重。真实神经网络的损失面里,不同参数方向的陡峭程度可以相差成千上万倍——这正是本节深入层里 Adam 这类「智能步伐」优化器存在的理由。
为什么每步只用一小批数据?
到目前为止我们默认:算一次梯度,要把全部训练数据过一遍。对 12 个点无所谓;可大模型的训练数据是十几万亿个 token——全过一遍才走一步,走几百万步等于天荒地老。
实际做法简单粗暴:每步只随机抽一小批(一个 batch,比如几百万 token)来估算梯度。这就是随机梯度下降(SGD):
- 抽样估出来的坡度大致指向正确方向,但每次都带点误差——这就是实验 ④ 里的手抖;
- 代价是路径歪歪扭扭,收益是每一步便宜了无数倍,还白送一个好处:噪声能帮小球晃出鞍点和小坑(0.4 节埋的伏笔,在这里兑现)。
你看到的仍然只是千亿维地形的一张 2 维切片。真实损失面上,「沟壑」远比图里夸张——不同方向的陡峭程度能差出几个数量级,而且地形还会随着训练数据的批次不断轻微变化(每批数据画出的「山」都略有不同)。另外,图里的噪声是我们手工加的均匀抖动,真实 SGD 的噪声大小取决于 batch 大小:批越小,抖得越凶。
小结
- 沟壑地形(有的方向陡、有的方向缓)让梯度下降走出之字形:学习率被最陡方向卡脖子。
- 大模型不可能每步用全部数据算梯度:随机抽一小批来估算,就是 SGD——便宜、带噪声,而噪声常常是帮手。
- 学习率过大在高维里更危险:轻则跨谷,重则发散。
- 动量与 Adam 用「惯性 + 每参数自适应步长」驯服沟壑,AdamW 是当今大模型训练的标配。
延伸阅读
- Distill: Why Momentum Really Works——把动量讲成艺术品的交互式论文。
- 复习 0.4 导数与梯度:一维版的直觉都在那里。
- 下一节 2.5 反向传播:梯度下降天天要用的梯度,到底是谁算出来的?