神经网络作为「端到端可学习的函数」已经是日常工具,但很多人对它「学习」过程的实际机制仍停留在「有反向传播」这一句话。这种黑箱视角在训练顺利时没问题;一旦遇到损失不下降、梯度爆炸、推断性能崩塌等异常,就完全没有抓手去定位问题。理解深度学习的底层原理不是为了重新发明 PyTorch,而是为了在模型不收敛或泛化失败时,知道往哪里看

这篇文章介绍深度学习最底层的数学骨架——从 1957 年 Rosenblatt 的感知机出发,一路推到现代深度网络可以稳定训练上百层的工程化基础。核心是三件事:用非线性激活把多个线性变换叠成「可表达任意函数」的结构、用链式法则把误差在计算图上反向传播、用方差控制与正则化让深层网络真正训练得动

本文按 § 1-5 顺序展开:单层感知机的数学表达与异或问题给出非线性的必要性(§ 1);多层感知机叠加 + 万能近似定理告诉我们非线性的足够性(§ 2);训练神经网络的基本流程——损失函数 + 梯度下降——把「能表达」落到「能学到」(§ 3);梯度消失 / 爆炸与初始化、归一化技术让训练在数十甚至上百层时仍然稳定(§ 4);最后从偏差-方差权衡到 L1 / L2 / Dropout 看「学到」与「泛化」之间的距离(§ 5)。

1. 感知机:线性模型的极限

1.1 感知机的数学表达

感知机由 Rosenblatt 在 1957 年提出,是历史上第一个可以从数据中学习参数的二分类模型。它的核心操作是把若干维输入加权求和,再过一个阶跃函数:

y  =  sign(wx+b),sign(z)={+1,z01,z<0y \;=\; \mathrm{sign}(w \cdot x + b), \qquad \mathrm{sign}(z) = \begin{cases} +1, & z \ge 0 \\ -1, & z < 0 \end{cases}

这里 xRnx \in \mathbb{R}^n 是输入向量,wRnw \in \mathbb{R}^n 是权重向量、bRb \in \mathbb{R} 是偏置,输出 y{1,+1}y \in \{-1, +1\} 是分类标签。从几何上看,决策边界 wx+b=0w \cdot x + b = 0Rn\mathbb{R}^n 中的一个超平面。感知机本质上是「找一个能把两类数据分开的超平面」的模型

graph LR
  x1((x1)) -->|w1| S["Σ + b"]
  x2((x2)) -->|w2| S
  xn((xn)) -->|wn| S
  S --> step["sign·"]
  step --> y((y))

学习算法本身极简——但要看清楚,需要先把后面要用到的符号一次列清:

符号含义类型
wRnw \in \mathbb{R}^n权重向量参数
bRb \in \mathbb{R}偏置标量参数
xiRnx_i \in \mathbb{R}^nii 个样本的输入数据
yi{1,+1}y_i \in \{-1, +1\}ii 个样本的标签数据
η>0\eta > 0学习率(learning rate),每步更新的步长超参数
\leftarrow赋值(用右值覆盖左值)操作符

wwbb 都是要学的参数,η\eta 是人工选的超参数;缺了 bb,决策超平面就被锁在「过原点」的位置,无法做到超平面的平移

完整的训练循环是:

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                             # 一整轮无更新,收敛

只有误分类的点触发更新,正确分类的点跳过——这是感知机和后来的梯度下降在「更新触发条件」上的关键区别。误分类的紧凑判据是 yi(wxi+b)0y_i (w \cdot x_i + b) \le 0:真实标签与预测分数符号相反(或分数恰好为 0)。

为什么更新方向是 +ηyixi+\eta y_i x_i 而不是别的?设某点 (xi,yi)(x_i, y_i) 被误分类。更新后再算一次它的分数:

wnewxi+bnew=(w+ηyixi)xi+(b+ηyi)=(wxi+b)+ηyi(xi2+1)=旧分数+ηyi(xi2+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}

η>0\eta > 0xi2+1>0\|x_i\|^2 + 1 > 0,所以「新分数」相对「旧分数」沿 yiy_i 的方向严格挪了一段:yi=+1y_i = +1 时变大、yi=1y_i = -1 时变小,两种情形都朝着「下一次能预测对」的方向走。yiy_i 既是「我希望分数往哪边走」的信号,也是让更新方向自动随标签反向的乘子;如果把它去掉、固定写成 +ηxi+\eta x_i,对负样本就会越走越错

具体跑一步:取 η=1\eta = 1,初始 w=(0,0),b=0w = (0, 0), b = 0,两个训练点 x1=(2,1),y1=+1x_1 = (2, 1), y_1 = +1x2=(1,2),y2=1x_2 = (-1, 2), y_2 = -1

  • x1x_1:分数 =0= 0y10=00y_1 \cdot 0 = 0 \le 0,误分类,更新 w(2,1),  b1w \leftarrow (2, 1),\; b \leftarrow 1
  • x2x_2:分数 =2(1)+12+1=1= 2 \cdot (-1) + 1 \cdot 2 + 1 = 1,预测 +1+1 但真实 1-1,误分类,更新 w(3,1),  b0w \leftarrow (3, -1),\; b \leftarrow 0
  • 复查 x1x_1:分数 =5>0= 5 > 0 ✓;复查 x2x_2:分数 =5<0= -5 < 0 ✓。两个点都对了,循环终止。

工程上常见的简化是bb 并入 ww:给每个 xx 末尾加一个常数 1、扩成 x~=(x,1)Rn+1\tilde x = (x, 1) \in \mathbb{R}^{n+1},把权重也扩成 w~=(w,b)\tilde w = (w, b);这样 wx+b=w~x~w \cdot x + b = \tilde w \cdot \tilde x,整套更新塌成 w~w~+ηyix~i\tilde w \leftarrow \tilde w + \eta y_i \tilde x_i,公式更紧凑。bb 在数学上仍是参数,只是位于扩展向量的最后一个分量

整个学习过程没有梯度、没有反向传播、没有损失函数的概念——它是「错就改」的最原始版本:误分类的点把超平面朝自己拉一点,正确分类的点保持不动

1.2 Novikoff 收敛性定理

光有学习规则不够,还要回答两个问题:这套规则在什么条件下一定能停?停的时候要多少步?1962 年 Novikoff 给出了完整的答案:在数据线性可分时,感知机算法在 R2/γ2\lceil R^2 / \gamma^2 \rceil 步内必然收敛

定理(Novikoff 1962):设训练集 {(xi,yi)}i=1N\{(x_i, y_i)\}_{i=1}^N 满足 xiR\|x_i\| \le R,且存在 ww^*(不失一般性地取 w=1\|w^*\| = 1)使得对所有 ii 都有 yi(wxi)γ>0y_i (w^* \cdot x_i) \ge \gamma > 0。则从 w0=0w_0 = 0 开始、学习率 η=1\eta = 1 的感知机算法在至多 tR2/γ2t \le R^2 / \gamma^2 次更新后收敛。

证明分上下两个 bound 后用 Cauchy-Schwarz 夹起来。设 wtw_t 是经过 tt 次更新后的权向量。

内积下界:每次更新 wt=wt1+yitxitw_t = w_{t-1} + y_{i_t} x_{i_t},于是

wtw=(wt1+yitxit)w=wt1w+yit(xitw)wt1w+γ.\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}

