第 10 天 · 把捷径修成纯恒等,1001 层也能训
一句话
论文证明:捷径和加法之后的操作都是恒等映射时,信号和梯度能在任意两层之间直接传递。据此提出预激活残差块(BN → ReLU → 卷积),1001 层 ResNet 在 CIFAR-10 上的错误率降到 4.62%。
论文讲了什么
结论先行:残差网络要训得深,捷径上必须什么都不放,加法之后也不要再接 ReLU。作者把 BN 和 ReLU 挪到卷积之前,得到预激活(pre-activation)残差块,1001 层网络因此可以顺利训练。
问题。第 9 天的原版 ResNet 在 1202 层时效果变差。原版块在加法之后接一个 ReLU,捷径并不是纯粹的恒等通道。这个 ReLU 会不会妨碍信号传递?
分析。假设捷径和加法后的操作都是恒等,残差块就是 x[l+1] = x[l] + F(x[l])。逐层展开得到 x[L] = x[l] + ΣF(x[i]),求和范围是 i 从 l 到 L−1。这说明两件事:
- 前向:任何深层特征都等于某个浅层特征加上中间所有残差之和。普通网络则是一长串矩阵连乘。
- 反向:损失对 x[l] 的梯度等于顶层梯度乘以(1 + 残差项的导数)。括号里的 1 让顶层梯度直接到达任何浅层。残差项的导数对整个 mini-batch 恰好等于 −1 的可能性很小,所以梯度不会消失。
实验 1:捷径上放东西都会变差。作者在 110 层 CIFAR-10 网络上试了 5 种捷径:乘常数 0.5、门控、只在捷径上门控、1×1 卷积、对捷径做 dropout。结果全部不如纯恒等捷径,有的难以收敛。原因是捷径上的乘法因子会跨很多层连乘,信号随之爆炸或消失。1×1 卷积的表达能力更强,结果却更差,说明问题出在优化。
实验 2:BN 和 ReLU 放在哪里。作者比较了 5 种排列:原版(加法后 ReLU)、BN 放到加法后、ReLU 放到加法前、只把 ReLU 前置、BN 和 ReLU 都前置(完整预激活)。完整预激活最好,原因有两个:
- 优化更容易:加法后没有 ReLU,捷径成为真正的恒等通道。原版 1001 层网络在训练初期误差下降很慢,预激活版没有这个问题。
- 正则化更好:每个权重层的输入都先经过 BN,训练误差略高,测试误差反而更低。
关键结果。1001 层预激活网络在 CIFAR-10 上错误率 4.62%,在 CIFAR-100 上也明显优于原版。164 层网络在两个数据集上同样有提升。ImageNet 上,200 层预激活网络优于 200 层原版网络。
关键概念
- 恒等映射(identity mapping)
- 输出等于输入的映射 h(x) = x。论文要求捷径和加法后的操作都是恒等,信号才能不经任何变换跨层传递。
- 预激活(pre-activation)
- 残差分支内部按 BN → ReLU → 卷积的顺序排列,归一化和激活放在卷积之前。加法之后不再接任何操作。
- 后激活(post-activation)
- 原版 ResNet 的顺序:卷积 → BN → ReLU,并在加法之后再接一个 ReLU。这个 ReLU 让捷径不再是纯恒等通道。
- 梯度直通项(additive gradient term)
- 反向传播公式里的常数 1。它来自恒等捷径,保证顶层梯度不经过任何权重就能到达浅层。
- 捷径门控(shortcut gating)
- 在捷径上乘一个可学习的门值,Highway Networks 就是这样做的。论文实验显示,它在超深网络里反而妨碍优化。
历史位置:为什么值得读
它是 ResNet 作者的自我修正。第 9 天的论文给出了“残差容易优化”的经验结论,但没有解释为什么,而且 1202 层网络比 110 层差。仅仅 3 个月后,同一团队用一个简单的展开式说清了原理,并把可训练深度推到 1001 层。
它回答了“门控还是不门控”。Highway Networks 和 LSTM(第 2 天)都用门控制信息流。这篇论文用对照实验说明:对超深网络来说,不带参数、永远畅通的捷径更好。
它的影响远超视觉领域。同年的 Wide ResNet 用预激活块研究了宽度与深度的取舍。更重要的是 Transformer:2019 年 GPT-2 的论文明确写到,它把层归一化移到每个子模块的输入端,做法类似预激活残差网络。2020 年有论文专门分析 Pre-LN Transformer,结论是它能去掉学习率预热、训练更稳定。今天的 Pre-Norm 大语言模型都可以追溯到这一天。
学前准备
- 先看第 9 天,理解残差块和退化问题
- 能用链式法则推导一个加法节点的梯度
- 理解 BN 在训练和推理时的不同行为
- 知道 Transformer 的层归一化放在哪里(可后看第 14 天)
在原仓库怎么学
- 读 README.md 的目录,它依次对比后激活块和预激活块,再讲实现和超深网络的训练技巧。对照论文第 2、3 节的公式读。
- 读 implementation.py。找到预激活块,确认顺序是 BN → ReLU → 卷积,并检查加法之后没有激活函数。
- 运行 train_minimal.py。它并排训练 v1 和 v2,并跟踪信号和梯度。数据说明见 data/README.md。
- 用 visualization.py 画两种块的结构差异、信号流和梯度流对比。notebook.ipynb 把预激活原理、搭块、训练超深网络三部分串起来。
- 做 exercises/ 的 5 个练习:01 对比预激活和后激活;02 复现论文的 5 种激活位置;03 训练 100 层以上的网络;04 搭建 1001 层 ResNet;05 比较 v1 和 v2 的迁移效果。答案在 exercises/solutions/。
- 进阶题在 assessments/exercises.md,包括恒等映射分析、BN 位置、深度方向的梯度流,答案在 assessments/solutions.md。
今天再看
预激活思想已经变成大语言模型的默认结构。GPT-2、GPT-3、LLaMA 系列都用 Pre-Norm:每个子层先做归一化,再进注意力或 MLP,结果加回残差流,加法之后不做任何处理。LLaMA 把层归一化换成了更省计算的 RMSNorm,但位置没变。
Pre-Norm 也有代价。残差流一路相加,越往后数值越大,单个深层的贡献会被稀释。层数很多时,后面的层容易变得作用很小。2022 年的 DeepNet 改回 Post-Norm 并调整残差缩放,训练了 1000 层的 Transformer。两种设计的取舍至今仍在讨论。
“保持主干干净”是一条通用原则。不要在信号主通道上放会连乘的东西。今天设计新结构时,人们仍然先检查这一条。
容易卡住的地方
- 预激活网络最后一个块的输出没有经过归一化。必须在全局池化前补一个 BN 和 ReLU,否则分类层的输入分布不稳定。
- 加法之后不要再接 ReLU。接了以后捷径只能传递非负值,残差也无法把特征往负方向修正,这就退回了原版结构。
- 1001 层网络显存占用很大。建议先用论文里的 164 层网络验证代码,因为它训练快很多,而且同样能看出 v1 和 v2 的差距。
- 公式里的“梯度不会消失”依赖两个假设:捷径是恒等,加法后也是恒等。只满足其中一个时,推导不成立。
延伸阅读
- 原论文:Identity Mappings in Deep Residual Networks
- 原仓库第 10 天目录:10_resnet_v2/ —— 代码、笔记本、练习与答案(英文)
- KaimingHe/resnet-1k-layers —— 作者发布的 1001 层网络代码
- Wide Residual Networks —— 用预激活块研究宽度与深度
- On Layer Normalization in the Transformer Architecture —— Pre-LN 与 Post-LN 的理论对比
- DeepNet: Scaling Transformers to 1,000 Layers —— 用 Post-Norm 加缩放训练千层模型