监督学习 入门
读懂任何 ML 论文之前所需的最少「学习理论」。5 个短小主题,把「学习」这件事 翻译成一个数学问题 —— 拟合一个「输入到输出」的映射 —— 并讲清楚每个监督模型都共享的五个组件: 函数族、损失函数、优化器、过拟合陷阱,以及把模型从陷阱里拽出来的正则化。
输入 → 输出的映射
每个监督模型,本质上都是一个函数。训练,就是去找它。
监督学习这件事的本质,是「从样本里逼近一个未知函数」。 给模型看一堆 (输入, 输出) 对,让它对没见过的新输入预测输出。 「监督」二字的来历,就在于每个例子都自带「答案」 —— 把数据基础里讲的「特征 / 标签」概念,翻译成「学习目标」。
把这个映射抽象地写出来:
ŷ = fθ(x)
x 是一个输入(特征向量、图像、一串 token 都行)。ŷ(读作「y hat」)是模型给出的预测。fθ 是模型本身 —— 一个由参数 θ(希腊字母「theta」,代表模型内部所有可学习的旋钮的总称)控制行为的函数。 训练,就是在参数空间里找一组 θ, 让 ŷ = fθ(x) 在整个数据集上尽可能贴近真实的 y。
决定 fθ 的形状 —— 也就是你在哪个 函数族上做搜索 —— 是「建模」要做的选择。不同函数族,能力差异巨大:
- 线性回归。
ŷ = w · x + b—— 输入的加权和。 每个输入对应一个参数,再加一个偏置。便宜、快,在表格数据上经常出乎意料地能打。 - 决策树。一组嵌套的「if x[3] > 1.5 then…」规则,每个叶子存一个预测。 多棵树拼起来就是随机森林、梯度提升树, 这类方法在结构化小数据上至今仍能在 Kaggle 上拿冠军。
- 神经网络。线性层和逐元素非线性(ReLU、GELU)交替堆起来。 小到几百万参数,大到几万亿。在足够宽 / 深时是「万能逼近器」—— 理论上能拟合数据所暗示的任何「输入到输出」关系。
具体例子:用线性回归,基于面积预测房价。一个特征(x = 面积)、 一个要学的参数(w)加一个偏置(b)。模型是 ŷ = w · x + b。 训练就是去找一对 (w, b),让那条画出来的直线尽可能贴着数据点:
本文统一例子。你刚才看到的这 5 个房价点,以及最佳拟合线 w ≈ 0.75,b ≈ 130,会贯穿整篇 primer。 §2 把这条线的残差平方起来变成 MSE;§3 让梯度下降把这条斜率「重新找一次」; §4 和 §5 保留这 5 个点,但把直线换成更灵活的多项式 —— 用来展示过拟合是怎么发生的、 正则化又怎么把它扳回来。
不管你选哪个函数族,这三个概念都会反复出现:
- 假设空间(hypothesis space)。所有你愿意考虑的
fθ的集合 —— 也就是θ的所有可能取值。假设空间越大,能拟合的模式越多, 也越容易过拟合。 - 归纳偏置(inductive bias)。函数族对世界默默作出的假设。 线性回归假设关系本身就是线性的。卷积网络假设「平移不变」 (「图挪一下还是同一只猫」)。Transformer 假设 token 之间通过注意力交互。 没有「无假设」的模型 —— 关键是挑一个假设跟问题对路的家族。
- 容量(capacity)。函数族的表达力。线性回归容量很小 (每个特征只有一个数),700 亿参数的 LLM 容量极大。 硬问题需要大容量;但容量大也正是「过拟合成为可能」的根源 —— 见第 4、5 节。
后面四节回答的是同一个明显的后续问题:给定一个函数族,具体怎么找到最好的 θ?答案分成四步:「衡量当前 θ 错得有多远」(第 2 节 —— 损失); 「把 θ 往「更不错」的方向推一下」(第 3 节 —— 优化); 「确认模型学到的是规律、不是死记硬背训练集」(第 4 节 —— 泛化); 「把这个『不死记』的偏好直接塞进损失」(第 5 节 —— 正则化)。
在 Transformer 里:函数族就是「带残差连接的自注意力块加前馈层的堆叠」。 参数 θ 是每一块里的几十亿权重矩阵,加上 token 的嵌入表。 输入 x 是一串 token ID,输出 ŷ 是下一个 token 上的概率分布 (概率统计第 2 节)。训练在参数空间里搜索一个 θ, 让这个分布在「下一个 token 真实出现的那一项上」尽可能高, 在几万亿训练 token 上取平均。本文剩下所有内容都适用 —— 只是函数族这一项有点特殊。
损失函数(Loss Function)
用一个数表示「当前模型错得有多远」。
第 1 节把图景搭好了:找一组参数 θ, 让 ŷ = fθ(x) 尽可能贴近真实的 y。 但「尽可能贴近」要变成「能算出来的定义」,优化器才有的优化。损失函数就是这个定义。给它一个预测 ŷ 和一个真实标签 y, 它返回一个数 L(ŷ, y),表示「这次预测错了多少」。越小越好,0 就是完美。
两种损失基本能覆盖你平时碰到的 95%:
- 均方误差(MSE),用于回归(连续输出):
L = mean[ (ŷ − y)² ]。算出每个样本的误差,平方 (这样正负误差不互相抵消,而且大错被惩罚得更狠), 再在整个数据集上求平均。 - 交叉熵,用于分类(离散输出):
L = −mean[ log P(y) ]。模型通过 softmax 给每一类分配一个概率, 损失就是「正确那一类的概率」取负对数,再平均。 概率统计 primer 的对数概率那一节,讲的就是这件事。
具体例子,用 §1 里那 5 个房价点,以及 demo 收敛到的最佳拟合线 ŷ = 0.75 · 面积 + 130:
面积 真值 y 预测 ŷ 误差 (ŷ − y) 平方误差
──── ──────── ──────────── ────────────── ──────────────
600 480 580 +100 10,000 (k²)
850 920 768 −152 23,104 (k²)
1450 1080 1218 +138 19,044 (k²)
2100 1900 1705 −195 38,025 (k²)
3200 2480 2530 +50 2,500 (k²)
MSE = mean( 平方误差 )
= (10000 + 23104 + 19044 + 38025 + 2500) / 5
= 18,535 (k²,千美元的平方)
≈ $136k (开平方 → RMSE,跟 y 同单位)为什么要平方,而不是直接取绝对值 |ŷ − y|?有三个到处都用得上的实用理由:
- 处处可导。平方函数的导数光滑(
2(ŷ − y)); 绝对值在 0 处有个尖角,导数没定义。优化器最爱「光滑」。 - 大错被多惩罚。误差 100 平方后是 10000;误差 10 平方后是 100。 优化器会自动把注意力放在「模型错得最离谱」的那些样本上 —— 在多数问题里,这是个特性,不是 bug。
- 有干净的概率解释。当假设
y上的噪声是高斯分布时, MSE 恰好就是最大似然损失。大多数「自然」的损失,都源自类似的概率推导。
其他特殊问题还有专门的损失 —— Huber(对离群值更鲁棒)、hinge(SVM 分类器)、 KL 散度(让一个分布去匹配另一个)、focal loss(罕见正样本)。 但几乎每一个都长成同一个形状:「每个样本一个惩罚,再在整个数据集上求平均」。
损失的两个性质,下一节会用到:
- 损失是 θ 的函数。把数据集固定,让模型参数
θ变, 损失就是一个依赖θ的数,记作L(θ)。 训练,就是去找那个使L(θ)最小的θ。 - 通常它有梯度。因为损失对
θ可导, 微积分 primer 里的梯度∇L(θ)存在,指向损失曲面上的上坡方向。 第 3 节就拿着这支箭往下走。
在 Transformer 里:损失是交叉熵, 在每个训练样本的每个位置上对「下一个 token 的分布」算出一个值,然后在批次上平均。 一次对 4096-token 序列、批大小 256 的前向,就会产出约 100 万个逐 token 交叉熵值; 优化器真正看到的损失,就是这一百万个数的平均。每一步训练都围绕这个标量在转 —— 算出来,对每个参数求梯度,走一步(第 3 节)。 把这个数反复地往下压,就是现代 LLM 一切有趣能力的源头。
优化(Optimization)
朝「能让损失下降」的方向推一下 θ,然后重复几百万次。
第 2 节把「拟合数据」翻译成「最小化 L(θ)」。现在要真正去做这件事。 损失是一个「高维参数空间 → 一个数」的函数;对任何有点意思的模型, 直接解出它的最小值都是没希望的。实用做法,就是把微积分 primer 最后一节那一套, 放大到工业规模:梯度下降。
更新规则,一行就能写下:
θ ← θ − η · ∇L(θ)
算出梯度 —— 一个向量,描述「每个参数往上挪一丁点,损失会怎么变」。然后朝反方向走一步。 学习率 η(eta)控制一步走多大。再重复。走够多步,参数就停在损失的某个极小点附近。 整套算法就是这样。你听过的每一个 ML 模型,训练时干的就是这件事。
按一次计算梯度时用多少数据,分三种风味:
- 批量(full-batch)梯度下降。每一次更新用整个数据集。 梯度最准,每步最慢,大数据时塞不进显存。现在几乎没人这么干了。
- 随机梯度下降(SGD)。每次只用一个样本。 梯度里噪声巨大 —— 但便宜,而且噪声有时反倒能让你跳出损失曲面的烂区域。 原始配方,如今基本只用来当基线。
- 小批量(mini-batch)梯度下降。用 16、64、256、4096 个样本一组。 兼顾两者:梯度估计够好,又不用啃整份数据集。这个才是现代每个模型都在用的。 2026 年大家说「SGD」时,基本都是指 mini-batch SGD。
用梯度下降在损失曲面上行走,就像一个球往坡下滚 —— 只是这片「坡」住在一个你画不出的百万维空间里。 一维的图像就是最好的直觉:
每个项目都会调的两个旋钮:
- 学习率(η)。ML 里调得最多的超参数。太小训练慢得受不了; 太大参数就越过极小点,损失开始震荡甚至爆炸。 现代食谱通常会给学习率排个表 —— 先从 0 缓步爬起(warmup), 再在训练过程里逐渐衰减(线性、余弦、阶梯)。
- batch size。batch 越大,梯度噪声越小 (样本越多 → 方差按 1/√n 缩,见概率 primer 第 4 节),但单步显存开销也越大。 多数论文都会写自己用了多大 batch。
两个建在普通 mini-batch SGD 之上、到处都能见到的改进:
- 动量(momentum)。维护一份最近梯度的指数滑动平均,沿这个方向走。 能抹平 mini-batch 带来的噪声;在「梯度方向比较一致」的方向上加速前进; 能让球滚过一些小坑 —— 纯 SGD 可能会卡在那儿。
- Adam。再加一份「梯度平方」的滑动平均,然后用它的平方根去除一下。 效果是:每个参数各自有一个按维度自适应的学习率, 在那些梯度一直很大的维度上自动缩小步长。够稳健, 几乎所有 Transformer 都默认用它。
对一个有几十亿参数的模型,∇L(θ) 怎么算出来? 把链式法则放大到工业规模 —— 反向传播(backpropagation)。 前向:算出损失。反向:沿着前向走过的运算图反着走一遍,在每一步把局部导数乘上去。 微积分 primer 第 3 节就是这套机制本身;本节的优化器, 就是「拿到反向传播交来的梯度后,按什么规则迈步」。
在 Transformer 里:训练循环就是上面这四步。 (1)从数据集采样一批 token 序列。(2)前向跑过 Transformer 得到损失。 (3)反向得到对每个参数的梯度。(4)走一步优化(几乎总是 AdamW —— Adam 加上第 5 节的权重衰减正则化)。重复几十亿次。 现代训练基础设施(数据并行、张量并行、流水并行、ZeRO、梯度 checkpoint) 都是为了把这四步循环扩到上千张 GPU 的集群上 —— 但循环本身完全不变。
过拟合与泛化
练习题做满分、考试一脸懵的学生 —— 模型也会这样。
想象一个学生把所有练习题都背得滚瓜烂熟,但题目稍微变一点就当场卡住。 他学到的是具体那些题,不是背后的规律。同样的失败在 ML 里也会发生, 有个名字:过拟合(overfitting)。反过来 —— 不只在训练数据上做得好, 在模型从没见过的样本上也做得好 —— 叫 泛化(generalization)。 监督学习的全部意义,就是泛化。光看训练损失什么都说明不了。
诊断工具,就是数据基础 primer 第 3 节里那个验证集。训练时一边盯着L_train(训练集损失)和 L_val(留出验证集损失)。 会出现三种情况:
- 欠拟合(underfitting)。两个损失都很高,而且差不多。 模型要么太小、要么训练时间不够 —— 连训练数据都拟合不上,更别说泛化。 解决:更大的模型、更多训练步、更好的特征。
- 刚刚好。两个损失都低,验证损失只比训练损失略高一点。 模型抓到了真实的规律、忽略了噪声。
- 过拟合。训练损失很小、还在往下;验证损失高得多,而且开始往上爬。 模型把训练集里那些不可推广的怪癖也背下来了。解决:提前停训练、缩小模型、 加数据、加正则化(第 5 节)。
现在把 §1 的函数族放宽一点。还是同样 5 个房价点,但不再假设它是直线 —— 拿不同次数的多项式去拟合这同一份数据。经典图像:
训练 RMSE 验证 RMSE 诊断结论
────────── ─────────── ──────────────────────────────
degree 0 高 高 「直接预测平均价」
degree 1 中等 中等 §1 那条最佳拟合直线
degree 4 $0 非常高 每个房价点都精确穿过;
点和点之间剧烈摇摆12 次多项式能把训练损失压到 0 —— 它能精确穿过每个数据点 —— 但点与点之间的预测一塌糊涂。训练损失低,是「好模型」的必要条件,不是充分条件。训练损失和验证损失之间的差距 —— 有时叫泛化间隙(generalization gap) —— 才是真正的诊断指标。
为什么会过拟合?容量足够大的模型,自由度比数据所能约束的多得多。 穿过任何有限点集的函数有无穷多个;光让你「拟合训练数据」并不能挑出唯一一个。 这些函数里,有些光滑、能泛化;有些在数据点之间乱跳、不能。 如果没有什么力量推着优化器往「光滑」那侧走,只要能把训练损失压到 0, 它很乐意挑一个乱跳的函数收工。
对付过拟合的三个杠杆,平时这样从上往下试:
- 更多数据。最干净的解药。数据翻倍,对函数的约束就更紧, 模型就更难单纯靠死记硬背。这也是为什么「scaling laws」的论文反复发现: 预训练数据越多,下游精度可以预测地变好。
- 降容量。小一点的模型,自由度也小,死记硬背的余地小。 缩宽度、砍一层,或者把 12 次多项式换成 3 次。
- 正则化。保持大模型,但把优化器往「更简单的解」那一侧偏一下。 第 5 节正是这件事。
一个第一次都会被坑的细节:「大模型就一定过拟合」是错的。现代深度学习经常在「参数远多于训练样本」的设定下训练,泛化反而不错。 经典的偏差-方差故事(过了某个阈值后,参数越多泛化越差)在大型神经网络上失效。 这种现象有个名字叫 double descent(双重下降):验证损失会先升上去、 然后随着模型变得更大,又降回来。为什么如此目前还是活跃研究问题, 但实践上:不要默认「巨大模型 = 过拟合」。
在 Transformer 里:LLM 在几千亿 token 上只过一个 epoch。 训练集大到「单纯靠背」都难以塞下,泛化自然就成了默认结果,而不是例外。 过拟合更多发生在微调阶段:模型要适配一个小得多的、任务相关的数据集。 本节讲的那套诊断(训练损失继续往下、验证损失却往上)就是大家用来识别它的方法。 现代微调食谱用小学习率、early stopping、LoRA(一种参数高效、实际容量更小的方法)、 以及下一节的那几种正则化,把泛化间隙压住。
正则化(Regularization)
把「我偏好简单的解」这件事,直接写进损失里。
第 4 节给问题起了名字:容量足够大时,很多不同的参数取值都能让训练损失为 0, 但只有一部分能泛化。没有「平局裁决规则」,优化器随便挑一个就走人, 挑到那些「乱跳的」就在新数据上灾难性翻车。正则化就是那个裁决规则。 它把「偏好简单解」这件事直接塞进损失里 —— 让优化器在「拟合数据」和「保持简单」之间权衡,平手时往简单那侧偏。
所有正则化器都长成同一个模板:
Lreg(θ) = Ldata(θ) + λ · Ω(θ)
Ldata 就是第 2 节的原始损失。Ω(θ)(读作「omega」) 是衡量「这组参数有多复杂」的惩罚项。λ(读作「lambda」)是正则化强度 —— 一个由用户来定的旋钮。加上这个惩罚之后,优化器搜索的目标就变了: 新的极小点是「既拟合数据、又简单」的参数组合,λ 决定在二者之间偏哪边。
四种正则化器,基本能覆盖所有实际情况:
- L2(权重衰减)。
Ω(θ) = Σ θᵢ²—— 参数平方和。 惩罚大权重。倾向于把「拟合数据」的重担均匀地分散到很多小权重上, 而不是让少数几个权重长成怪物。机制上,每次梯度更新会多一项−η · 2λ · θ, 相当于每步把每个权重朝 0 「衰减」一点 —— 名字里的「衰减」就来自这里。 - L1。
Ω(θ) = Σ |θᵢ|—— 参数绝对值的和。 有个很显著的副作用:它会把很多权重压到精确的 0,产生一个稀疏模型。 想让「特征选择」自动发生在训练里时很有用。 - Dropout。只在训练时,每次前向都把一部分激活随机置 0。 模型没法依赖任何单个神经元,实际上学到的是一个「这些神经元不存在时会怎样」的子模型集成。 推理时所有神经元都用上。便宜、出奇地有效,在 2010 年代到处都是 —— 在现代 Transformer 里有一部分被「大 batch + 权重衰减」取代,但还是工具箱里的常客。
- 提前停止(early stopping)。训练时盯着验证损失, 只要它开始往上爬,就停。世界上最便宜的「正则化器」 —— 没有惩罚项、 除「我能等多久」之外没有额外超参 —— 它之所以管用,是因为提前停下来, 能让参数留在一个比较光滑的状态,而再训下去就走丢了。
具体图像。第 4 节那条 12 次过拟合多项式,能精确穿过每个点,但点和点之间剧烈摇摆。 给多项式系数加一个 L2 惩罚,优化器就偏好「小系数」,而小系数会直接压住摇摆。 随着 λ 增大,拟合曲线从「穿过每个点」逐渐变成 「一条几乎忽略噪声的光滑曲线」:
注意这张权衡曲线的形状。λ = 0 时就是第 4 节那条乱跳曲线。λ 非常大时,惩罚主导一切,拟合几乎变成常数 —— 模型简单到几乎没怎么用数据。在两者之间的某个值,验证损失会取到最小值。怎么找?在验证集上扫一遍。取几个 λ 值, 选验证损失最小的那个。(数据 primer 第 3 节里所说的「验证集」,就是干这个用的。)
理解正则化的一个有用的视角,来自概率 primer: 每个正则化器都对应一个「合理的参数应该长什么样」的先验信念。 L2 对应「权重大概比较小、服从高斯分布」。 L1 对应「权重大概是 0,除非有证据要求它非 0」。 正则化损失就是「负的后验对数」 —— 「拟合 + 先验」,贝叶斯意义下的那个组合。 同一件事,两种语言。
在 Transformer 里:优化器几乎全是 AdamW —— Adam 加上 L2 家族的权重衰减。名字里的「W」字面意思就是「weight decay」。 其他常用正则化:注意力层和 MLP 层里的 dropout(微调时尤其多用); 交叉熵里的 label smoothing(可以看成对输出分布做一种软的 L2); 梯度裁剪(防止一次极大梯度毁掉一次漫长的训练, 结构上和「对更新步本身做正则化」的思想很像)。当然, 现代 LLM 训练里最强的正则化器,其实就是「在更多数据上训练」 —— 见第 4 节里的「更多数据」杠杆。每个选择都是同一条权衡曲线上的一个点:我有多愿意让模型贴近训练数据,取决于我有多相信训练数据长得像真实世界?