w0w=0w_0 \cdot w^* = 0 递推到 tt 步得 wtwtγw_t \cdot w^* \ge t \gamma

范数平方上界

wt2=wt1+yitxit2=wt12+2yit(wt1xit)+xit2.\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}

更新发生的前提是 (xit,yit)(x_{i_t}, y_{i_t})wt1w_{t-1} 下被误分类,即 yit(wt1xit)0y_{i_t} (w_{t-1} \cdot x_{i_t}) \le 0,因此中间项 0\le 0;再代入 xit2R2\|x_{i_t}\|^2 \le R^2wt2wt12+R2\|w_t\|^2 \le \|w_{t-1}\|^2 + R^2。从 w0=0\|w_0\| = 0 递推到 tt 步得 wt2tR2\|w_t\|^2 \le t R^2

夹定:由 Cauchy-Schwarz wtwwtw=wtw_t \cdot w^* \le \|w_t\| \cdot \|w^*\| = \|w_t\|,结合上下界得

tγ    wtw    wt    tR2=Rt.t \gamma \;\le\; w_t \cdot w^* \;\le\; \|w_t\| \;\le\; \sqrt{t R^2} = R \sqrt{t}.

平方两边除以 γ2\gamma^2tR2/γ2t \le R^2 / \gamma^2\blacksquare

Novikoff 定理给的不是渐进保证,而是绝对上界——只要数据线性可分,迭代次数被「半径 RR 与 margin γ\gamma 的比值」一次性卡死。1960 年代这条结果一度让人对感知机的前景非常乐观;但马上就会迎来新的限制。

1.3 异或问题:线性不可分的代数与几何

Minsky 与 Papert 在 1969 年的 《Perceptrons》 一书里给出了一个让感知机几乎被打入冷宫的反例:异或(XOR)。XOR 把 (x1,x2){0,1}2(x_1, x_2) \in \{0, 1\}^2 映成 0 或 1,真值表是:

x1x_1x2x_2XOR
000
011
101
110

代数上假设存在 (w1,w2,b)(w_1, w_2, b) 使感知机能学到 XOR。把四个点代入符号约束(输出 1 时 0\ge 0,输出 0 时 <0< 0):

b<0from (0,0)0,w2+b0from (0,1)1,w1+b0from (1,0)1,w1+w2+b<0from (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}

把第 2 式与第 3 式相加得 w1+w2+2b0w_1 + w_2 + 2b \ge 0;把第 1 式与第 4 式相加得 w1+w2+2b<0w_1 + w_2 + 2b < 0两条不等式直接矛盾——任何单层线性模型在代数上都无法实现 XOR

几何上更直白:决策边界 w1x1+w2x2+b=0w_1 x_1 + w_2 x_2 + b = 0R2\mathbb{R}^2 中的一条直线,把平面切成两个半平面。XOR 要求 (0,0)(0, 0)(1,1)(1, 1) 落在 0 这一侧、(0,1)(0, 1)(1,0)(1, 0) 落在 1 这一侧——把每一类的两个点用线段连起来,恰好得到单位正方形的两条对角线,而这两条对角线在中心 (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  =  σ ⁣(W2σ(W1x+b1)+b2),y \;=\; \sigma\!\left(W_2 \, \sigma(W_1 x + b_1) + b_2\right),

其中 W1Rh×nW_1 \in \mathbb{R}^{h \times n}nn 维输入映到 hh 维隐层、W2Rm×hW_2 \in \mathbb{R}^{m \times h} 把隐层映到 mm 维输出,σ\sigma 是 element-wise 非线性。一般可以推广到 LL 层:

a0=x,al=σ(Wlal1+bl)    (l=1,,L),y=aL.a_0 = x, \quad a_l = \sigma(W_l a_{l-1} + b_l) \;\; (l = 1, \dots, L), \quad y = a_L.

多层感知机的本质是用矩阵乘法把若干线性变换串起来,再在每两层之间插入一次非线性 σ\sigma 防止整体退化。这里「非线性 σ」是关键——下一节会证明缺了它,整套结构会立刻塌成单层。

2.2 线性崩塌定理:激活函数为何必须存在

把上面定义的 σ\sigma 换成恒等映射 σ(z)=z\sigma(z) = z,两层 MLP 就变成

y=W2(W1x+b1)+b2=(W2W1)x+(W2b1+b2)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}

是一个新的线性变换。一般地,LL 层全线性 MLP 为

y=WLWL1W1x+l=1L ⁣(k=l+1LWk)bl=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,

仍是单层线性变换。任何有限层数的纯线性变换复合仍然是线性变换——无论叠多少层,表达能力都不会超过最浅那一层。这就是「线性崩塌」(linear collapse)。

非线性激活的存在是让整个结构跳出仿射子空间的唯一方式。具体跳出多远由 σ\sigma 的选择与层数 LL 决定,但前提是 σ\sigma 不是恒等映射。激活函数不是装饰——它是非线性表达能力的唯一来源

2.3 万能近似定理:构造性证明思路

非线性激活带来表达能力的「下限」是多少?1989 年 Cybenko 与 1991 年 Hornik 各自给出答案:万能近似定理(Universal Approximation Theorem,UAT)。

