神经网络作为「端到端可学习的函数」已经是日常工具,但很多人对它「学习」过程的实际机制仍停留在「有反向传播」这一句话。这种黑箱视角在训练顺利时没问题;一旦遇到损失不下降、梯度爆炸、推断性能崩塌等异常,就完全没有抓手去定位问题。理解深度学习的底层原理不是为了重新发明 PyTorch,而是为了在模型不收敛或泛化失败时,知道往哪里看 。
这篇文章介绍深度学习最底层的数学骨架——从 1957 年 Rosenblatt 的感知机 出发,一路推到现代深度网络可以稳定训练上百层的工程化基础。核心是三件事:用非线性激活把多个线性变换叠成「可表达任意函数」的结构、用链式法则把误差在计算图上反向传播、用方差控制与正则化让深层网络真正训练得动 。
本文按 § 1-5 顺序展开:单层感知机的数学表达与异或问题给出非线性的必要性(§ 1);多层感知机叠加 + 万能近似定理告诉我们非线性的足够性(§ 2);训练神经网络的基本流程——损失函数 + 梯度下降——把「能表达」落到「能学到」(§ 3);梯度消失 / 爆炸与初始化、归一化技术让训练在数十甚至上百层时仍然稳定(§ 4);最后从偏差-方差权衡到 L1 / L2 / Dropout 看「学到」与「泛化」之间的距离(§ 5)。
1. 感知机:线性模型的极限
1.1 感知机的数学表达
感知机由 Rosenblatt 在 1957 年提出,是历史上第一个可以从数据中学习参数的二分类模型。它的核心操作是把若干维输入加权求和,再过一个阶跃函数:
y = s i g n ( w ⋅ x + b ) , s i g n ( z ) = { + 1 , z ≥ 0 − 1 , z < 0 y \;=\; \mathrm{sign}(w \cdot x + b),
\qquad
\mathrm{sign}(z) =
\begin{cases}
+1, & z \ge 0 \\
-1, & z < 0
\end{cases} y = sign ( w ⋅ x + b ) , sign ( z ) = { + 1 , − 1 , z ≥ 0 z < 0
这里 x ∈ R n x \in \mathbb{R}^n x ∈ R n 是输入向量,w ∈ R n w \in \mathbb{R}^n w ∈ R n 是权重向量、b ∈ R b \in \mathbb{R} b ∈ R 是偏置,输出 y ∈ { − 1 , + 1 } y \in \{-1, +1\} y ∈ { − 1 , + 1 } 是分类标签。从几何上看,决策边界 w ⋅ x + b = 0 w \cdot x + b = 0 w ⋅ x + b = 0 是 R n \mathbb{R}^n R n 中的一个超平面。感知机本质上是「找一个能把两类数据分开的超平面」的模型 。
graph LR
x1((x1)) -->|w1| S["Σ + b"]
x2((x2)) -->|w2| S
xn((xn)) -->|wn| S
S --> step["sign·"]
step --> y((y))
学习算法本身极简——但要看清楚,需要先把后面要用到的符号一次列清:
符号 含义 类型 w ∈ R n w \in \mathbb{R}^n w ∈ R n 权重向量 参数 b ∈ R b \in \mathbb{R} b ∈ R 偏置标量 参数 x i ∈ R n x_i \in \mathbb{R}^n x i ∈ R n 第 i i i 个样本的输入 数据 y i ∈ { − 1 , + 1 } y_i \in \{-1, +1\} y i ∈ { − 1 , + 1 } 第 i i i 个样本的标签 数据 η > 0 \eta > 0 η > 0 学习率(learning rate),每步更新的步长 超参数 ← \leftarrow ← 赋值(用右值覆盖左值) 操作符
w w w 和 b b b 都是要学的参数,η \eta η 是人工选的超参数;缺了 b b b ,决策超平面就被锁在「过原点」的位置,无法做到超平面的平移 。
完整的训练循环是:
eta = 1 # 学习率
w = 0 ; b = 0
for _ in range (max_iter): # 迭代上限
n_updates = 0
for x_i, y_i in training_samples:
score = w @ x_i + b # 点积
if y_i * score <= 0 : # 误分类
w = w + eta * y_i * x_i
b = b + eta * y_i
n_updates += 1
if n_updates == 0 :
break # 一整轮无更新,收敛
只有误分类的点触发更新,正确分类的点跳过——这是感知机和后来的梯度下降在「更新触发条件」上的关键区别 。误分类的紧凑判据是 y i ( w ⋅ x i + b ) ≤ 0 y_i (w \cdot x_i + b) \le 0 y i ( w ⋅ x i + b ) ≤ 0 :真实标签与预测分数符号相反(或分数恰好为 0)。
为什么更新方向是 + η y i x i +\eta y_i x_i + η y i x i 而不是别的?设某点 ( x i , y i ) (x_i, y_i) ( x i , y i ) 被误分类。更新后再算一次它的分数:
w new ⋅ x i + b new = ( w + η y i x i ) ⋅ x i + ( b + η y i ) = ( w ⋅ x i + b ) + η y i ( ∥ x i ∥ 2 + 1 ) = 旧分数 + η y i ( ∥ x i ∥ 2 + 1 ) . \begin{aligned}
w_{\text{new}} \cdot x_i + b_{\text{new}}
&= (w + \eta y_i x_i) \cdot x_i + (b + \eta y_i) \\
&= (w \cdot x_i + b) + \eta y_i (\|x_i\|^2 + 1) \\
&= \text{旧分数} + \eta y_i (\|x_i\|^2 + 1).
\end{aligned} w new ⋅ x i + b new = ( w + η y i x i ) ⋅ x i + ( b + η y i ) = ( w ⋅ x i + b ) + η y i ( ∥ x i ∥ 2 + 1 ) = 旧分数 + η y i ( ∥ x i ∥ 2 + 1 ) .
η > 0 \eta > 0 η > 0 、∥ x i ∥ 2 + 1 > 0 \|x_i\|^2 + 1 > 0 ∥ x i ∥ 2 + 1 > 0 ,所以「新分数」相对「旧分数」沿 y i y_i y i 的方向严格挪了一段:y i = + 1 y_i = +1 y i = + 1 时变大、y i = − 1 y_i = -1 y i = − 1 时变小,两种情形都朝着「下一次能预测对」的方向走。y i y_i y i 既是「我希望分数往哪边走」的信号,也是让更新方向自动随标签反向的乘子;如果把它去掉、固定写成 + η x i +\eta x_i + η x i ,对负样本就会越走越错 。
具体跑一步:取 η = 1 \eta = 1 η = 1 ,初始 w = ( 0 , 0 ) , b = 0 w = (0, 0), b = 0 w = ( 0 , 0 ) , b = 0 ,两个训练点 x 1 = ( 2 , 1 ) , y 1 = + 1 x_1 = (2, 1), y_1 = +1 x 1 = ( 2 , 1 ) , y 1 = + 1 与 x 2 = ( − 1 , 2 ) , y 2 = − 1 x_2 = (-1, 2), y_2 = -1 x 2 = ( − 1 , 2 ) , y 2 = − 1 。
看 x 1 x_1 x 1 :分数 = 0 = 0 = 0 ,y 1 ⋅ 0 = 0 ≤ 0 y_1 \cdot 0 = 0 \le 0 y 1 ⋅ 0 = 0 ≤ 0 ,误分类,更新 w ← ( 2 , 1 ) , b ← 1 w \leftarrow (2, 1),\; b \leftarrow 1 w ← ( 2 , 1 ) , b ← 1 。
看 x 2 x_2 x 2 :分数 = 2 ⋅ ( − 1 ) + 1 ⋅ 2 + 1 = 1 = 2 \cdot (-1) + 1 \cdot 2 + 1 = 1 = 2 ⋅ ( − 1 ) + 1 ⋅ 2 + 1 = 1 ,预测 + 1 +1 + 1 但真实 − 1 -1 − 1 ,误分类,更新 w ← ( 3 , − 1 ) , b ← 0 w \leftarrow (3, -1),\; b \leftarrow 0 w ← ( 3 , − 1 ) , b ← 0 。
复查 x 1 x_1 x 1 :分数 = 5 > 0 = 5 > 0 = 5 > 0 ✓;复查 x 2 x_2 x 2 :分数 = − 5 < 0 = -5 < 0 = − 5 < 0 ✓。两个点都对了,循环终止。
工程上常见的简化是把 b b b 并入 w w w :给每个 x x x 末尾加一个常数 1、扩成 x ~ = ( x , 1 ) ∈ R n + 1 \tilde x = (x, 1) \in \mathbb{R}^{n+1} x ~ = ( x , 1 ) ∈ R n + 1 ,把权重也扩成 w ~ = ( w , b ) \tilde w = (w, b) w ~ = ( w , b ) ;这样 w ⋅ x + b = w ~ ⋅ x ~ w \cdot x + b = \tilde w \cdot \tilde x w ⋅ x + b = w ~ ⋅ x ~ ,整套更新塌成 w ~ ← w ~ + η y i x ~ i \tilde w \leftarrow \tilde w + \eta y_i \tilde x_i w ~ ← w ~ + η y i x ~ i ,公式更紧凑。b b b 在数学上仍是参数,只是位于扩展向量的最后一个分量 。
整个学习过程没有梯度、没有反向传播、没有损失函数的概念——它是「错就改」的最原始版本:误分类的点把超平面朝自己拉一点,正确分类的点保持不动 。
1.2 Novikoff 收敛性定理
光有学习规则不够,还要回答两个问题:这套规则在什么条件下一定能停?停的时候要多少步?1962 年 Novikoff 给出了完整的答案:在数据线性可分时,感知机算法在 ⌈ R 2 / γ 2 ⌉ \lceil R^2 / \gamma^2 \rceil ⌈ R 2 / γ 2 ⌉ 步内必然收敛 。
定理 (Novikoff 1962):设训练集 { ( x i , y i ) } i = 1 N \{(x_i, y_i)\}_{i=1}^N {( x i , y i ) } i = 1 N 满足 ∥ x i ∥ ≤ R \|x_i\| \le R ∥ x i ∥ ≤ R ,且存在 w ∗ w^* w ∗ (不失一般性地取 ∥ w ∗ ∥ = 1 \|w^*\| = 1 ∥ w ∗ ∥ = 1 )使得对所有 i i i 都有 y i ( w ∗ ⋅ x i ) ≥ γ > 0 y_i (w^* \cdot x_i) \ge \gamma > 0 y i ( w ∗ ⋅ x i ) ≥ γ > 0 。则从 w 0 = 0 w_0 = 0 w 0 = 0 开始、学习率 η = 1 \eta = 1 η = 1 的感知机算法在至多 t ≤ R 2 / γ 2 t \le R^2 / \gamma^2 t ≤ R 2 / γ 2 次更新后收敛。
证明分上下两个 bound 后用 Cauchy-Schwarz 夹起来。设 w t w_t w t 是经过 t t t 次更新后的权向量。
内积下界 :每次更新 w t = w t − 1 + y i t x i t w_t = w_{t-1} + y_{i_t} x_{i_t} w t = w t − 1 + y i t x i t ,于是
w t ⋅ w ∗ = ( w t − 1 + y i t x i t ) ⋅ w ∗ = w t − 1 ⋅ w ∗ + y i t ( x i t ⋅ w ∗ ) ≥ w t − 1 ⋅ w ∗ + γ . \begin{aligned}
w_t \cdot w^*
&= (w_{t-1} + y_{i_t} x_{i_t}) \cdot w^* \\
&= w_{t-1} \cdot w^* + y_{i_t} (x_{i_t} \cdot w^*) \\
&\ge w_{t-1} \cdot w^* + \gamma.
\end{aligned} w t ⋅ w ∗ = ( w t − 1 + y i t x i t ) ⋅ w ∗ = w t − 1 ⋅ w ∗ + y i t ( x i t ⋅ w ∗ ) ≥ w t − 1 ⋅ w ∗ + γ .
从 w 0 ⋅ w ∗ = 0 w_0 \cdot w^* = 0 w 0 ⋅ w ∗ = 0 递推到 t t t 步得 w t ⋅ w ∗ ≥ t γ w_t \cdot w^* \ge t \gamma w t ⋅ w ∗ ≥ t γ 。
范数平方上界 :
∥ w t ∥ 2 = ∥ w t − 1 + y i t x i t ∥ 2 = ∥ w t − 1 ∥ 2 + 2 y i t ( w t − 1 ⋅ x i t ) + ∥ x i t ∥ 2 . \begin{aligned}
\|w_t\|^2
&= \|w_{t-1} + y_{i_t} x_{i_t}\|^2 \\
&= \|w_{t-1}\|^2 + 2 y_{i_t} (w_{t-1} \cdot x_{i_t}) + \|x_{i_t}\|^2.
\end{aligned} ∥ w t ∥ 2 = ∥ w t − 1 + y i t x i t ∥ 2 = ∥ w t − 1 ∥ 2 + 2 y i t ( w t − 1 ⋅ x i t ) + ∥ x i t ∥ 2 .
更新发生的前提是 ( x i t , y i t ) (x_{i_t}, y_{i_t}) ( x i t , y i t ) 在 w t − 1 w_{t-1} w t − 1 下被误分类,即 y i t ( w t − 1 ⋅ x i t ) ≤ 0 y_{i_t} (w_{t-1} \cdot x_{i_t}) \le 0 y i t ( w t − 1 ⋅ x i t ) ≤ 0 ,因此中间项 ≤ 0 \le 0 ≤ 0 ;再代入 ∥ x i t ∥ 2 ≤ R 2 \|x_{i_t}\|^2 \le R^2 ∥ x i t ∥ 2 ≤ R 2 得 ∥ w t ∥ 2 ≤ ∥ w t − 1 ∥ 2 + R 2 \|w_t\|^2 \le \|w_{t-1}\|^2 + R^2 ∥ w t ∥ 2 ≤ ∥ w t − 1 ∥ 2 + R 2 。从 ∥ w 0 ∥ = 0 \|w_0\| = 0 ∥ w 0 ∥ = 0 递推到 t t t 步得 ∥ w t ∥ 2 ≤ t R 2 \|w_t\|^2 \le t R^2 ∥ w t ∥ 2 ≤ t R 2 。
夹定 :由 Cauchy-Schwarz w t ⋅ w ∗ ≤ ∥ w t ∥ ⋅ ∥ w ∗ ∥ = ∥ w t ∥ w_t \cdot w^* \le \|w_t\| \cdot \|w^*\| = \|w_t\| w t ⋅ w ∗ ≤ ∥ w t ∥ ⋅ ∥ w ∗ ∥ = ∥ w t ∥ ,结合上下界得
t γ ≤ w t ⋅ w ∗ ≤ ∥ w t ∥ ≤ t R 2 = R t . t \gamma \;\le\; w_t \cdot w^* \;\le\; \|w_t\| \;\le\; \sqrt{t R^2} = R \sqrt{t}. t γ ≤ w t ⋅ w ∗ ≤ ∥ w t ∥ ≤ t R 2 = R t .
平方两边除以 γ 2 \gamma^2 γ 2 即 t ≤ R 2 / γ 2 t \le R^2 / \gamma^2 t ≤ R 2 / γ 2 。■ \blacksquare ■
Novikoff 定理给的不是渐进保证,而是绝对上界——只要数据线性可分,迭代次数被「半径 R R R 与 margin γ \gamma γ 的比值」一次性卡死 。1960 年代这条结果一度让人对感知机的前景非常乐观;但马上就会迎来新的限制。
1.3 异或问题:线性不可分的代数与几何
Minsky 与 Papert 在 1969 年的 《Perceptrons》 一书里给出了一个让感知机几乎被打入冷宫的反例:异或(XOR )。XOR 把 ( x 1 , x 2 ) ∈ { 0 , 1 } 2 (x_1, x_2) \in \{0, 1\}^2 ( x 1 , x 2 ) ∈ { 0 , 1 } 2 映成 0 或 1,真值表是:
x 1 x_1 x 1 x 2 x_2 x 2 XOR 0 0 0 0 1 1 1 0 1 1 1 0
代数上假设存在 ( w 1 , w 2 , b ) (w_1, w_2, b) ( w 1 , w 2 , b ) 使感知机能学到 XOR。把四个点代入符号约束(输出 1 时 ≥ 0 \ge 0 ≥ 0 ,输出 0 时 < 0 < 0 < 0 ):
b < 0 from ( 0 , 0 ) → 0 , w 2 + b ≥ 0 from ( 0 , 1 ) → 1 , w 1 + b ≥ 0 from ( 1 , 0 ) → 1 , w 1 + w 2 + b < 0 from ( 1 , 1 ) → 0. \begin{aligned}
b &< 0 \quad &&\text{from } (0, 0) \to 0, \\
w_2 + b &\ge 0 \quad &&\text{from } (0, 1) \to 1, \\
w_1 + b &\ge 0 \quad &&\text{from } (1, 0) \to 1, \\
w_1 + w_2 + b &< 0 \quad &&\text{from } (1, 1) \to 0.
\end{aligned} b w 2 + b w 1 + b w 1 + w 2 + b < 0 ≥ 0 ≥ 0 < 0 from ( 0 , 0 ) → 0 , from ( 0 , 1 ) → 1 , from ( 1 , 0 ) → 1 , from ( 1 , 1 ) → 0.
把第 2 式与第 3 式相加得 w 1 + w 2 + 2 b ≥ 0 w_1 + w_2 + 2b \ge 0 w 1 + w 2 + 2 b ≥ 0 ;把第 1 式与第 4 式相加得 w 1 + w 2 + 2 b < 0 w_1 + w_2 + 2b < 0 w 1 + w 2 + 2 b < 0 。两条不等式直接矛盾——任何单层线性模型在代数上都无法实现 XOR 。
几何上更直白:决策边界 w 1 x 1 + w 2 x 2 + b = 0 w_1 x_1 + w_2 x_2 + b = 0 w 1 x 1 + w 2 x 2 + b = 0 是 R 2 \mathbb{R}^2 R 2 中的一条直线,把平面切成两个半平面。XOR 要求 ( 0 , 0 ) (0, 0) ( 0 , 0 ) 与 ( 1 , 1 ) (1, 1) ( 1 , 1 ) 落在 0 这一侧、( 0 , 1 ) (0, 1) ( 0 , 1 ) 与 ( 1 , 0 ) (1, 0) ( 1 , 0 ) 落在 1 这一侧——把每一类的两个点用线段连起来,恰好得到单位正方形的两条对角线,而这两条对角线在中心 ( 0.5 , 0.5 ) (0.5,\, 0.5) ( 0.5 , 0.5 ) 处相交。两类点的凸包一旦相交(这里是两条交于中心的对角线段),就不存在一条直线能把它们分到不同的半平面,因此没有任何超平面能完成 XOR 的「跨对角线同色」切分 。
x2
│
1 ● ○ ● 类别 1
│
│
0 ○ ● ○ 类别 0
└────────────── x1
0 1
XOR 不是孤立反例——它指出了一类更广的问题:只要类别需要「非凸的决策区域」,单层线性模型就必然失败 。要打开这条天花板,下一步必须把模型从「单个超平面」推到「多个超平面的组合」,由此引出多层感知机。
2. 多层感知机:非线性的涌现
2.1 从单层到多层的矩阵级联
多层感知机 (MLP)的写法是把多个线性变换中间夹一个非线性激活 σ \sigma σ 串起来。两层 MLP 形式:
y = σ ( W 2 σ ( W 1 x + b 1 ) + b 2 ) , y \;=\; \sigma\!\left(W_2 \, \sigma(W_1 x + b_1) + b_2\right), y = σ ( W 2 σ ( W 1 x + b 1 ) + b 2 ) ,
其中 W 1 ∈ R h × n W_1 \in \mathbb{R}^{h \times n} W 1 ∈ R h × n 把 n n n 维输入映到 h h h 维隐层、W 2 ∈ R m × h W_2 \in \mathbb{R}^{m \times h} W 2 ∈ R m × h 把隐层映到 m m m 维输出,σ \sigma σ 是 element-wise 非线性。一般可以推广到 L L L 层:
a 0 = x , a l = σ ( W l a l − 1 + b l ) ( l = 1 , … , L ) , y = a L . a_0 = x, \quad a_l = \sigma(W_l a_{l-1} + b_l) \;\; (l = 1, \dots, L), \quad y = a_L. a 0 = x , a l = σ ( W l a l − 1 + b l ) ( l = 1 , … , L ) , y = a L .
多层感知机的本质是用矩阵乘法把若干线性变换串起来,再在每两层之间插入一次非线性 σ \sigma σ 防止整体退化 。这里「非线性 σ」是关键——下一节会证明缺了它,整套结构会立刻塌成单层。
2.2 线性崩塌定理:激活函数为何必须存在
把上面定义的 σ \sigma σ 换成恒等映射 σ ( z ) = z \sigma(z) = z σ ( z ) = z ,两层 MLP 就变成
y = W 2 ( W 1 x + b 1 ) + b 2 = ( W 2 W 1 ) x + ( W 2 b 1 + b 2 ) ≡ W ~ x + b ~ , \begin{aligned}
y &= W_2 (W_1 x + b_1) + b_2 \\
&= (W_2 W_1) x + (W_2 b_1 + b_2) \\
&\equiv \tilde W x + \tilde b,
\end{aligned} y = W 2 ( W 1 x + b 1 ) + b 2 = ( W 2 W 1 ) x + ( W 2 b 1 + b 2 ) ≡ W ~ x + b ~ ,
是一个新的线性变换。一般地,L L L 层全线性 MLP 为
y = W L W L − 1 ⋯ W 1 x + ∑ l = 1 L ( ∏ k = l + 1 L W k ) b l = W ~ x + b ~ , y = W_L W_{L-1} \cdots W_1 x + \sum_{l=1}^{L} \!\left(\prod_{k=l+1}^{L} W_k\right) b_l = \tilde W x + \tilde b, y = W L W L − 1 ⋯ W 1 x + l = 1 ∑ L ( k = l + 1 ∏ L W k ) b l = W ~ x + b ~ ,
仍是单层线性变换。任何有限层数的纯线性变换复合仍然是线性变换——无论叠多少层,表达能力都不会超过最浅那一层 。这就是「线性崩塌」(linear collapse)。
非线性激活的存在是让整个结构跳出仿射子空间的唯一方式。具体跳出多远由 σ \sigma σ 的选择与层数 L L L 决定,但前提是 σ \sigma σ 不是恒等映射。激活函数不是装饰——它是非线性表达能力的唯一来源 。
2.3 万能近似定理:构造性证明思路
非线性激活带来表达能力的「下限」是多少?1989 年 Cybenko 与 1991 年 Hornik 各自给出答案:万能近似定理 (Universal Approximation Theorem,UAT)。
定理 (Cybenko 1989):设 σ \sigma σ 是连续、单调递增、有界的激活函数(sigmoidal)。则对紧集 (compact set,即闭且有界的子集,例如 [ 0 , 1 ] n [0, 1]^n [ 0 , 1 ] n )K ⊂ R n K \subset \mathbb{R}^n K ⊂ R n 上任意连续函数 f : K → R f: K \to \mathbb{R} f : K → R 与任意 ϵ > 0 \epsilon > 0 ϵ > 0 ,都存在自然数 h h h 、权重 { w i , b i , α i } i = 1 h \{w_i, b_i, \alpha_i\}_{i=1}^h { w i , b i , α i } i = 1 h ,使得网络
g ( x ) = ∑ i = 1 h α i σ ( w i ⋅ x + b i ) g(x) = \sum_{i=1}^{h} \alpha_i \sigma(w_i \cdot x + b_i) g ( x ) = i = 1 ∑ h α i σ ( w i ⋅ x + b i )
满足 sup x ∈ K ∣ g ( x ) − f ( x ) ∣ < ϵ \sup_{x \in K} |g(x) - f(x)| < \epsilon sup x ∈ K ∣ g ( x ) − f ( x ) ∣ < ϵ 。
构造性思路(不写完整证明,只写直觉):以 σ \sigma σ 为 sigmoid 为例。σ ( α ( z − c ) ) \sigma(\alpha(z - c)) σ ( α ( z − c )) 本身是一条光滑的 S 曲线,在 z = c z = c z = c 附近从 0 平滑过渡 到 1——α 越大,过渡区间越窄、曲线越陡,形态越接近以 c c c 为台阶的阶跃函数。
把两条过渡位置相隔很近 (间距 δ \delta δ )的这种 sigmoid 相减——σ ( α ( z − c ) ) − σ ( α ( z − c − δ ) ) \sigma(\alpha(z - c)) - \sigma(\alpha(z - c - \delta)) σ ( α ( z − c )) − σ ( α ( z − c − δ )) ,按 z z z 轴分三段看就很直观:
区间 σ ( α ( z − c ) ) \sigma(\alpha(z - c)) σ ( α ( z − c )) σ ( α ( z − c − δ ) ) \sigma(\alpha(z - c - \delta)) σ ( α ( z − c − δ )) 差 z < c z < c z < c ≈ 0 \approx 0 ≈ 0 ≈ 0 \approx 0 ≈ 0 ≈ 0 \approx 0 ≈ 0 z ∈ [ c , c + δ ] z \in [c,\, c+\delta] z ∈ [ c , c + δ ] ≈ 1 \approx 1 ≈ 1 (已跨过 c c c )≈ 0 \approx 0 ≈ 0 (还没到 c + δ c+\delta c + δ )≈ 1 \approx 1 ≈ 1 z > c + δ z > c + \delta z > c + δ ≈ 1 \approx 1 ≈ 1 ≈ 1 \approx 1 ≈ 1 ≈ 0 \approx 0 ≈ 0
差只在中间那条窄带上 ≈ 1 \approx 1 ≈ 1 、其他地方 ≈ 0 \approx 0 ≈ 0 ——这就是一个支撑在 [ c , c + δ ] [c, c + \delta] [ c , c + δ ] 上的矩形脉冲,由两个错开 δ \delta δ 的阶跃做差得到 。α \alpha α 有限时这个矩形是光滑过渡(两侧不再是直角),所以本质上 sigmoid 差给我们提供了一个矩形脉冲的光滑近似。
而紧集上的连续函数都可以被阶梯函数 (即分段常数函数:一串高度不同、宽度足够小的矩形构成)任意精度地一致逼近——这是 Heine–Cantor 一致连续定理 的直接推论(紧集上连续 f f f 一致连续,所以把紧集切得足够细、每块上用代表点的 f ( x i ) f(x_i) f ( x i ) 当常数即可,逼近误差被切片宽度卡死)。把阶梯函数里的每个矩形换成对应高度的 sigmoid 差窄峰、再按段加起来,就用一个单隐层 sigmoid 网络分段逼近了 f f f ——形式正是 UAT 定理陈述里的 g ( x ) = ∑ i α i σ ( w i ⋅ x + b i ) g(x) = \sum_i \alpha_i \sigma(w_i \cdot x + b_i) g ( x ) = ∑ i α i σ ( w i ⋅ x + b i ) 。Hornik 1991 把结论推广到任意非常数、有界、连续的 σ \sigma σ ,并不要求 sigmoidal 形状。
UAT 给的是「表达能力的存在性保证」,不是构造效率,更不是优化或泛化保证 。它告诉我们「神经网络原理上能逼近任何连续函数」——但「能逼近」≠「能学到」(这是优化问题)≠「在测试集上也能逼近」(这是泛化问题)。这两条恰恰是 § 3-5 要讨论的核心。
2.4 激活函数全景:饱和到非饱和
讲具体函数之前先把后面会反复出现的几个术语定义清楚:
饱和区(saturation region) :激活函数导数 σ ′ ( z ) → 0 \sigma'(z) \to 0 σ ′ ( z ) → 0 的区域。在饱和区里输入再变化也几乎不影响输出,反向传播时这一层的梯度会被压扁到接近零。
饱和型激活函数(saturating activation) :两端都有饱和区的激活函数。Sigmoid(z → ± ∞ z \to \pm\infty z → ± ∞ 时分别趋近 0 / 1)和 tanh(趋近 ∓ 1 \mp 1 ∓ 1 )都是双侧饱和;深层网络里这类函数的链积 ∏ σ ′ \prod \sigma' ∏ σ ′ 容易指数衰减。
半饱和激活函数 :只一边饱和,比如 ReLU 的负半区(z < 0 z < 0 z < 0 时 σ = 0 \sigma = 0 σ = 0 );正半区 σ ′ ( z ) = 1 \sigma'(z) = 1 σ ′ ( z ) = 1 不饱和。
死亡区(dying region) :导数严格等于 0 而不是接近 0 的区域。ReLU 的负半区就是这样:σ ( z ) = 0 \sigma(z) = 0 σ ( z ) = 0 且 σ ′ ( z ) = 0 \sigma'(z) = 0 σ ′ ( z ) = 0 ,落到这里的神经元再也收不到梯度信号、永远不更新——这就是「dying ReLU」。死亡区和饱和区的差别是「严格零」vs「接近零」;前者不可逆,后者还能因为小扰动恢复。
UAT 对 σ \sigma σ 的形态要求很宽,但工程上选哪个 σ \sigma σ 直接决定训练稳定性。常见的四种激活函数:
-4 -3 -2 -1 0 1 2 3 4 输入 z -1 0 1 2 3 4 激活值 σ(z) Sigmoid Tanh ReLU GeLU 四种激活函数对比
比训练影响更直接的是它们的导数 ——反向传播链积全靠 σ ′ \sigma' σ ′ 在每一层乘进去:
-4 -3 -2 -1 0 1 2 3 4 输入 z 0 0.2 0.4 0.6 0.8 1 1.2 导数 σ'(z) Sigmoid' Tanh' ReLU' GeLU' 四种激活函数的导数
四种激活函数的关键差别都集中在导数特性上:
激活 表达式 σ ′ ( 0 ) \sigma'(0) σ ′ ( 0 ) 饱和区导数 训练表现 Sigmoid 1 / ( 1 + e − z ) 1 / (1 + e^{-z}) 1/ ( 1 + e − z ) 0.25 → 0 \to 0 → 0 深网络极易梯度消失 Tanh tanh ( z ) \tanh(z) tanh ( z ) 1 → 0 \to 0 → 0 比 sigmoid 略好,仍饱和 ReLU max ( 0 , z ) \max(0, z) max ( 0 , z ) 1(约定) 1(正区)/ 0(负区) 不饱和但有死亡区 GeLU z ⋅ Φ ( z ) z \cdot \Phi(z) z ⋅ Φ ( z ) 0.5 → 1 \to 1 → 1 (正区)/ → 0 \to 0 → 0 (负区)Transformer 标配,光滑
饱和型激活(sigmoid、tanh)在 ∣ z ∣ \lvert z \rvert ∣ z ∣ 大时导数趋于 0,深网络的链积 ∏ σ ′ \prod \sigma' ∏ σ ′ 会指数衰减——这是 sigmoid 在深层网络上几乎被弃用的根本原因 。ReLU 把正区导数固定到 1 解决了饱和问题,但引入了「半区死亡」(dying ReLU):负区导数恒为 0,一旦某神经元被推到负区就再也无法更新。GeLU 把 ReLU 的拐点光滑化,是现代 Transformer 等架构的默认选择。
ReLU 的死亡区催生了一批改良版本,工程上常用的几个:
Leaky ReLU :σ ( z ) = max ( α z , z ) \sigma(z) = \max(\alpha z, z) σ ( z ) = max ( α z , z ) ,其中 α \alpha α 是一个小正数(通常 0.01)。把 ReLU 的负区导数从 0 改成 α \alpha α ,死亡区消失——任何输入都有非零梯度往回传。
PReLU (Parametric ReLU):跟 Leaky ReLU 同形,但 α \alpha α 当成可学习参数、每层各自学一个。
ELU (Exponential Linear Unit):σ ( z ) = z \sigma(z) = z σ ( z ) = z 若 z > 0 z > 0 z > 0 、α ( e z − 1 ) \alpha(e^z - 1) α ( e z − 1 ) 若 z ≤ 0 z \le 0 z ≤ 0 。当 z → − ∞ z \to -\infty z → − ∞ 时函数值 σ ( z ) → − α \sigma(z) \to -\alpha σ ( z ) → − α (负区饱和在 y = − α y = -\alpha y = − α ),所以整个函数处处可导且有下界 − α -\alpha − α ,训练上通常比 Leaky ReLU 更稳。
Swish / SiLU :σ ( z ) = z ⋅ σ sigm ( z ) \sigma(z) = z \cdot \sigma_\text{sigm}(z) σ ( z ) = z ⋅ σ sigm ( z ) (σ sigm \sigma_\text{sigm} σ sigm 即 sigmoid)。形状跟 GeLU 几乎一样——GeLU 用累积分布函数 Φ \Phi Φ 做平滑权重、Swish 用 sigmoid,在大模型实践里两者基本可以互换。
把这几个改良函数(Leaky ReLU 取 α = 0.1 \alpha = 0.1 α = 0.1 、ELU 取 α = 1 \alpha = 1 α = 1 ,叠加 plain ReLU 当对照)画在同一张图里看形状差异:
-4 -3 -2 -1 0 1 2 3 4 输入 z -1 0 1 2 3 4 激活值 σ(z) ReLU(对照) Leaky ReLU (α=0.1) ELU (α=1) Swish / SiLU ReLU 改良家族对比
对应的导数:
-4 -3 -2 -1 0 1 2 3 4 输入 z -0.2 0 0.2 0.4 0.6 0.8 1 1.2 导数 σ'(z) ReLU'(对照) Leaky ReLU' (α=0.1) ELU' (α=1) Swish' / SiLU' ReLU 改良家族的导数
观察要点:Leaky ReLU 把 ReLU 的负区导数从 0 抬到 α \alpha α (一条水平线,这就是消死亡区的全部代价);ELU 在 z = 0 z = 0 z = 0 处导数连续,不像 ReLU 是折角;Swish 整体光滑、在 z ≈ − 1.3 z \approx -1.3 z ≈ − 1.3 附近导数甚至会降到轻微负值——这正是它跟 GeLU 在形态上能互换的依据 。
实际选哪个,按场景大致分 :
Transformer / 大语言模型 :默认 GeLU(BERT、GPT 系列、LLaMA 都是);Swish / SiLU 可替代。光滑性帮助大模型优化器稳定。
CNN / 普通 MLP 的隐层 :ReLU 仍是默认,简单高效;担心死亡区可换 Leaky ReLU 或 ELU。
输出层 :取决于任务——回归用线性、二分类用 sigmoid、多分类用 softmax;这一层的「饱和」是设计目的(把 logits 压到概率),不算问题。
LSTM / GRU 的门 :门控本身需要 [ 0 , 1 ] [0, 1] [ 0 , 1 ] 输出,所以用 sigmoid;cell state 用 tanh。这是 RNN 设计的内嵌结构,不要换。
避免在深层隐层用 sigmoid / tanh :链积衰减太狠,除非有 BatchNorm / LayerNorm 兜底(见 § 4.3)。
权重初始化要配套:ReLU 家族用 He 初始化、sigmoid / tanh 用 Xavier(§ 4.2 推导)。
§ 4 会回到这里量化「链积衰减」到底意味着什么。
3. 训练神经网络:损失、反向传播、梯度下降
3.1 训练流程全景
§ 1-2 把神经网络「能表达什么」讲完了——单层模型只能切超平面、多层 + 非线性可以逼近任意连续函数。剩下的核心问题是:给定网络结构,怎么从数据里学出参数 θ \theta θ ? 这一节先给一个高层视角——训练循环的三个核心动作(定义损失 / 反向传播算梯度 / 梯度下降更新参数 );§ 3.2 再展开「损失从哪来」。
1. 训练目标 :把网络看成参数化函数 f θ f_\theta f θ ,给定训练集 { ( x i , y i ) } i = 1 N \{(x_i, y_i)\}_{i=1}^N {( x i , y i ) } i = 1 N ,训练的目标是找到 θ ∗ \theta^* θ ∗ 使「模型预测与真实标签的差距」最小 ——这个「差距」由一个损失函数(loss function) L ( θ ) L(\theta) L ( θ ) 量化(常见形式见下文 §3.2,概率诠释见 §3.3)。
2. 梯度下降 :神经网络通常没有解析最优解,所以训练用迭代法——每一步沿损失对参数的负梯度方向 走一小步:
θ ← θ − η ∇ θ L ( θ ) . \theta \leftarrow \theta - \eta\, \nabla_\theta L(\theta). θ ← θ − η ∇ θ L ( θ ) .
直觉:梯度 ∇ θ L \nabla_\theta L ∇ θ L 指向损失上升最快 的方向;反方向就是下降最快 的方向。学习率 η \eta η (一个小正数,如 10 − 3 10^{-3} 1 0 − 3 )控制每一步走多远——太大会越过最优、太小收敛太慢。这就是 梯度下降 (gradient descent)。
3. 反向传播是个高效算梯度的算法 :现代神经网络的参数动辄上百万、上亿,∇ θ L \nabla_\theta L ∇ θ L 不可能逐个手工求偏导。反向传播 (backpropagation)解决的就是这件事:把网络看成一张计算图(forward pass 算出来),然后按图的反向拓扑顺序、用链式法则 一次性算出所有 ∂ L / ∂ θ j \partial L / \partial \theta_j ∂ L / ∂ θ j ,计算量跟前向同阶 。注意区分两个词——「反向传播」是算梯度的算法 ,「梯度下降」是用梯度的优化算法 ;两者配合才能完成一次参数更新,缺一不可。
4. 完整训练循环 :把上面三件事串起来:
graph LR
input["输入 x_batch"] --> forward["前向: y_pred = f_θx"]
forward --> loss["算损失 L"]
loss --> backward["反向: ∇_θ L"]
backward --> update["更新: θ ← θ - η∇L"]
update --> input
对应的伪代码(一个最朴素的 mini-batch SGD (随机梯度下降) 训练循环——每次只用一个 batch 的样本算梯度并更新,而不是扫整个训练集;这是所有现代框架的默认范式):
for epoch in range (num_epochs):
for x_batch, y_batch in dataloader:
y_pred = model.forward(x_batch) # 前向
loss = loss_fn(y_pred, y_batch) # 算损失
grads = loss.backward() # 反向传播 → ∇L
for param in model.parameters():
param -= eta * grads[param] # 梯度下降
训练循环的本质是「前向算预测 → 算损失 → 反向算梯度 → 一小步更新」的反复迭代 。
3.2 常见损失函数一览
在进入概率推导之前,先看一下深度学习里最常用的几个损失函数,建立一个初步的「损失全景」:
损失 形式 典型用途 MSE / L2 1 N ∑ i ( y i − y ^ i ) 2 \frac{1}{N}\sum_i (y_i - \hat y_i)^2 N 1 ∑ i ( y i − y ^ i ) 2 回归 MAE / L1 1 N ∑ i ∣ y i − y ^ i ∣ \frac{1}{N}\sum_i \lvert y_i - \hat y_i \rvert N 1 ∑ i ∣ y i − y ^ i ∣ 回归,对离群点更稳健 二分类交叉熵 − y log y ^ − ( 1 − y ) log ( 1 − y ^ ) -y \log \hat y - (1-y) \log(1 - \hat y) − y log y ^ − ( 1 − y ) log ( 1 − y ^ ) 二分类 多分类交叉熵 − ∑ k y k log y ^ k -\sum_k y_k \log \hat y_k − ∑ k y k log y ^ k 多分类(配 softmax 输出) Hinge loss max ( 0 , 1 − y y ^ ) \max(0,\, 1 - y \hat y) max ( 0 , 1 − y y ^ ) SVM、max-margin 分类 KL 散度 ∑ x p ( x ) log p ( x ) q ( x ) \sum_x p(x) \log \frac{p(x)}{q(x)} ∑ x p ( x ) log q ( x ) p ( x ) 分布匹配(VAE、知识蒸馏)
3.3 损失函数的概率解释:MLE 推 MSE 与交叉熵
很多教材把 MSE 与交叉熵当作两条独立的损失,但它们其实都来自同一个源头:最大似然估计 (MLE)+ 不同的噪声 / 输出分布假设。
回归情形(高斯噪声) :假设观测 y i = f θ ( x i ) + ϵ i y_i = f_\theta(x_i) + \epsilon_i y i = f θ ( x i ) + ϵ i ,其中 ϵ i ∼ N ( 0 , σ 2 ) \epsilon_i \sim \mathcal{N}(0, \sigma^2) ϵ i ∼ N ( 0 , σ 2 ) 独立同分布。条件密度
p ( y i ∣ x i , θ ) = 1 2 π σ exp ( − ( y i − f θ ( x i ) ) 2 2 σ 2 ) . p(y_i \mid x_i, \theta) = \frac{1}{\sqrt{2\pi}\,\sigma} \exp\!\left(-\frac{(y_i - f_\theta(x_i))^2}{2\sigma^2}\right). p ( y i ∣ x i , θ ) = 2 π σ 1 exp ( − 2 σ 2 ( y i − f θ ( x i ) ) 2 ) .
对数似然
log p ( { y i } ∣ { x i } , θ ) = ∑ i = 1 N log p ( y i ∣ x i , θ ) = − 1 2 σ 2 ∑ i = 1 N ( y i − f θ ( x i ) ) 2 − N log ( 2 π σ ) . \begin{aligned}
\log p(\{y_i\} \mid \{x_i\}, \theta)
&= \sum_{i=1}^{N} \log p(y_i \mid x_i, \theta) \\
&= -\frac{1}{2\sigma^2}\sum_{i=1}^{N}(y_i - f_\theta(x_i))^2 - N \log(\sqrt{2\pi}\,\sigma).
\end{aligned} log p ({ y i } ∣ { x i } , θ ) = i = 1 ∑ N log p ( y i ∣ x i , θ ) = − 2 σ 2 1 i = 1 ∑ N ( y i − f θ ( x i ) ) 2 − N log ( 2 π σ ) .
第二项与 θ \theta θ 无关,最大化对数似然等价于最小化 ∑ ( y i − f θ ( x i ) ) 2 \sum (y_i - f_\theta(x_i))^2 ∑ ( y i − f θ ( x i ) ) 2 ——这就是 MSE。MSE 不是凭空定义的损失——它是「输出加高斯噪声」假设下的 MLE 直接产物 。
分类情形(伯努利输出) :二分类时令 f θ ( x ) ∈ ( 0 , 1 ) f_\theta(x) \in (0, 1) f θ ( x ) ∈ ( 0 , 1 ) 是模型预测的「类别为 1 的概率」,标签 y i ∈ { 0 , 1 } y_i \in \{0, 1\} y i ∈ { 0 , 1 } 。伯努利分布 是只取 { 0 , 1 } \{0, 1\} { 0 , 1 } 的随机变量分布,由一个参数 π ∈ [ 0 , 1 ] \pi \in [0, 1] π ∈ [ 0 , 1 ] 完全决定:P ( Y = 1 ) = π P(Y = 1) = \pi P ( Y = 1 ) = π 、P ( Y = 0 ) = 1 − π P(Y = 0) = 1 - \pi P ( Y = 0 ) = 1 − π 。它的紧凑写法用「指数当 if-else 选择器 」把两种情况合并成一行——
P ( Y = y ) = π y ( 1 − π ) 1 − y , y ∈ { 0 , 1 } . P(Y = y) = \pi^y (1 - \pi)^{1 - y}, \quad y \in \{0, 1\}. P ( Y = y ) = π y ( 1 − π ) 1 − y , y ∈ { 0 , 1 } .
代进去验证:y = 1 y = 1 y = 1 时 ( 1 − π ) 0 = 1 (1 - \pi)^0 = 1 ( 1 − π ) 0 = 1 退场,剩 π \pi π ;y = 0 y = 0 y = 0 时 π 0 = 1 \pi^0 = 1 π 0 = 1 退场,剩 1 − π 1 - \pi 1 − π 。任何数的 0 次幂等于 1——所以「不该选中的那一项」自动消失。
「条件分布 」中的「条件」指给定输入 x i x_i x i ——模型让伯努利的参数 π \pi π 变成 x i x_i x i 的函数 π ( x i ) = f θ ( x i ) \pi(x_i) = f_\theta(x_i) π ( x i ) = f θ ( x i ) ,同一个 θ \theta θ 在不同 x i x_i x i 上输出不同的 π \pi π 。把 π ( x i ) \pi(x_i) π ( x i ) 代入伯努利紧凑形式:
p ( y i ∣ x i , θ ) = f θ ( x i ) y i ( 1 − f θ ( x i ) ) 1 − y i . p(y_i \mid x_i, \theta) = f_\theta(x_i)^{y_i} (1 - f_\theta(x_i))^{1 - y_i}. p ( y i ∣ x i , θ ) = f θ ( x i ) y i ( 1 − f θ ( x i ) ) 1 − y i .
举例(猫狗分类):模型对一张图输出 f θ ( x ) = 0.8 f_\theta(x) = 0.8 f θ ( x ) = 0.8 (「这是猫」的预测概率)。若真实标签 y = 1 y = 1 y = 1 (猫),代入得 p ( y = 1 ∣ x , θ ) = 0.8 1 ⋅ 0.2 0 = 0.8 p(y = 1 \mid x, \theta) = 0.8^1 \cdot 0.2^0 = 0.8 p ( y = 1 ∣ x , θ ) = 0. 8 1 ⋅ 0. 2 0 = 0.8 ——模型对真实标签赋的概率很高;若真实是 y = 0 y = 0 y = 0 (狗),p ( y = 0 ∣ x , θ ) = 0.8 0 ⋅ 0.2 1 = 0.2 p(y = 0 \mid x, \theta) = 0.8^0 \cdot 0.2^1 = 0.2 p ( y = 0 ∣ x , θ ) = 0. 8 0 ⋅ 0. 2 1 = 0.2 ——模型判断错了,给真实标签的概率很低。MLE 要做的就是调 θ \theta θ 让所有训练样本上模型赋给真实标签的概率尽量大 。
对数似然
log p ( { y i } ∣ { x i } , θ ) = ∑ i = 1 N [ y i log f θ ( x i ) + ( 1 − y i ) log ( 1 − f θ ( x i ) ) ] . \log p(\{y_i\} \mid \{x_i\}, \theta) = \sum_{i=1}^{N} \big[\, y_i \log f_\theta(x_i) + (1 - y_i) \log(1 - f_\theta(x_i)) \,\big]. log p ({ y i } ∣ { x i } , θ ) = i = 1 ∑ N [ y i log f θ ( x i ) + ( 1 − y i ) log ( 1 − f θ ( x i )) ] .
取负即为二分类的交叉熵 损失。多分类用 softmax 输出 f θ ( x ) = ( p 1 , … , p K ) f_\theta(x) = (p_1, \dots, p_K) f θ ( x ) = ( p 1 , … , p K ) ,one-hot 标签 y y y 同样推出 categorical cross-entropy − ∑ k y k log p k -\sum_k y_k \log p_k − ∑ k y k log p k 。
那为什么叫「交叉 熵」?这个名字来自信息论。按信息论的经典约定,一个离散 分布 p p p 的熵 (entropy)
H ( p ) = − ∑ x p ( x ) log 2 p ( x ) H(p) = -\sum_x p(x) \log_2 p(x) H ( p ) = − ∑ x p ( x ) log 2 p ( x )
衡量它的「平均信息量」——按 p p p 自身最优地编码时,平均每个事件需要多少 bit (连续分布的对应物是积分形式 − ∫ p ( x ) log 2 p ( x ) d x -\int p(x) \log_2 p(x)\, dx − ∫ p ( x ) log 2 p ( x ) d x ,称为微分熵 ,本文不展开)。交叉熵 (cross-entropy)把两个离散分布交叉起来:
H ( p , q ) = − ∑ x p ( x ) log 2 q ( x ) . H(p, q) = -\sum_x p(x) \log_2 q(x). H ( p , q ) = − ∑ x p ( x ) log 2 q ( x ) .
含义是「事件按真实分布 p p p 发生,但你用按 q q q 设计的编码去存——平均要花多少 bit」。「交叉 」就来自两个分布在公式里担任不同的角色 :p p p 在 log 外面当权重 、q q q 在 log 里面当对数的概率参数 。如果把它们对调位置——让 q q q 当权重、p p p 钻进 log 里——得到的是 H ( q , p ) = − ∑ x q ( x ) log 2 p ( x ) H(q, p) = -\sum_x q(x) \log_2 p(x) H ( q , p ) = − ∑ x q ( x ) log 2 p ( x ) ,一般跟原值不等;所以交叉熵不对称 :H ( p , q ) ≠ H ( q , p ) H(p, q) \neq H(q, p) H ( p , q ) = H ( q , p ) 。
回到分类损失:one-hot 真实标签 y y y 就是 p p p 、模型预测的 softmax 输出 y ^ \hat y y ^ 就是 q q q ,于是 − ∑ k y k log y ^ k = H ( p , q ) -\sum_k y_k \log \hat y_k = H(p, q) − ∑ k y k log y ^ k = H ( p , q ) ——分类的交叉熵损失正好是「真实标签分布与模型预测分布之间的交叉熵」。最小化交叉熵 = 把 q q q 推向 p p p ;与之等价的写法是最小化 KL 散度 D K L ( p ∥ q ) = H ( p , q ) − H ( p ) D_{KL}(p \| q) = H(p, q) - H(p) D K L ( p ∥ q ) = H ( p , q ) − H ( p ) ,二者只差一个仅由数据本身决定的常数 H ( p ) H(p) H ( p ) 。
⚙️ 底数的选择只影响单位、不影响最小化结果 :log 2 \log_2 log 2 → bit、自然对数 ln \ln ln → nat、log 10 \log_{10} log 10 → ban,三者只差常数因子。机器学习实现(PyTorch、TensorFlow 的 cross-entropy)实际用的是自然对数 ln \ln ln ——求导简单、与 MLE 的负对数似然直接对应,单位是 nat 而非 bit。所以本文 §3.1 上半段从 MLE 推出来的「− ∑ k y k log y ^ k -\sum_k y_k \log \hat y_k − ∑ k y k log y ^ k 」里的 log \log log 在工程上就是 ln \ln ln ;最优参数 θ \theta θ 与用 log 2 \log_2 log 2 得到的完全相同。
交叉熵也不是凭空——它是「分类输出服从伯努利 / 多项式分布」假设下的 MLE 直接产物 。两条损失共享同一个底层逻辑:负对数似然。
最后多说一句 KL 散度 (Kullback & Leibler 1951,又叫相对熵 )。它原本是数理统计里刻画「两个假设分布有多容易区分」的工具:非负 (Gibbs 不等式 ,D K L ( p ∥ q ) = 0 D_{KL}(p \| q) = 0 D K L ( p ∥ q ) = 0 当且仅当 p = q p = q p = q 几乎处处相等)、跟交叉熵一样不对称 ,常被解读为「用 q q q 近似 p p p 时的信息损失」。除了分类训练里跟交叉熵的隐含联系,深度学习里它还有几个常见落地:
变分自编码器 (VAE) :损失里 D K L ( q ( z ∣ x ) ∥ p ( z ) ) D_{KL}(q(z \mid x) \| p(z)) D K L ( q ( z ∣ x ) ∥ p ( z )) 把编码器输出的隐变量分布拉向先验,让隐空间结构化、可采样。
强化学习(PPO / TRPO) :每步策略更新时约束 D K L ( π new ∥ π old ) D_{KL}(\pi_\text{new} \| \pi_\text{old}) D K L ( π new ∥ π old ) 不要太大,防止策略一次性剧变。
知识蒸馏 :最小化 D K L ( p student ∥ p teacher ) D_{KL}(p_\text{student} \| p_\text{teacher}) D K L ( p student ∥ p teacher ) ,让学生模型对每个输入的输出分布尽量贴近教师。
p p p 在训练中固定时(分类问题就是这样),最小化交叉熵等于最小化 KL;但 p p p 也是模型一部分的场景(如 VAE 的先验项)必须用完整的 KL 。
3.4 反向传播:计算图、链式法则、雅可比
§ 3.1 把反向传播定位成「算梯度的算法」。反向传播本身不是新的求导规则 ——它做的全部事情是「把链式法则按计算图反向拓扑顺序套用一遍」。本节介绍计算图、雅可比矩阵、链积形式,以及它们在张量、矩阵、深度网络层结构上的具体写法。
计算图与局部偏导 。现代深度学习框架(PyTorch / TensorFlow / JAX)的底层抽象都是计算图 ——把一次前向计算拆成一张有向无环图(DAG),节点是所有变量 (含输入、参数 W W W 和 b b b 、中间量、输出),边表示计算依赖、携带从父节点到子节点的局部偏导 。注意这跟 § 1.1 / § 2.1 的「网络结构图」不一样:那种图里权重是边 (神经元之间的加权连接),而这里的计算图里权重是节点 ,连接它和下游中间量的边携带的是局部偏导 ∂ z / ∂ W \partial z / \partial W ∂ z / ∂ W 、不是权重本身。
以最简单的回归损失 L = ( σ ( W x + b ) − y ) 2 L = (\sigma(W x + b) - y)^2 L = ( σ ( W x + b ) − y ) 2 为例,把它拆成中间变量 z = W x + b z = W x + b z = W x + b 、a = σ ( z ) a = \sigma(z) a = σ ( z ) 、L = ( a − y ) 2 L = (a - y)^2 L = ( a − y ) 2 ,对应的计算图是:
graph LR
x((x)) --> z[z]
W((W)) --> z
b((b)) --> z
z --> a[a]
a --> diff["a - y"]
y((y)) --> diff
diff --> L[L]
每条边都对应一个局部偏导 :∂ z / ∂ W = x T \partial z / \partial W = x^T ∂ z / ∂ W = x T 、∂ a / ∂ z = σ ′ ( z ) \partial a / \partial z = \sigma'(z) ∂ a / ∂ z = σ ′ ( z ) 、∂ L / ∂ a = 2 ( a − y ) \partial L / \partial a = 2(a - y) ∂ L / ∂ a = 2 ( a − y ) ,等等。要算 ∂ L / ∂ W \partial L / \partial W ∂ L / ∂ W ,把 L → a → z → W L \to a \to z \to W L → a → z → W 这条路径上的所有局部偏导按链式法则乘起来:
∂ L ∂ W = ∂ L ∂ a ⋅ ∂ a ∂ z ⋅ ∂ z ∂ W = 2 ( a − y ) ⋅ σ ′ ( z ) ⋅ x T . \frac{\partial L}{\partial W} = \frac{\partial L}{\partial a} \cdot \frac{\partial a}{\partial z} \cdot \frac{\partial z}{\partial W} = 2(a - y) \cdot \sigma'(z) \cdot x^T. ∂ W ∂ L = ∂ a ∂ L ⋅ ∂ z ∂ a ⋅ ∂ W ∂ z = 2 ( a − y ) ⋅ σ ′ ( z ) ⋅ x T .
反向传播不是新的求导规则——它是把链式法则按图的反向拓扑顺序、用局部偏导组合得到 。任何能写成 DAG 的函数都可这样求导,框架要做的只是记住每条边对应的局部偏导算子。
雅可比矩阵 。当某一层是向量到向量的映射时,「局部偏导」就是雅可比矩阵 :若 f : R n → R m f: \mathbb{R}^n \to \mathbb{R}^m f : R n → R m ,则 ∂ f / ∂ x ∈ R m × n \partial f / \partial x \in \mathbb{R}^{m \times n} ∂ f / ∂ x ∈ R m × n ,其第 ( i , j ) (i, j) ( i , j ) 元素是 ∂ f i / ∂ x j \partial f_i / \partial x_j ∂ f i / ∂ x j 。神经网络中常见三类层的 Jacobian:
线性层 y = W x + b y = W x + b y = W x + b (y ∈ R m y \in \mathbb{R}^m y ∈ R m ,x ∈ R n x \in \mathbb{R}^n x ∈ R n ,W ∈ R m × n W \in \mathbb{R}^{m \times n} W ∈ R m × n ):∂ y / ∂ x = W \partial y / \partial x = W ∂ y / ∂ x = W ;对参数 W W W 的偏导按元素写为 ∂ y i / ∂ W i j = x j \partial y_i / \partial W_{ij} = x_j ∂ y i / ∂ W ij = x j 。
激活层 y = σ ( x ) y = \sigma(x) y = σ ( x ) (element-wise):∂ y / ∂ x = d i a g ( σ ′ ( x ) ) \partial y / \partial x = \mathrm{diag}(\sigma'(x)) ∂ y / ∂ x = diag ( σ ′ ( x )) ,是一个对角矩阵。
损失层 L = ℓ ( y , y true ) L = \ell(y, y_{\text{true}}) L = ℓ ( y , y true ) (标量输出):∂ L / ∂ y ∈ R 1 × m \partial L / \partial y \in \mathbb{R}^{1 \times m} ∂ L / ∂ y ∈ R 1 × m ,是行向量。
element-wise 激活层的雅可比是对角阵——这一观察是 §4.1 分析「梯度链积」的关键 :对角矩阵的奇异值就是对角元素 σ ′ ( z i ) \sigma'(z_i) σ ′ ( z i ) 本身,整个链积的幅值由各层 σ ′ \sigma' σ ′ 一路相乘决定。
链积形式 。把整个反向传播写成一行:深度 L L L 处的损失对输入 x 0 x_0 x 0 的梯度可以写成所有层雅可比的链积:
∂ L ∂ x 0 = ∂ L ∂ x L ⋅ ∏ l = L 1 J l , J l = ∂ x l ∂ x l − 1 . \frac{\partial L}{\partial x_0} = \frac{\partial L}{\partial x_L} \cdot \prod_{l=L}^{1} J_l, \quad J_l = \frac{\partial x_l}{\partial x_{l-1}}. ∂ x 0 ∂ L = ∂ x L ∂ L ⋅ l = L ∏ 1 J l , J l = ∂ x l − 1 ∂ x l .
这条公式就是 §4 接下来要分析「梯度消失 / 爆炸」的出发点。
4. 训练稳定性:深层网络的生存之道
4.1 梯度消失与爆炸:谱半径视角
回到 § 2.4 的导数图,接 § 3.4 末尾的链积公式
∂ L ∂ x 0 = ∂ L ∂ x L ⋅ ∏ l = L 1 J l , J l = ∂ x l ∂ x l − 1 . \frac{\partial L}{\partial x_0} = \frac{\partial L}{\partial x_L} \cdot \prod_{l=L}^{1} J_l, \quad J_l = \frac{\partial x_l}{\partial x_{l-1}}. ∂ x 0 ∂ L = ∂ x L ∂ L ⋅ l = L ∏ 1 J l , J l = ∂ x l − 1 ∂ x l .
链积的幅值受每一层 J l J_l J l 对向量长度的缩放能力 支配。对一个矩阵 A A A ,最大奇异值 σ max ( A ) \sigma_{\max}(A) σ m a x ( A ) 给出它把单位长度向量拉得最长的倍数——精确地说,对任何向量 v v v 都有
∥ A v ∥ 2 ≤ σ max ( A ) ⋅ ∥ v ∥ 2 , \|A v\|_2 \;\le\; \sigma_{\max}(A) \cdot \|v\|_2, ∥ A v ∥ 2 ≤ σ m a x ( A ) ⋅ ∥ v ∥ 2 ,
而且等号在 v v v 取 A A A 的最长方向时取到。所以如果每层 σ max ( J l ) \sigma_{\max}(J_l) σ m a x ( J l ) 都 < 1 < 1 < 1 ,链积把梯度幅值越乘越小;都 > 1 > 1 > 1 则指数级放大。
方阵情形下还常用 谱半径 ρ ( J ) = max i ∣ λ i ( J ) ∣ \rho(J) = \max_i \lvert \lambda_i(J) \rvert ρ ( J ) = max i ∣ λ i ( J )∣ (特征值绝对值的最大者)描述迭代意义下的渐近缩放——非对称矩阵下有 ρ ( J ) ≤ σ max ( J ) \rho(J) \le \sigma_{\max}(J) ρ ( J ) ≤ σ m a x ( J ) ,二者在工程语境里常被混用作「该变换的有效缩放因子」。下文用 ρ ˉ \bar\rho ρ ˉ 表示每层 J l J_l J l 的平均缩放因子(取奇异值或谱半径都可以)。
设每层 J l J_l J l 的平均缩放因子为 ρ ˉ \bar\rho ρ ˉ ,链积的幅值近似正比于 ρ ˉ L \bar\rho^L ρ ˉ L 。两个极端:
ρ ˉ < 1 \bar\rho < 1 ρ ˉ < 1 :链积指数衰减——梯度消失 ,靠近输入的层几乎收不到梯度信号。
ρ ˉ > 1 \bar\rho > 1 ρ ˉ > 1 :链积指数放大——梯度爆炸 ,数值上溢、优化失败。
消失和爆炸的失败机制略有不同。消失时训练表面还在跑、损失也在降,但靠近输入的层几乎不更新 ——深层网络等于退化成只训练后几层的浅层模型,泛化能力受限。
爆炸更暴力。一旦梯度某个分量超过 float32 上限(约 3.4 × 10 38 3.4 \times 10^{38} 3.4 × 1 0 38 )就变成 inf;后续 inf - inf / 0 * inf / inf / inf 这类运算又产生 NaN,而 NaN 在 IEEE 754 里是吸收性的——任何包含它的算术都返回 NaN。NaN 一旦进入某个参数,下一次前向时整张激活图都变成 NaN、损失变 NaN、所有梯度都是 NaN、所有参数被更新成 NaN——训练彻底死掉、无法恢复 。
即便没到 inf,一次过大的步长 η ∇ L \eta \nabla L η ∇ L 也会让参数跳到损失景观完全陌生的区域、轨迹发散。工程上的对症方案是 gradient clipping :检测到 ∥ ∇ L ∥ > τ \|\nabla L\| > \tau ∥∇ L ∥ > τ 时按比例缩到 τ \tau τ ,宁可走慢也不让单次步长爆掉 ;RNN / Transformer 训练里几乎是标配。
以 Sigmoid 为例算个具体数字:它的导数 σ ′ ( z ) = σ ( z ) ( 1 − σ ( z ) ) \sigma'(z) = \sigma(z)(1 - \sigma(z)) σ ′ ( z ) = σ ( z ) ( 1 − σ ( z )) 是钟形曲线,最大值 0.25 0.25 0.25 在 z = 0 z = 0 z = 0 处取到,偏离 0 时 σ ′ \sigma' σ ′ 迅速减小。所以即便在「最理想的位置」(z ≈ 0 z \approx 0 z ≈ 0 ),一层 ρ ˉ \bar\rho ρ ˉ 顶多也只到 0.25 0.25 0.25 ;权重未做特殊初始化时实际更低,10 层链积上界约为 0.25 10 ≈ 10 − 6 0.25^{10} \approx 10^{-6} 0.2 5 10 ≈ 1 0 − 6 ——梯度几乎完全归零 。
5 1 15 2 深度 L 0 1 2 3 4 5 链积 ρ^L sigmoid' 链积 (0.25)^L tanh' 近饱和 (0.9)^L ReLU' 正区 (1.0)^L 爆炸 ρ=1.2 梯度链积 ρ^L 随深度的变化
注意 ρ = 1.2 \rho = 1.2 ρ = 1.2 的曲线在 L ≈ 9 L \approx 9 L ≈ 9 之后冲出图外——这就是「爆炸」的字面意思。梯度问题的本质不是「网络深」,而是「Jacobian 链积的谱半径不在 1 附近」 。这就把问题从「网络架构选择」转到「让每一层的 J l J_l J l 谱半径保持在 1 附近」这个工程任务上。下面 4.2 / 4.3 两节就是它的两条解法。
4.2 权重初始化:Xavier 与 He 的方差齐性推导
Xavier 初始化 (Glorot & Bengio 2010)的核心想法是让每层 forward / backward 时各分量的方差与上一层相同 ——链积的谱半径自然贴近 1。
为什么「方差齐性」能让谱半径贴近 1?两步:方差保持 意味着每层平均不放大也不缩小向量长度的平方;**随机矩阵理论的 Marchenko–Pastur 定律 **告诉我们,iid 元素、方差 σ w 2 \sigma_w^2 σ w 2 、规模 m × n m \times n m × n 的随机矩阵,奇异值集中在 σ w n \sigma_w \sqrt{n} σ w n 附近。代入下文 Xavier 前向方程的解 σ w 2 = 1 / n \sigma_w^2 = 1/n σ w 2 = 1/ n ,奇异值 ≈ 1 / n ⋅ n = 1 \approx \sqrt{1/n} \cdot \sqrt{n} = 1 ≈ 1/ n ⋅ n = 1 ,谱半径 ρ ≈ 1 \rho \approx 1 ρ ≈ 1 。方差齐性其实是「让每层 Jacobian 的奇异值集中在 1 附近」的工程化代理 ——直接控制方差比直接做 SVD 控制奇异值容易得多(采样权重时控制方差是 O ( 1 ) O(1) O ( 1 ) 的事;做 SVD 是 O ( n 3 ) O(n^3) O ( n 3 ) )。
假设:输入 x x x 各维独立同分布、零均值、方差 σ x 2 \sigma_x^2 σ x 2 ;权重 W ∈ R m × n W \in \mathbb{R}^{m \times n} W ∈ R m × n 各元素独立、零均值、方差 σ w 2 \sigma_w^2 σ w 2 ;激活近似线性(小输入区,对 tanh 在 0 附近成立)。符号约定 :W W W 把 n n n 维输入映到 m m m 维输出,所以每个输出神经元接收 n n n 个输入——称为 fan-in = n = n = n (W W W 的列数);每个输入被分发到 m m m 个输出——称为 fan-out = m = m = m (W W W 的行数)。两个词借自电路术语:扇形进来的端口数(fan-in)与扇形出去的端口数(fan-out)。
前向方差 :对线性层 z j = ∑ k = 1 n W j k x k z_j = \sum_{k=1}^{n} W_{jk} x_k z j = ∑ k = 1 n W j k x k ,
V a r ( z j ) = ∑ k = 1 n V a r ( W j k x k ) = ∑ k = 1 n V a r ( W j k ) ⋅ V a r ( x k ) = n ⋅ σ w 2 ⋅ σ x 2 . \begin{aligned}
\mathrm{Var}(z_j)
&= \sum_{k=1}^{n} \mathrm{Var}(W_{jk} x_k) \\
&= \sum_{k=1}^{n} \mathrm{Var}(W_{jk}) \cdot \mathrm{Var}(x_k) \\
&= n \cdot \sigma_w^2 \cdot \sigma_x^2.
\end{aligned} Var ( z j ) = k = 1 ∑ n Var ( W j k x k ) = k = 1 ∑ n Var ( W j k ) ⋅ Var ( x k ) = n ⋅ σ w 2 ⋅ σ x 2 .
要保持 V a r ( z ) = V a r ( x ) \mathrm{Var}(z) = \mathrm{Var}(x) Var ( z ) = Var ( x ) ,需要 σ w 2 = 1 / n \sigma_w^2 = 1 / n σ w 2 = 1/ n (n n n 是 fan-in)。
反向方差 :反向传播的梯度 g j = ∑ i = 1 m W i j g i (out) g_j = \sum_{i=1}^{m} W_{ij} g_i^{\text{(out)}} g j = ∑ i = 1 m W ij g i (out) (m m m 是 fan-out),
V a r ( g j ) = m ⋅ σ w 2 ⋅ V a r ( g (out) ) . \mathrm{Var}(g_j) = m \cdot \sigma_w^2 \cdot \mathrm{Var}(g^{\text{(out)}}). Var ( g j ) = m ⋅ σ w 2 ⋅ Var ( g (out) ) .
要保持反向方差不变,需要 σ w 2 = 1 / m \sigma_w^2 = 1 / m σ w 2 = 1/ m 。前向与反向无法同时严格满足,Xavier 取调和折衷:
σ w 2 = 2 n + m . \sigma_w^2 = \frac{2}{n + m}. σ w 2 = n + m 2 .
He 初始化 (He et al. 2015)针对 ReLU 做了一处修正:ReLU 把负半区直接清零,实际激活的样本只有一半,所以前向方差变为 V a r ( z ) = 1 2 n σ w 2 σ x 2 \mathrm{Var}(z) = \tfrac{1}{2} n \sigma_w^2 \sigma_x^2 Var ( z ) = 2 1 n σ w 2 σ x 2 。要保持方差不变得:
σ w 2 = 2 n . \sigma_w^2 = \frac{2}{n}. σ w 2 = n 2 .
Xavier 与 He 的差别不在 σ x 2 \sigma_x^2 σ x 2 的选择,而在「ReLU 砍掉一半激活」这一条物理假设——后者把因子 2 推回到分子 。工程上对 sigmoid / tanh 网络用 Xavier、对 ReLU 系列用 He,几乎已是默认。
4.3 归一化:BatchNorm 与 LayerNorm 的数学本质
权重初始化只在 t = 0 t = 0 t = 0 时让 ρ ˉ ≈ 1 \bar\rho \approx 1 ρ ˉ ≈ 1 成立;训练过程中权重会漂移、激活分布会偏移、谱半径会脱离 1。归一化(Normalization)层的目的就是在每一层强制把激活拉回零均值、单位方差的分布 ,让 σ ′ \sigma' σ ′ 始终落在「敏感区」附近。
Batch Normalization (简称 BN) 在 mini-batch 维度做归一化。对一个 batch { x ( 1 ) , … , x ( B ) } \{x^{(1)}, \dots, x^{(B)}\} { x ( 1 ) , … , x ( B ) } 的某通道 / 神经元 j j j :
μ j = 1 B ∑ i = 1 B x j ( i ) , σ j 2 = 1 B ∑ i = 1 B ( x j ( i ) − μ j ) 2 , x ^ j ( i ) = x j ( i ) − μ j σ j 2 + ϵ , y j ( i ) = γ j x ^ j ( i ) + β j . \begin{aligned}
\mu_j &= \frac{1}{B} \sum_{i=1}^{B} x_j^{(i)}, \\
\sigma_j^2 &= \frac{1}{B} \sum_{i=1}^{B} (x_j^{(i)} - \mu_j)^2, \\
\hat x_j^{(i)} &= \frac{x_j^{(i)} - \mu_j}{\sqrt{\sigma_j^2 + \epsilon}}, \\
y_j^{(i)} &= \gamma_j \hat x_j^{(i)} + \beta_j.
\end{aligned} μ j σ j 2 x ^ j ( i ) y j ( i ) = B 1 i = 1 ∑ B x j ( i ) , = B 1 i = 1 ∑ B ( x j ( i ) − μ j ) 2 , = σ j 2 + ϵ x j ( i ) − μ j , = γ j x ^ j ( i ) + β j .
最后的 affine 参数 γ j , β j \gamma_j, \beta_j γ j , β j 可学习,避免归一化把网络的表达能力锁死 ——如果某层确实需要非零均值或非单位方差的输出,模型可以通过 γ , β \gamma, \beta γ , β 学回去。
⚙️ 实际架构中线性层的 b b b 经常被关掉 :ResNet 的卷积层默认 bias=False;LLaMA / PaLM 的 FFN 与 Q / K / V projection 也都 bias-free。原因是这些线性层后面紧接 BN / LN,归一化层的 β \beta β 已经提供了同样的 shift 自由度 ,再保留 b b b 只是冗余参数——增加参数量但不增加表达能力。所以「Linear + BN + ReLU」这种现代组合里把 b b b 关掉是 PyTorch 实现里的默认配置。
⚙️ 实际实现的取舍 :BatchNorm 训练时用 batch statistics μ j , σ j 2 \mu_j, \sigma_j^2 μ j , σ j 2 ,推断时若仍用 batch 统计就会导致同一个输入在不同 batch 下输出不同。PyTorch / TensorFlow 的实现——训练时同时维护 μ , σ 2 \mu, \sigma^2 μ , σ 2 的滑动平均(running statistics),推断时切换为滑动平均值 。这一切换让 BatchNorm 的训练-推断行为天然不对称,是它在小 batch、变长输入、RNN / Transformer 等场景翻车的根本原因。实际工程上 RNN / Transformer 改用下文的 LayerNorm;现代 LLM(LLaMA、Mistral、Gemma 等)进一步简化为 RMSNorm ——去掉减均值、只用 root-mean-square 归一 。
Layer Normalization (简称 LN) 改成在单个样本的所有维度上做归一化,与 batch size 无关:
μ = 1 n ∑ j = 1 n x j , σ 2 = 1 n ∑ j = 1 n ( x j − μ ) 2 , x ^ j = x j − μ σ 2 + ϵ . \mu = \frac{1}{n}\sum_{j=1}^{n} x_j, \quad \sigma^2 = \frac{1}{n}\sum_{j=1}^{n}(x_j - \mu)^2, \quad \hat x_j = \frac{x_j - \mu}{\sqrt{\sigma^2 + \epsilon}}. μ = n 1 j = 1 ∑ n x j , σ 2 = n 1 j = 1 ∑ n ( x j − μ ) 2 , x ^ j = σ 2 + ϵ x j − μ .
LayerNorm 与 batch 解耦,对 Transformer 这种 batch 内样本序列长度差异大的架构特别友好——这是它在 NLP 与现代 LLM 中几乎完全取代 BatchNorm 的工程原因 。
回到 § 4.1 的视角:归一化让每层激活分布固定在零均值、单位方差,相当于把激活强行钉回 σ ′ \sigma' σ ′ 大致恒定的「敏感区」。归一化的真实目标不是「分布稳定」这种含糊话,而是「保持激活分布在 σ ′ \sigma' σ ′ 接近常数的区间,使 Jacobian 链积的谱半径不漂移」 。
5. 泛化与正则化:拟合之后的思考
5.1 偏差-方差权衡
到这里所有讨论都集中在「训练能不能收敛」上。但训练损失低不等于模型有用——真正的目标是在新样本上的泛化误差 。给定输入 x 0 x_0 x 0 、真实标签 y 0 y_0 y 0 与训练集 D D D ,定义模型预测 y ^ ( x 0 ; D ) \hat y(x_0; D) y ^ ( x 0 ; D ) ,则任意点 x 0 x_0 x 0 处的期望 MSE 可以分解:
E D [ ( y ^ ( x 0 ; D ) − y 0 ) 2 ] = E D [ ( y ^ − y ^ ˉ ) 2 ] + ( y ^ ˉ − f ( x 0 ) ) 2 + σ ϵ 2 = V a r D [ y ^ ( x 0 ; D ) ] ⏟ 方差 + ( E D [ y ^ ( x 0 ; D ) ] − f ( x 0 ) ) 2 ⏟ 偏差 2 + σ ϵ 2 ⏟ 噪声 , \begin{aligned}
\mathbb{E}_D\!\left[(\hat y(x_0; D) - y_0)^2\right]
&= \mathbb{E}_D\!\left[(\hat y - \bar{\hat y})^2\right]
+ (\bar{\hat y} - f(x_0))^2
+ \sigma_\epsilon^2 \\
&= \underbrace{\mathrm{Var}_D[\hat y(x_0; D)]}_{\text{方差}}
+ \underbrace{(\mathbb{E}_D[\hat y(x_0; D)] - f(x_0))^2}_{\text{偏差}^2}
+ \underbrace{\sigma_\epsilon^2}_{\text{噪声}},
\end{aligned} E D [ ( y ^ ( x 0 ; D ) − y 0 ) 2 ] = E D [ ( y ^ − y ^ ˉ ) 2 ] + ( y ^ ˉ − f ( x 0 ) ) 2 + σ ϵ 2 = 方差 Var D [ y ^ ( x 0 ; D )] + 偏差 2 ( E D [ y ^ ( x 0 ; D )] − f ( x 0 ) ) 2 + 噪声 σ ϵ 2 ,
其中 y ^ ˉ = E D [ y ^ ( x 0 ; D ) ] \bar{\hat y} = \mathbb{E}_D[\hat y(x_0; D)] y ^ ˉ = E D [ y ^ ( x 0 ; D )] ,f ( x 0 ) f(x_0) f ( x 0 ) 是真实条件期望,σ ϵ 2 \sigma_\epsilon^2 σ ϵ 2 是不可约的标签噪声。
三项的对抗关系:模型容量越大,能拟合的 f f f 越复杂 → 偏差越小;但容量大也意味着对训练样本细节越敏感 → 方差越大。偏差-方差权衡 的本质是:模型容量是偏差的敌人也是方差的盟友,总误差的最优点出现在两者交叉之处 。
实际中,神经网络的双下降(double descent) 现象表明 bias-variance 经典图景在过参数化区域并不完整(Belkin et al. 2019 、Nakkiran et al. 2020 给出了系统性证据)。把神经网络的宽度 / 参数量从小到大扫一遍画测试误差,曲线不是经典的 U 形,而是「降 → 升 → 降 」:
容量较小时按经典 U 形先降到一个经典最优点;
容量继续增加、方差主导,测试误差上升 ;
在插值阈值 (interpolation threshold,模型容量刚好能完美记住整个训练集、训练误差 ≈ 0 \approx 0 ≈ 0 的临界点)附近,测试误差冲到一个峰值;
容量继续增加进入过参数化区域 (参数量 ≫ \gg ≫ 训练样本数),测试误差再次下降 ,最终值常常低于经典最优点。
这条「降 → 升 → 降」的曲线直接打破了经典 bias-variance「容量越大、方差越大、再加大必然过拟合」的预测——在过参数化区域继续加大模型反而泛化更好 ,这正是现代深度学习(GPT、LLaMA 等大模型)能靠堆参数取得好性能的实证基础。
学术界对成因尚无完全共识,常见的三条候选解释:
SGD 在过参数化区域的隐式正则化 :满足训练集的解有无穷多组,SGD 倾向找范数最小 的那组,等价于一种自动正则化。
Neural Tangent Kernel (NTK)视角 :当网络足够宽时,训练动力学接近一个确定性的核方法,其方差性质跟有限宽的经典模型不同。
lottery ticket 假说 :大网络里藏着稀疏「中奖票」子网络,训练自动选中它、对其余参数不依赖。
模型规模适中时(参数量与训练样本同量级或更少)经典 bias-variance 仍然成立,双下降只在过参数化区域才显现 ;作为基础视角和正则化设计的指导,经典图景仍是后两节讨论 L1 / L2 / Dropout 的出发点。
5.2 L2 / L1 正则化的贝叶斯本质
最朴素的对抗过拟合手段就是在损失函数里加一项「让权重不要太大」。下文用 N L L ( θ ) \mathrm{NLL}(\theta) NLL ( θ ) 表示负对数似然 (negative log-likelihood,即 − log p ( D ∣ θ ) -\log p(D \mid \theta) − log p ( D ∣ θ ) )——§ 3.3 从 MLE 推 MSE 与交叉熵时最小化的就是它,深度学习里几乎所有「损失函数」本质上都是某种 NLL。常见两种正则化形式:
L L2 ( θ ) = N L L ( θ ) + λ ∥ θ ∥ 2 2 , L L1 ( θ ) = N L L ( θ ) + λ ∥ θ ∥ 1 . L_{\text{L2}}(\theta) = \mathrm{NLL}(\theta) + \lambda \|\theta\|_2^2, \qquad L_{\text{L1}}(\theta) = \mathrm{NLL}(\theta) + \lambda \|\theta\|_1. L L2 ( θ ) = NLL ( θ ) + λ ∥ θ ∥ 2 2 , L L1 ( θ ) = NLL ( θ ) + λ ∥ θ ∥ 1 .
这两条正则化项在贝叶斯框架下都有非常自然的解释:它们分别是对参数加上不同先验后的 MAP(最大后验)估计 。
L2 ↔ 高斯先验 :假设参数 θ \theta θ 服从各向同性高斯先验 θ ∼ N ( 0 , τ 2 I ) \theta \sim \mathcal{N}(0, \tau^2 I) θ ∼ N ( 0 , τ 2 I ) 。给定数据 D D D ,后验对数为
log p ( θ ∣ D ) ∝ log p ( D ∣ θ ) + log p ( θ ) = − N L L ( θ ) − 1 2 τ 2 ∥ θ ∥ 2 2 + const . \begin{aligned}
\log p(\theta \mid D)
&\propto \log p(D \mid \theta) + \log p(\theta) \\
&= -\mathrm{NLL}(\theta) - \frac{1}{2\tau^2}\|\theta\|_2^2 + \text{const}.
\end{aligned} log p ( θ ∣ D ) ∝ log p ( D ∣ θ ) + log p ( θ ) = − NLL ( θ ) − 2 τ 2 1 ∥ θ ∥ 2 2 + const .
最大化后验等价于最小化 N L L ( θ ) + 1 2 τ 2 ∥ θ ∥ 2 2 \mathrm{NLL}(\theta) + \frac{1}{2\tau^2}\|\theta\|_2^2 NLL ( θ ) + 2 τ 2 1 ∥ θ ∥ 2 2 ——令 λ = 1 / ( 2 τ 2 ) \lambda = 1 / (2 \tau^2) λ = 1/ ( 2 τ 2 ) 即得 L2(岭回归) 。L2 正则化 = 高斯先验下的 MAP 估计——「权重不要太大」其实是「权重的先验集中在 0 附近」的等价表述 。
需要补一条工程实践:∥ θ ∥ 2 2 \|\theta\|_2^2 ∥ θ ∥ 2 2 在实际中通常只对权重生效、不对 bias 生效 ——PyTorch 的 weight_decay 默认会把 bias 也一起衰减,但教材与实战指南普遍建议显式排除 bias。这与「bias 应保留自由平移的能力」的直觉一致;在 § 4.3 提到的 bias-free 现代架构里这条要求自动满足。
L1 ↔ 拉普拉斯先验 :换成拉普拉斯先验 θ j ∼ L a p l a c e ( 0 , b ) \theta_j \sim \mathrm{Laplace}(0, b) θ j ∼ Laplace ( 0 , b ) ,密度 ∝ exp ( − ∣ θ j ∣ / b ) \propto \exp(-|\theta_j| / b) ∝ exp ( − ∣ θ j ∣/ b ) 。后验对数为
log p ( θ ∣ D ) ∝ − N L L ( θ ) − 1 b ∑ j ∣ θ j ∣ + const , \log p(\theta \mid D) \propto -\mathrm{NLL}(\theta) - \frac{1}{b}\sum_j |\theta_j| + \text{const}, log p ( θ ∣ D ) ∝ − NLL ( θ ) − b 1 j ∑ ∣ θ j ∣ + const ,
最大化对应最小化 N L L + λ ∥ θ ∥ 1 \mathrm{NLL} + \lambda \|\theta\|_1 NLL + λ ∥ θ ∥ 1 (λ = 1 / b \lambda = 1 / b λ = 1/ b )。L1(Lasso) 正则化 = 拉普拉斯先验下的 MAP 估计——选择拉普拉斯而非高斯就引入了稀疏性 。
为什么 L1 会带来稀疏(许多 θ j \theta_j θ j 恰好等于 0),L2 不会?关键在两个先验在 0 处的形状:高斯密度在 0 处光滑(一阶导为 0),拉普拉斯密度在 0 处有「尖峰」(一阶导有跳变)。把后者的负对数当作罚项 ∣ θ j ∣ |\theta_j| ∣ θ j ∣ ,目标函数在 θ j = 0 \theta_j = 0 θ j = 0 处有「角点」(非光滑),最优解倾向于把分量精确推到 0;而高斯的负对数是光滑的 θ j 2 \theta_j^2 θ j 2 ,最优解只会压小分量但不会压到 0。L1 的稀疏性不是巧合——它直接来自拉普拉斯先验密度在 0 处的非光滑性 。
5.3 Dropout 的集成视角
Dropout (Srivastava et al. 2014)的操作极简:训练时每个神经元以概率 p p p 被独立置零(mask),推断时不 dropout 但把激活乘以 ( 1 − p ) (1 - p) ( 1 − p ) 做尺度补偿。问题是这个看上去像「随机噪声注入」的操作,为什么对泛化能力有这么大帮助?
答案是它在数学上等价于一种巨型集成。考虑一个有 n n n 个隐神经元的网络。每个 mini-batch 上随机 mask 出现 2 n 2^n 2 n 种可能的子网络(每个神经元 0 或 1),每个子网络在那一步上独立训练(共享底层权重)。Dropout 不是简单的随机噪声——它在每个 batch 上训练一个不同的子网络,整体形成最多 2 n 2^n 2 n 个子网络的隐式 ensemble 。
推断时不再 dropout,每个激活乘以 ( 1 − p ) (1 - p) ( 1 − p ) ——这步操作对 softmax 输出层精确等价于 2 n 2^n 2 n 个子网络概率输出的归一化几何平均 。推导核心:每个 mask 下第 k k k 类 logit z k ( m ) = W k ⋅ ( m ⊙ h ) z_k(m) = W_k \cdot (m \odot h) z k ( m ) = W k ⋅ ( m ⊙ h ) 是 m m m 的线性函数,由期望线性性得 E m [ z k ( m ) ] = ( 1 − p ) ⋅ W k ⋅ h \mathbb{E}_m[z_k(m)] = (1 - p) \cdot W_k \cdot h E m [ z k ( m )] = ( 1 − p ) ⋅ W k ⋅ h ——正是推断时 ( 1 − p ) (1 - p) ( 1 − p ) scaling 给出的 logit 。把它代进 softmax,再用恒等式 e E m [ z ] = ∏ m e P ( m ) z ( m ) e^{\mathbb{E}_m[z]} = \prod_m e^{P(m) z(m)} e E m [ z ] = ∏ m e P ( m ) z ( m ) ,分子分母里 exp 的期望就展成 exp 的乘积,归一化后正是子网络 softmax 输出 y ^ k ( m ) \hat y_k(m) y ^ k ( m ) 的(归一化)几何平均 ∏ m y ^ k ( m ) P ( m ) \prod_m \hat y_k(m)^{P(m)} ∏ m y ^ k ( m ) P ( m ) 。
「算术平均的 logit → 几何平均的概率」来自 softmax 的指数运算,是 AM-GM 等式 e z ˉ = ( ∏ e z i ) 1 / N e^{\bar z} = (\prod e^{z_i})^{1/N} e z ˉ = ( ∏ e z i ) 1/ N 的直接体现 :在 logit 空间做线性平均、经过 exp 就变成概率空间的乘法平均。非 softmax 输出(sigmoid 回归头、卷积里的 ReLU 等)下这条等价不再严格,但实证上 dropout 的「集成近似」在非线性深网络中依然有效。
工程上 dropout 在卷积网络与 MLP 上效果显著、在 Transformer 上常被替换为 stochastic depth / attention dropout。Dropout 的核心理论价值在于把「正则化」与「集成学习」串成了同一件事——这一视角也适用于 BatchNorm(batch 噪声)和 data augmentation(输入扰动) 。
6. 结语
把这五部分串起来看,本文其实在回答三个根问题:神经网络为什么能学(§ 1-2)、怎么学(§ 3)、深了为什么难学(§ 4-5) 。下面几条没在正文里直接强调、但用之前最好心里有数:
感知机的极限不是「线性」,而是「单层」 。XOR 在 1969 年就给过这个答案;后来的「神经网络寒冬」不是感知机不行,而是当时缺反向传播、缺算力、缺非线性激活的工程化方案。多层 + 非线性才把表达能力的天花板真正推开。
反向传播不是新算法,是「把链式法则按计算图反向拓扑排序后高效实现」 。VJP 是关键——没有 VJP,所有现代 AD 框架(PyTorch / JAX / Autograd)都不存在;反向模式 AD 在「内存换计算」上的特殊性也来自 VJP 而不是链式法则本身。
梯度问题不是「网络深」的诅咒,而是「谱半径」的诅咒 。Xavier / He 初始化、BatchNorm / LayerNorm 都在围绕同一件事:让 Jacobian 链积的 ρ ˉ ≈ 1 \bar\rho \approx 1 ρ ˉ ≈ 1 。后续的 residual connection(ResNet)、归一化与 attention 设计也都可以从「保持谱半径稳定」这个视角统一看待。
正则化的数学本质都是参数的贝叶斯先验 。L2 ↔ 高斯先验、L1 ↔ 拉普拉斯先验、Dropout ↔ 隐式 ensemble——它们是同一件事的不同工程化。新的正则化技术(label smoothing、mixup、weight averaging)只要找到对应的先验或集成结构,就能纳入同一条主线。
万能近似定理是表达能力定理,不是泛化定理 。「能逼近」≠「能学到」(这是优化问题)≠「在测试集上也能逼近」(这是泛化问题)。深度学习近十年的真正进步都集中在后两条上——优化算法、归一化、正则化、架构先验(CNN / attention / Transformer)共同构成「让 UAT 在实际数据上落地」的工程基础。