定理(Cybenko 1989):设 σ\sigma 是连续、单调递增、有界的激活函数(sigmoidal)。则对紧集(compact set,即闭且有界的子集,例如 [0,1]n[0, 1]^nKRnK \subset \mathbb{R}^n 上任意连续函数 f:KRf: K \to \mathbb{R} 与任意 ϵ>0\epsilon > 0,都存在自然数 hh、权重 {wi,bi,αi}i=1h\{w_i, b_i, \alpha_i\}_{i=1}^h,使得网络

g(x)=i=1hαiσ(wix+bi)g(x) = \sum_{i=1}^{h} \alpha_i \sigma(w_i \cdot x + b_i)

满足 supxKg(x)f(x)<ϵ\sup_{x \in K} |g(x) - f(x)| < \epsilon

构造性思路(不写完整证明,只写直觉):以 σ\sigma 为 sigmoid 为例。σ(α(zc))\sigma(\alpha(z - c)) 本身是一条光滑的 S 曲线,在 z=cz = c 附近从 0 平滑过渡到 1——α 越大,过渡区间越窄、曲线越陡,形态越接近以 cc 为台阶的阶跃函数。

把两条过渡位置相隔很近(间距 δ\delta)的这种 sigmoid 相减——σ(α(zc))σ(α(zcδ))\sigma(\alpha(z - c)) - \sigma(\alpha(z - c - \delta)),按 zz 轴分三段看就很直观:

区间σ(α(zc))\sigma(\alpha(z - c))σ(α(zcδ))\sigma(\alpha(z - c - \delta))
z<cz < c0\approx 00\approx 00\approx 0
z[c,c+δ]z \in [c,\, c+\delta]1\approx 1(已跨过 cc0\approx 0(还没到 c+δc+\delta1\approx 1
z>c+δz > c + \delta1\approx 11\approx 10\approx 0

差只在中间那条窄带上 1\approx 1、其他地方 0\approx 0——这就是一个支撑在 [c,c+δ][c, c + \delta] 上的矩形脉冲,由两个错开 δ\delta 的阶跃做差得到α\alpha 有限时这个矩形是光滑过渡(两侧不再是直角),所以本质上 sigmoid 差给我们提供了一个矩形脉冲的光滑近似。

而紧集上的连续函数都可以被阶梯函数(即分段常数函数:一串高度不同、宽度足够小的矩形构成)任意精度地一致逼近——这是 Heine–Cantor 一致连续定理 的直接推论(紧集上连续 ff 一致连续,所以把紧集切得足够细、每块上用代表点的 f(xi)f(x_i) 当常数即可,逼近误差被切片宽度卡死)。把阶梯函数里的每个矩形换成对应高度的 sigmoid 差窄峰、再按段加起来,就用一个单隐层 sigmoid 网络分段逼近了 ff——形式正是 UAT 定理陈述里的 g(x)=iαiσ(wix+bi)g(x) = \sum_i \alpha_i \sigma(w_i \cdot x + b_i)。Hornik 1991 把结论推广到任意非常数、有界、连续的 σ\sigma,并不要求 sigmoidal 形状。

UAT 给的是「表达能力的存在性保证」,不是构造效率,更不是优化或泛化保证。它告诉我们「神经网络原理上能逼近任何连续函数」——但「能逼近」≠「能学到」(这是优化问题)≠「在测试集上也能逼近」(这是泛化问题)。这两条恰恰是 § 3-5 要讨论的核心。

2.4 激活函数全景:饱和到非饱和

讲具体函数之前先把后面会反复出现的几个术语定义清楚:

  • 饱和区(saturation region):激活函数导数 σ(z)0\sigma'(z) \to 0 的区域。在饱和区里输入再变化也几乎不影响输出,反向传播时这一层的梯度会被压扁到接近零。
  • 饱和型激活函数(saturating activation):两端都有饱和区的激活函数。Sigmoid(z±z \to \pm\infty 时分别趋近 0 / 1)和 tanh(趋近 1\mp 1)都是双侧饱和;深层网络里这类函数的链积 σ\prod \sigma' 容易指数衰减。
  • 半饱和激活函数:只一边饱和,比如 ReLU 的负半区(z<0z < 0σ=0\sigma = 0);正半区 σ(z)=1\sigma'(z) = 1 不饱和。
  • 死亡区(dying region):导数严格等于 0 而不是接近 0 的区域。ReLU 的负半区就是这样:σ(z)=0\sigma(z) = 0σ(z)=0\sigma'(z) = 0,落到这里的神经元再也收不到梯度信号、永远不更新——这就是「dying ReLU」。死亡区和饱和区的差别是「严格零」vs「接近零」;前者不可逆,后者还能因为小扰动恢复。

UAT 对 σ\sigma 的形态要求很宽,但工程上选哪个 σ\sigma 直接决定训练稳定性。常见的四种激活函数:

-4-3-2-101234输入 z -101234激活值 σ(z) Sigmoid Tanh ReLU GeLU
四种激活函数对比

比训练影响更直接的是它们的导数——反向传播链积全靠 σ\sigma' 在每一层乘进去:

-4-3-2-101234输入 z 00.20.40.60.811.2导数 σ'(z) Sigmoid' Tanh' ReLU' GeLU'
四种激活函数的导数

四种激活函数的关键差别都集中在导数特性上:

激活表达式σ(0)\sigma'(0)饱和区导数训练表现
Sigmoid1/(1+ez)1 / (1 + e^{-z})0.250\to 0深网络极易梯度消失
Tanhtanh(z)\tanh(z)10\to 0比 sigmoid 略好,仍饱和
ReLUmax(0,z)\max(0, z)1(约定)1(正区)/ 0(负区)不饱和但有死亡区
GeLUzΦ(z)z \cdot \Phi(z)0.51\to 1(正区)/ 0\to 0(负区)Transformer 标配,光滑

饱和型激活(sigmoid、tanh)在 z\lvert z \rvert 大时导数趋于 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),其中 α\alpha 是一个小正数(通常 0.01)。把 ReLU 的负区导数从 0 改成 α\alpha,死亡区消失——任何输入都有非零梯度往回传。
  • PReLU(Parametric ReLU):跟 Leaky ReLU 同形,但 α\alpha 当成可学习参数、每层各自学一个。
  • ELU(Exponential Linear Unit):σ(z)=z\sigma(z) = zz>0z > 0α(ez1)\alpha(e^z - 1)z0z \le 0。当 zz \to -\infty 时函数值 σ(z)α\sigma(z) \to -\alpha(负区饱和在 y=αy = -\alpha),所以整个函数处处可导且有下界 α-\alpha,训练上通常比 Leaky ReLU 更稳。
  • Swish / SiLUσ(z)=zσsigm(z)\sigma(z) = z \cdot \sigma_\text{sigm}(z)σsigm\sigma_\text{sigm} 即 sigmoid)。形状跟 GeLU 几乎一样——GeLU 用累积分布函数 Φ\Phi 做平滑权重、Swish 用 sigmoid,在大模型实践里两者基本可以互换。

把这几个改良函数(Leaky ReLU 取 α=0.1\alpha = 0.1、ELU 取 α=1\alpha = 1,叠加 plain ReLU 当对照)画在同一张图里看形状差异:

-4-3-2-101234输入 z -101234激活值 σ(z) ReLU(对照) Leaky ReLU (α=0.1) ELU (α=1) Swish / SiLU
ReLU 改良家族对比

对应的导数:

-4-3-2-101234输入 z -0.200.20.40.60.811.2导数 σ'(z) ReLU'(对照) Leaky ReLU' (α=0.1) ELU' (α=1) Swish' / SiLU'
ReLU 改良家族的导数

观察要点:Leaky ReLU 把 ReLU 的负区导数从 0 抬到 α\alpha(一条水平线,这就是消死亡区的全部代价);ELU 在 z=0z = 0 处导数连续,不像 ReLU 是折角;Swish 整体光滑、在 z1.3z \approx -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] 输出,所以用 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,给定训练集 {(xi,yi)}i=1N\{(x_i, y_i)\}_{i=1}^N训练的目标是找到 θ\theta^* 使「模型预测与真实标签的差距」最小——这个「差距」由一个损失函数(loss function) L(θ)L(\theta) 量化(常见形式见下文 §3.2,概率诠释见 §3.3)。

2. 梯度下降:神经网络通常没有解析最优解,所以训练用迭代法——每一步沿损失对参数的负梯度方向走一小步:

θθηθL(θ).\theta \leftarrow \theta - \eta\, \nabla_\theta L(\theta).

直觉:梯度 θL\nabla_\theta L 指向损失上升最快的方向;反方向就是下降最快的方向。学习率 η\eta(一个小正数,如 10310^{-3})控制每一步走多远——太大会越过最优、太小收敛太慢。这就是 梯度下降(gradient descent)。

3. 反向传播是个高效算梯度的算法:现代神经网络的参数动辄上百万、上亿,θL\nabla_\theta L 不可能逐个手工求偏导。反向传播(backpropagation)解决的就是这件事:把网络看成一张计算图(forward pass 算出来),然后按图的反向拓扑顺序、用链式法则一次性算出所有 L/θj\partial L / \partial \theta_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 / L21Ni(yiy^i)2\frac{1}{N}\sum_i (y_i - \hat y_i)^2回归
MAE / L11Niyiy^i\frac{1}{N}\sum_i \lvert y_i - \hat y_i \rvert回归,对离群点更稳健
二分类交叉熵ylogy^(1y)log(1y^)-y \log \hat y - (1-y) \log(1 - \hat y)二分类
多分类交叉熵kyklogy^k-\sum_k y_k \log \hat y_k多分类(配 softmax 输出)
Hinge lossmax(0,1yy^)\max(0,\, 1 - y \hat y)SVM、max-margin 分类
KL 散度xp(x)logp(x)q(x)\sum_x p(x) \log \frac{p(x)}{q(x)}分布匹配(VAE、知识蒸馏)

3.3 损失函数的概率解释:MLE 推 MSE 与交叉熵

很多教材把 MSE 与交叉熵当作两条独立的损失,但它们其实都来自同一个源头:最大似然估计(MLE)+ 不同的噪声 / 输出分布假设。

回归情形(高斯噪声):假设观测 yi=fθ(xi)+ϵiy_i = f_\theta(x_i) + \epsilon_i,其中 ϵiN(0,σ2)\epsilon_i \sim \mathcal{N}(0, \sigma^2) 独立同分布。条件密度

p(yixi,θ)=12πσexp ⁣((yifθ(xi))22σ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).

对数似然

logp({yi}{xi},θ)=i=1Nlogp(yixi,θ)=12σ2i=1N(yifθ(xi))2Nlog(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}

第二项与 θ\theta 无关,最大化对数似然等价于最小化 (yifθ(xi))2\sum (y_i - f_\theta(x_i))^2——这就是 MSE。MSE 不是凭空定义的损失——它是「输出加高斯噪声」假设下的 MLE 直接产物

分类情形(伯努利输出):二分类时令 fθ(x)(0,1)f_\theta(x) \in (0, 1) 是模型预测的「类别为 1 的概率」,标签 yi{0,1}y_i \in \{0, 1\}伯努利分布 是只取 {0,1}\{0, 1\} 的随机变量分布,由一个参数 π[0,1]\pi \in [0, 1] 完全决定:P(Y=1)=πP(Y = 1) = \piP(Y=0)=1πP(Y = 0) = 1 - \pi。它的紧凑写法用「指数当 if-else 选择器」把两种情况合并成一行——

P(Y=y)=πy(1π)1y,y{0,1}.P(Y = y) = \pi^y (1 - \pi)^{1 - y}, \quad y \in \{0, 1\}.

代进去验证:y=1y = 1(1π)0=1(1 - \pi)^0 = 1 退场,剩 π\piy=0y = 0π0=1\pi^0 = 1 退场,剩 1π1 - \pi。任何数的 0 次幂等于 1——所以「不该选中的那一项」自动消失。

条件分布」中的「条件」指给定输入 xix_i——模型让伯努利的参数 π\pi 变成 xix_i 的函数 π(xi)=fθ(xi)\pi(x_i) = f_\theta(x_i),同一个 θ\theta 在不同 xix_i 上输出不同的 π\pi。把 π(xi)\pi(x_i) 代入伯努利紧凑形式:

p(yixi,θ)=fθ(xi)yi(1fθ(xi))1yi.p(y_i \mid x_i, \theta) = f_\theta(x_i)^{y_i} (1 - f_\theta(x_i))^{1 - y_i}.

举例(猫狗分类):模型对一张图输出 fθ(x)=0.8f_\theta(x) = 0.8(「这是猫」的预测概率)。若真实标签 y=1y = 1(猫),代入得 p(y=1x,θ)=0.810.20=0.8p(y = 1 \mid x, \theta) = 0.8^1 \cdot 0.2^0 = 0.8——模型对真实标签赋的概率很高;若真实是 y=0y = 0(狗),p(y=0x,θ)=0.800.21=0.2p(y = 0 \mid x, \theta) = 0.8^0 \cdot 0.2^1 = 0.2——模型判断错了,给真实标签的概率很低。MLE 要做的就是调 θ\theta 让所有训练样本上模型赋给真实标签的概率尽量大

对数似然

logp({yi}{xi},θ)=i=1N[yilogfθ(xi)+(1yi)log(1fθ(xi))].\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].

取负即为二分类的交叉熵损失。多分类用 softmax 输出 fθ(x)=(p1,,pK)f_\theta(x) = (p_1, \dots, p_K),one-hot 标签 yy 同样推出 categorical cross-entropy kyklogpk-\sum_k y_k \log p_k

那为什么叫「交叉熵」?这个名字来自信息论。按信息论的经典约定,一个离散分布 pp(entropy)

H(p)=xp(x)log2p(x)H(p) = -\sum_x p(x) \log_2 p(x)

衡量它的「平均信息量」——按 pp 自身最优地编码时,平均每个事件需要多少 bit(连续分布的对应物是积分形式 p(x)log2p(x)dx-\int p(x) \log_2 p(x)\, dx,称为微分熵,本文不展开)。交叉熵(cross-entropy)把两个离散分布交叉起来:

H(p,q)=xp(x)log2q(x).H(p, q) = -\sum_x p(x) \log_2 q(x).

含义是「事件按真实分布 pp 发生,但你用按 qq 设计的编码去存——平均要花多少 bit」。「交叉」就来自两个分布在公式里担任不同的角色pp 在 log 外面当权重qq 在 log 里面当对数的概率参数。如果把它们对调位置——让 qq 当权重、pp 钻进 log 里——得到的是 H(q,p)=xq(x)log2p(x)H(q, p) = -\sum_x q(x) \log_2 p(x),一般跟原值不等;所以交叉熵不对称H(p,q)H(q,p)H(p, q) \neq H(q, p)

回到分类损失:one-hot 真实标签 yy 就是 pp、模型预测的 softmax 输出 y^\hat y 就是 qq,于是 kyklogy^k=H(p,q)-\sum_k y_k \log \hat y_k = H(p, q)——分类的交叉熵损失正好是「真实标签分布与模型预测分布之间的交叉熵」。最小化交叉熵 = 把 qq 推向 pp;与之等价的写法是最小化 KL 散度 DKL(pq)=H(p,q)H(p)D_{KL}(p \| q) = H(p, q) - H(p),二者只差一个仅由数据本身决定的常数 H(p)H(p)

⚙️ 底数的选择只影响单位、不影响最小化结果log2\log_2 → bit、自然对数 ln\ln → nat、log10\log_{10} → ban,三者只差常数因子。机器学习实现(PyTorch、TensorFlow 的 cross-entropy)实际用的是自然对数 ln\ln——求导简单、与 MLE 的负对数似然直接对应,单位是 nat 而非 bit。所以本文 §3.1 上半段从 MLE 推出来的「kyklogy^k-\sum_k y_k \log \hat y_k」里的 log\log 在工程上就是 ln\ln;最优参数 θ\theta 与用 log2\log_2 得到的完全相同。

交叉熵也不是凭空——它是「分类输出服从伯努利 / 多项式分布」假设下的 MLE 直接产物。两条损失共享同一个底层逻辑:负对数似然。

最后多说一句 KL 散度(Kullback & Leibler 1951,又叫相对熵)。它原本是数理统计里刻画「两个假设分布有多容易区分」的工具:非负Gibbs 不等式DKL(pq)=0D_{KL}(p \| q) = 0 当且仅当 p=qp = q 几乎处处相等)、跟交叉熵一样不对称,常被解读为「用 qq 近似 pp 时的信息损失」。除了分类训练里跟交叉熵的隐含联系,深度学习里它还有几个常见落地:

  • 变分自编码器(VAE):损失里 DKL(q(zx)p(z))D_{KL}(q(z \mid x) \| p(z)) 把编码器输出的隐变量分布拉向先验,让隐空间结构化、可采样。
  • 强化学习(PPO / TRPO):每步策略更新时约束 DKL(πnewπold)D_{KL}(\pi_\text{new} \| \pi_\text{old}) 不要太大,防止策略一次性剧变。
  • 知识蒸馏:最小化 DKL(pstudentpteacher)D_{KL}(p_\text{student} \| p_\text{teacher}),让学生模型对每个输入的输出分布尽量贴近教师。

pp 在训练中固定时(分类问题就是这样),最小化交叉熵等于最小化 KL;但 pp 也是模型一部分的场景(如 VAE 的先验项)必须用完整的 KL

3.4 反向传播:计算图、链式法则、雅可比

§ 3.1 把反向传播定位成「算梯度的算法」。反向传播本身不是新的求导规则——它做的全部事情是「把链式法则按计算图反向拓扑顺序套用一遍」。本节介绍计算图、雅可比矩阵、链积形式,以及它们在张量、矩阵、深度网络层结构上的具体写法。

计算图与局部偏导。现代深度学习框架(PyTorch / TensorFlow / JAX)的底层抽象都是计算图——把一次前向计算拆成一张有向无环图(DAG),节点是所有变量(含输入、参数 WWbb、中间量、输出),边表示计算依赖、携带从父节点到子节点的局部偏导。注意这跟 § 1.1 / § 2.1 的「网络结构图」不一样:那种图里权重是边(神经元之间的加权连接),而这里的计算图里权重是节点,连接它和下游中间量的边携带的是局部偏导 z/W\partial z / \partial W、不是权重本身。

以最简单的回归损失 L=(σ(Wx+b)y)2L = (\sigma(W x + b) - y)^2 为例,把它拆成中间变量 z=Wx+bz = W x + ba=σ(z)a = \sigma(z)L=(ay)2L = (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=xT\partial z / \partial W = x^Ta/z=σ(z)\partial a / \partial z = \sigma'(z)L/a=2(ay)\partial L / \partial a = 2(a - y),等等。要算 L/W\partial L / \partial W,把 LazWL \to a \to z \to W 这条路径上的所有局部偏导按链式法则乘起来:

LW=LaazzW=2(ay)σ(z)xT.\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.

反向传播不是新的求导规则——它是把链式法则按图的反向拓扑顺序、用局部偏导组合得到。任何能写成 DAG 的函数都可这样求导,框架要做的只是记住每条边对应的局部偏导算子。

雅可比矩阵。当某一层是向量到向量的映射时,「局部偏导」就是雅可比矩阵:若 f:RnRmf: \mathbb{R}^n \to \mathbb{R}^m,则 f/xRm×n\partial f / \partial x \in \mathbb{R}^{m \times n},其第 (i,j)(i, j) 元素是 fi/xj\partial f_i / \partial x_j。神经网络中常见三类层的 Jacobian:

  • 线性层 y=Wx+by = W x + byRmy \in \mathbb{R}^mxRnx \in \mathbb{R}^nWRm×nW \in \mathbb{R}^{m \times n}):y/x=W\partial y / \partial x = W;对参数 WW 的偏导按元素写为 yi/Wij=xj\partial y_i / \partial W_{ij} = x_j
  • 激活层 y=σ(x)y = \sigma(x)(element-wise):y/x=diag(σ(x))\partial y / \partial x = \mathrm{diag}(\sigma'(x)),是一个对角矩阵。
  • 损失层 L=(y,ytrue)L = \ell(y, y_{\text{true}})(标量输出):L/yR1×m\partial L / \partial y \in \mathbb{R}^{1 \times m},是行向量。

element-wise 激活层的雅可比是对角阵——这一观察是 §4.1 分析「梯度链积」的关键:对角矩阵的奇异值就是对角元素 σ(zi)\sigma'(z_i) 本身,整个链积的幅值由各层 σ\sigma' 一路相乘决定。

链积形式。把整个反向传播写成一行:深度 LL 处的损失对输入 x0x_0 的梯度可以写成所有层雅可比的链积:

Lx0=LxLl=L1Jl,Jl=xlxl1.\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}}.

这条公式就是 §4 接下来要分析「梯度消失 / 爆炸」的出发点。

4. 训练稳定性:深层网络的生存之道

4.1 梯度消失与爆炸:谱半径视角

回到 § 2.4 的导数图,接 § 3.4 末尾的链积公式

Lx0=LxLl=L1Jl,Jl=xlxl1.\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}}.

链积的幅值受每一层 JlJ_l 对向量长度的缩放能力支配。对一个矩阵 AA最大奇异值 σmax(A)\sigma_{\max}(A) 给出它把单位长度向量拉得最长的倍数——精确地说,对任何向量 vv 都有

Av2    σmax(A)v2,\|A v\|_2 \;\le\; \sigma_{\max}(A) \cdot \|v\|_2,

而且等号在 vvAA 的最长方向时取到。所以如果每层 σmax(Jl)\sigma_{\max}(J_l)<1< 1,链积把梯度幅值越乘越小;都 >1> 1 则指数级放大。

方阵情形下还常用 谱半径 ρ(J)=maxiλi(J)\rho(J) = \max_i \lvert \lambda_i(J) \rvert(特征值绝对值的最大者)描述迭代意义下的渐近缩放——非对称矩阵下有 ρ(J)σmax(J)\rho(J) \le \sigma_{\max}(J),二者在工程语境里常被混用作「该变换的有效缩放因子」。下文用 ρˉ\bar\rho 表示每层 JlJ_l 的平均缩放因子(取奇异值或谱半径都可以)。

设每层 JlJ_l 的平均缩放因子为 ρˉ\bar\rho,链积的幅值近似正比于 ρˉL\bar\rho^L。两个极端:

  • ρˉ<1\bar\rho < 1:链积指数衰减——梯度消失,靠近输入的层几乎收不到梯度信号。
  • ρˉ>1\bar\rho > 1:链积指数放大——梯度爆炸,数值上溢、优化失败。

消失和爆炸的失败机制略有不同。消失时训练表面还在跑、损失也在降,但靠近输入的层几乎不更新——深层网络等于退化成只训练后几层的浅层模型,泛化能力受限。

爆炸更暴力。一旦梯度某个分量超过 float32 上限(约 3.4×10383.4 \times 10^{38})就变成 inf;后续 inf - inf / 0 * inf / inf / inf 这类运算又产生 NaN,而 NaN 在 IEEE 754 里是吸收性的——任何包含它的算术都返回 NaNNaN 一旦进入某个参数,下一次前向时整张激活图都变成 NaN、损失变 NaN、所有梯度都是 NaN、所有参数被更新成 NaN——训练彻底死掉、无法恢复

即便没到 inf,一次过大的步长 ηL\eta \nabla L 也会让参数跳到损失景观完全陌生的区域、轨迹发散。工程上的对症方案是 gradient clipping:检测到 L>τ\|\nabla L\| > \tau 时按比例缩到 τ\tau宁可走慢也不让单次步长爆掉;RNN / Transformer 训练里几乎是标配。

以 Sigmoid 为例算个具体数字:它的导数 σ(z)=σ(z)(1σ(z))\sigma'(z) = \sigma(z)(1 - \sigma(z)) 是钟形曲线,最大值 0.250.25z=0z = 0 处取到,偏离 0 时 σ\sigma' 迅速减小。所以即便在「最理想的位置」(z0z \approx 0),一层 ρˉ\bar\rho 顶多也只到 0.250.25;权重未做特殊初始化时实际更低,10 层链积上界约为 0.25101060.25^{10} \approx 10^{-6}——梯度几乎完全归零

51152深度 L 012345链积 ρ^L sigmoid' 链积 (0.25)^L tanh' 近饱和 (0.9)^L ReLU' 正区 (1.0)^L 爆炸 ρ=1.2
梯度链积 ρ^L 随深度的变化

注意 ρ=1.2\rho = 1.2 的曲线在 L9L \approx 9 之后冲出图外——这就是「爆炸」的字面意思。梯度问题的本质不是「网络深」,而是「Jacobian 链积的谱半径不在 1 附近」。这就把问题从「网络架构选择」转到「让每一层的 JlJ_l 谱半径保持在 1 附近」这个工程任务上。下面 4.2 / 4.3 两节就是它的两条解法。

4.2 权重初始化:Xavier 与 He 的方差齐性推导

Xavier 初始化(Glorot & Bengio 2010)的核心想法是让每层 forward / backward 时各分量的方差与上一层相同——链积的谱半径自然贴近 1。

为什么「方差齐性」能让谱半径贴近 1?两步:方差保持意味着每层平均不放大也不缩小向量长度的平方;**随机矩阵理论的 Marchenko–Pastur 定律**告诉我们,iid 元素、方差 σw2\sigma_w^2、规模 m×nm \times n 的随机矩阵,奇异值集中在 σwn\sigma_w \sqrt{n} 附近。代入下文 Xavier 前向方程的解 σw2=1/n\sigma_w^2 = 1/n,奇异值 1/nn=1\approx \sqrt{1/n} \cdot \sqrt{n} = 1,谱半径 ρ1\rho \approx 1方差齐性其实是「让每层 Jacobian 的奇异值集中在 1 附近」的工程化代理——直接控制方差比直接做 SVD 控制奇异值容易得多(采样权重时控制方差是 O(1)O(1) 的事;做 SVD 是 O(n3)O(n^3))。

假设:输入 xx 各维独立同分布、零均值、方差 σx2\sigma_x^2;权重 WRm×nW \in \mathbb{R}^{m \times n} 各元素独立、零均值、方差 σw2\sigma_w^2;激活近似线性(小输入区,对 tanh 在 0 附近成立)。符号约定WWnn 维输入映到 mm 维输出,所以每个输出神经元接收 nn 个输入——称为 fan-in =n= nWW 的列数);每个输入被分发到 mm 个输出——称为 fan-out =m= mWW 的行数)。两个词借自电路术语:扇形进来的端口数(fan-in)与扇形出去的端口数(fan-out)。

前向方差:对线性层 zj=k=1nWjkxkz_j = \sum_{k=1}^{n} W_{jk} x_k

Var(zj)=k=1nVar(Wjkxk)=k=1nVar(Wjk)Var(xk)=nσw2σx2.\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)=Var(x)\mathrm{Var}(z) = \mathrm{Var}(x),需要 σw2=1/n\sigma_w^2 = 1 / nnn 是 fan-in)。

反向方差:反向传播的梯度 gj=i=1mWijgi(out)g_j = \sum_{i=1}^{m} W_{ij} g_i^{\text{(out)}}mm 是 fan-out),

Var(gj)=mσw2Var(g(out)).\mathrm{Var}(g_j) = m \cdot \sigma_w^2 \cdot \mathrm{Var}(g^{\text{(out)}}).

要保持反向方差不变,需要 σw2=1/m\sigma_w^2 = 1 / m。前向与反向无法同时严格满足,Xavier 取调和折衷:

σw2=2n+m.\sigma_w^2 = \frac{2}{n + m}.

He 初始化(He et al. 2015)针对 ReLU 做了一处修正:ReLU 把负半区直接清零,实际激活的样本只有一半,所以前向方差变为 Var(z)=12nσw2σx2\mathrm{Var}(z) = \tfrac{1}{2} n \sigma_w^2 \sigma_x^2。要保持方差不变得:

σw2=2n.\sigma_w^2 = \frac{2}{n}.

Xavier 与 He 的差别不在 σx2\sigma_x^2 的选择,而在「ReLU 砍掉一半激活」这一条物理假设——后者把因子 2 推回到分子。工程上对 sigmoid / tanh 网络用 Xavier、对 ReLU 系列用 He,几乎已是默认。

4.3 归一化:BatchNorm 与 LayerNorm 的数学本质

权重初始化只在 t=0t = 0 时让 ρˉ1\bar\rho \approx 1 成立;训练过程中权重会漂移、激活分布会偏移、谱半径会脱离 1。归一化(Normalization)层的目的就是在每一层强制把激活拉回零均值、单位方差的分布,让 σ\sigma' 始终落在「敏感区」附近。

Batch Normalization(简称 BN) 在 mini-batch 维度做归一化。对一个 batch {x(1),,x(B)}\{x^{(1)}, \dots, x^{(B)}\} 的某通道 / 神经元 jj

μj=1Bi=1Bxj(i),σj2=1Bi=1B(xj(i)μj)2,x^j(i)=xj(i)μjσj2+ϵ,yj(i)=γjx^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}

最后的 affine 参数 γj,βj\gamma_j, \beta_j 可学习,避免归一化把网络的表达能力锁死——如果某层确实需要非零均值或非单位方差的输出,模型可以通过 γ,β\gamma, \beta 学回去。

⚙️ 实际架构中线性层的 bb 经常被关掉:ResNet 的卷积层默认 bias=False;LLaMA / PaLM 的 FFN 与 Q / K / V projection 也都 bias-free。原因是这些线性层后面紧接 BN / LN,归一化层的 β\beta 已经提供了同样的 shift 自由度,再保留 bb 只是冗余参数——增加参数量但不增加表达能力。所以「Linear + BN + ReLU」这种现代组合里把 bb 关掉是 PyTorch 实现里的默认配置。

⚙️ 实际实现的取舍:BatchNorm 训练时用 batch statistics μj,σj2\mu_j, \sigma_j^2,推断时若仍用 batch 统计就会导致同一个输入在不同 batch 下输出不同。PyTorch / TensorFlow 的实现——训练时同时维护 μ,σ2\mu, \sigma^2 的滑动平均(running statistics),推断时切换为滑动平均值。这一切换让 BatchNorm 的训练-推断行为天然不对称,是它在小 batch、变长输入、RNN / Transformer 等场景翻车的根本原因。实际工程上 RNN / Transformer 改用下文的 LayerNorm;现代 LLM(LLaMA、Mistral、Gemma 等)进一步简化为 RMSNorm——去掉减均值、只用 root-mean-square 归一

Layer Normalization(简称 LN) 改成在单个样本的所有维度上做归一化,与 batch size 无关:

μ=1nj=1nxj,σ2=1nj=1n(xjμ)2,x^j=xjμσ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}}.

LayerNorm 与 batch 解耦,对 Transformer 这种 batch 内样本序列长度差异大的架构特别友好——这是它在 NLP 与现代 LLM 中几乎完全取代 BatchNorm 的工程原因

回到 § 4.1 的视角:归一化让每层激活分布固定在零均值、单位方差,相当于把激活强行钉回 σ\sigma' 大致恒定的「敏感区」。归一化的真实目标不是「分布稳定」这种含糊话,而是「保持激活分布在 σ\sigma' 接近常数的区间,使 Jacobian 链积的谱半径不漂移」

5. 泛化与正则化:拟合之后的思考

5.1 偏差-方差权衡

到这里所有讨论都集中在「训练能不能收敛」上。但训练损失低不等于模型有用——真正的目标是在新样本上的泛化误差。给定输入 x0x_0、真实标签 y0y_0 与训练集 DD,定义模型预测 y^(x0;D)\hat y(x_0; D),则任意点 x0x_0 处的期望 MSE 可以分解:

ED ⁣[(y^(x0;D)y0)2]=ED ⁣[(y^y^ˉ)2]+(y^ˉf(x0))2+σϵ2=VarD[y^(x0;D)]方差+(ED[y^(x0;D)]f(x0))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}

其中 y^ˉ=ED[y^(x0;D)]\bar{\hat y} = \mathbb{E}_D[\hat y(x_0; D)]f(x0)f(x_0) 是真实条件期望,σϵ2\sigma_\epsilon^2 是不可约的标签噪声。

三项的对抗关系:模型容量越大,能拟合的 ff 越复杂 → 偏差越小;但容量大也意味着对训练样本细节越敏感 → 方差越大。偏差-方差权衡的本质是:模型容量是偏差的敌人也是方差的盟友,总误差的最优点出现在两者交叉之处

实际中,神经网络的双下降(double descent)现象表明 bias-variance 经典图景在过参数化区域并不完整(Belkin et al. 2019Nakkiran et al. 2020 给出了系统性证据)。把神经网络的宽度 / 参数量从小到大扫一遍画测试误差,曲线不是经典的 U 形,而是「降 → 升 → 降」:

  1. 容量较小时按经典 U 形先降到一个经典最优点;
  2. 容量继续增加、方差主导,测试误差上升
  3. 插值阈值(interpolation threshold,模型容量刚好能完美记住整个训练集、训练误差 0\approx 0 的临界点)附近,测试误差冲到一个峰值;
  4. 容量继续增加进入过参数化区域(参数量 \gg 训练样本数),测试误差再次下降,最终值常常低于经典最优点。

这条「降 → 升 → 降」的曲线直接打破了经典 bias-variance「容量越大、方差越大、再加大必然过拟合」的预测——在过参数化区域继续加大模型反而泛化更好,这正是现代深度学习(GPT、LLaMA 等大模型)能靠堆参数取得好性能的实证基础。

学术界对成因尚无完全共识,常见的三条候选解释:

  • SGD 在过参数化区域的隐式正则化:满足训练集的解有无穷多组,SGD 倾向找范数最小的那组,等价于一种自动正则化。
  • Neural Tangent Kernel(NTK)视角:当网络足够宽时,训练动力学接近一个确定性的核方法,其方差性质跟有限宽的经典模型不同。
  • lottery ticket 假说:大网络里藏着稀疏「中奖票」子网络,训练自动选中它、对其余参数不依赖。

模型规模适中时(参数量与训练样本同量级或更少)经典 bias-variance 仍然成立,双下降只在过参数化区域才显现;作为基础视角和正则化设计的指导,经典图景仍是后两节讨论 L1 / L2 / Dropout 的出发点。

5.2 L2 / L1 正则化的贝叶斯本质

最朴素的对抗过拟合手段就是在损失函数里加一项「让权重不要太大」。下文用 NLL(θ)\mathrm{NLL}(\theta) 表示负对数似然(negative log-likelihood,即 logp(Dθ)-\log p(D \mid \theta))——§ 3.3 从 MLE 推 MSE 与交叉熵时最小化的就是它,深度学习里几乎所有「损失函数」本质上都是某种 NLL。常见两种正则化形式:

LL2(θ)=NLL(θ)+λθ22,LL1(θ)=NLL(θ)+λθ1.L_{\text{L2}}(\theta) = \mathrm{NLL}(\theta) + \lambda \|\theta\|_2^2, \qquad L_{\text{L1}}(\theta) = \mathrm{NLL}(\theta) + \lambda \|\theta\|_1.

这两条正则化项在贝叶斯框架下都有非常自然的解释:它们分别是对参数加上不同先验后的 MAP(最大后验)估计

L2 ↔ 高斯先验:假设参数 θ\theta 服从各向同性高斯先验 θN(0,τ2I)\theta \sim \mathcal{N}(0, \tau^2 I)。给定数据 DD,后验对数为

logp(θD)logp(Dθ)+logp(θ)=NLL(θ)12τ2θ22+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}

最大化后验等价于最小化 NLL(θ)+12τ2θ22\mathrm{NLL}(\theta) + \frac{1}{2\tau^2}\|\theta\|_2^2——令 λ=1/(2τ2)\lambda = 1 / (2 \tau^2) 即得 L2(岭回归)L2 正则化 = 高斯先验下的 MAP 估计——「权重不要太大」其实是「权重的先验集中在 0 附近」的等价表述

需要补一条工程实践:θ22\|\theta\|_2^2 在实际中通常只对权重生效、不对 bias 生效——PyTorch 的 weight_decay 默认会把 bias 也一起衰减,但教材与实战指南普遍建议显式排除 bias。这与「bias 应保留自由平移的能力」的直觉一致;在 § 4.3 提到的 bias-free 现代架构里这条要求自动满足。

L1 ↔ 拉普拉斯先验:换成拉普拉斯先验 θjLaplace(0,b)\theta_j \sim \mathrm{Laplace}(0, b),密度 exp(θj/b)\propto \exp(-|\theta_j| / b)。后验对数为

logp(θD)NLL(θ)1bjθj+const,\log p(\theta \mid D) \propto -\mathrm{NLL}(\theta) - \frac{1}{b}\sum_j |\theta_j| + \text{const},

最大化对应最小化 NLL+λθ1\mathrm{NLL} + \lambda \|\theta\|_1λ=1/b\lambda = 1 / b)。L1(Lasso)正则化 = 拉普拉斯先验下的 MAP 估计——选择拉普拉斯而非高斯就引入了稀疏性

为什么 L1 会带来稀疏(许多 θj\theta_j 恰好等于 0),L2 不会?关键在两个先验在 0 处的形状:高斯密度在 0 处光滑(一阶导为 0),拉普拉斯密度在 0 处有「尖峰」(一阶导有跳变)。把后者的负对数当作罚项 θj|\theta_j|,目标函数在 θj=0\theta_j = 0 处有「角点」(非光滑),最优解倾向于把分量精确推到 0;而高斯的负对数是光滑的 θj2\theta_j^2,最优解只会压小分量但不会压到 0。L1 的稀疏性不是巧合——它直接来自拉普拉斯先验密度在 0 处的非光滑性

5.3 Dropout 的集成视角

Dropout(Srivastava et al. 2014)的操作极简:训练时每个神经元以概率 pp 被独立置零(mask),推断时不 dropout 但把激活乘以 (1p)(1 - p) 做尺度补偿。问题是这个看上去像「随机噪声注入」的操作,为什么对泛化能力有这么大帮助?

答案是它在数学上等价于一种巨型集成。考虑一个有 nn 个隐神经元的网络。每个 mini-batch 上随机 mask 出现 2n2^n 种可能的子网络(每个神经元 0 或 1),每个子网络在那一步上独立训练(共享底层权重)。Dropout 不是简单的随机噪声——它在每个 batch 上训练一个不同的子网络,整体形成最多 2n2^n 个子网络的隐式 ensemble

推断时不再 dropout,每个激活乘以 (1p)(1 - p)——这步操作对 softmax 输出层精确等价于 2n2^n 个子网络概率输出的归一化几何平均。推导核心:每个 mask 下第 kk 类 logit zk(m)=Wk(mh)z_k(m) = W_k \cdot (m \odot h)mm 的线性函数,由期望线性性得 Em[zk(m)]=(1p)Wkh\mathbb{E}_m[z_k(m)] = (1 - p) \cdot W_k \cdot h——正是推断时 (1p)(1 - p) scaling 给出的 logit。把它代进 softmax,再用恒等式 eEm[z]=meP(m)z(m)e^{\mathbb{E}_m[z]} = \prod_m e^{P(m) z(m)},分子分母里 exp 的期望就展成 exp 的乘积,归一化后正是子网络 softmax 输出 y^k(m)\hat y_k(m) 的(归一化)几何平均 my^k(m)P(m)\prod_m \hat y_k(m)^{P(m)}

「算术平均的 logit → 几何平均的概率」来自 softmax 的指数运算,是 AM-GM 等式 ezˉ=(ezi)1/Ne^{\bar z} = (\prod 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。后续的 residual connection(ResNet)、归一化与 attention 设计也都可以从「保持谱半径稳定」这个视角统一看待。
  • 正则化的数学本质都是参数的贝叶斯先验。L2 ↔ 高斯先验、L1 ↔ 拉普拉斯先验、Dropout ↔ 隐式 ensemble——它们是同一件事的不同工程化。新的正则化技术(label smoothing、mixup、weight averaging)只要找到对应的先验或集成结构,就能纳入同一条主线。
  • 万能近似定理是表达能力定理,不是泛化定理。「能逼近」≠「能学到」(这是优化问题)≠「在测试集上也能逼近」(这是泛化问题)。深度学习近十年的真正进步都集中在后两条上——优化算法、归一化、正则化、架构先验(CNN / attention / Transformer)共同构成「让 UAT 在实际数据上落地」的工程基础。