残差连接:今天真正弄懂
先记住:一句话定义 + 一句记忆口诀
一句话定义:残差连接就是让一层或几层网络不要只学“完整答案”,而是学“在原输入上需要改多少”,最后把“原输入”和“改动量”相加。口诀:不会全重做,就学改一点;原路加旁路,深层更好练。
生活类比:你在改一段字幕。普通网络像“把整段字幕重新写一遍”。残差连接像“保留原字幕,只标出需要修改的地方”。如果原字幕已经差不多对了,你只要改几个字。这样更省力,也更不容易改坏。
必要公式:
常见残差块写法是:
`y = F(x) + x`
逐个解释:
- `x`:输入。比如一段音频特征、一帧图像特征、一个 token 特征。
- `F(x)`:网络层学到的“变化量”。也叫残差分支。它通常由卷积、线性层、归一化、激活函数等组成。
- `+`:逐元素相加。要求 `F(x)` 和 `x` 的形状一样。
- `y`:输出。它等于“原来的 x”加上“网络认为要补充或修正的部分”。
如果形状不一样,就常写成:
`y = F(x) + P(x)`
- `P(x)`:投影分支。常用 `1x1` 卷积或线性层,把 `x` 的维度变成和 `F(x)` 一样。
- 例如通道数从 64 变成 128,就不能直接加,要先用 `P(x)` 对齐形状。
它解决什么问题:
核心问题:深层网络难训练。
没有残差连接时,网络层数加深后,经常出现:
- 梯度传不到前面。
- 前面层学得很慢。
- 训练误差反而变高。
- 模型明明更深,却不一定更好。
- 网络容易把已经有用的表示“改坏”。
残差连接的好处:
- 给信息一条“直通路”。
- 给梯度一条“回传捷径”。
- 让网络更容易学“微调”,而不是每层都重建全部表示。
- 如果某些层暂时没学好,至少 `x` 可以直接过去,不至于完全断掉。
在音视频理解里可以这样想:
- 语音特征里已经有音色、能量、韵律信息。
- 视频帧特征里已经有人脸、嘴部动作、场景信息。
- 后面的层不必每次都推翻重来。
- 它只需要逐步修正、补充、更抽象。
残差连接最常见公式是什么?
残差连接主要缓解什么训练问题?
残差连接和拼接连接的核心区别是什么?
发展流程:
- 之前怎么做
早期深度网络通常是简单堆层:
`输入 → 层1 → 层2 → 层3 → ... → 输出`
每一层都把前一层输出完全变换一次。
问题是:层数变深后,训练变难。不是只因为过拟合,也不是只因为参数多,而是优化本身变难。一个很深的网络,理论上至少应该能学成“前面浅层网络 + 后面几层什么都不做”。但实际训练时,它不容易自动学出“什么都不做”的恒等映射。
- 为什么出现残差连接
残差连接的关键想法是:
如果最优情况是“保持原样”,那网络不用费力学 `H(x)=x`。 只要让 `F(x)=0`,就有:
`y = F(x) + x = x`
这比让一堆非线性层精确学出“输入等于输出”容易得多。
也就是说:
- 普通网络学目标:`H(x)`
- 残差网络改成学:`F(x) = H(x) - x`
- 最后再还原:`H(x) = F(x) + x`
所以它叫“残差”。因为它学的是“目标和输入之间的差”。
- 现在怎么用
现在残差连接非常常见。它不只在 ResNet 里用,也在 Transformer、Conformer、语音模型、视频模型、多模态模型里大量出现。
典型位置:
- 卷积网络:一个残差块包住几层卷积。
- Transformer:自注意力模块外面有残差连接,前馈网络外面也有残差连接。
- 音频模型:卷积块、时序建模块、注意力块中常用。
- 视频模型:2D/3D 卷积块、时空注意力块中常用。
- 说话人日志:说话人嵌入提取网络、语音分割模型、音频 Transformer/Conformer 编码器里常见。
主流模型中的实际位置与用法:
- ResNet 图像/视频骨干
一个典型残差块:
`输入 x → 卷积 → 归一化 → 激活 → 卷积 → 归一化 → 加回 x → 激活`
它常用于图像帧特征提取。视频模型会把它扩展到时空卷积,比如处理连续帧。
- Transformer 编码器
常见结构:
`x = x + SelfAttention(x)` `x = x + FeedForward(x)`
意思是:
- 注意力模块负责补充“上下文关系”。
- 前馈网络负责做“每个位置的非线性变换”。
- 残差连接保留原始表示,避免每个模块都完全覆盖旧信息。
- 音频理解
在语音识别、音频事件检测、说话人识别里,输入常是 log-mel 频谱或其他声学特征。
残差连接常出现在:
- CNN 声学前端。
- TDNN/ResNet 风格说话人嵌入网络。
- Conformer 编码器。
- 音频 Transformer 块。
它的作用是让模型在多层处理中保留低层声学线索,比如音色、能量、频谱结构,同时逐层加入更高层语义或说话人信息。
- 说话人日志 diarization
说话人日志要回答:“什么时候谁在说话”。
残差连接常间接帮忙:
- 在说话人嵌入网络中,提取更稳定的 speaker embedding。
- 在分帧分类网络中,帮助长层数模型稳定训练。
- 在 Transformer/Conformer 时序编码器中,保留局部声学信息,同时建模长时间上下文。
- 在多麦克风或音视频 diarization 中,帮助融合音频、视觉、人脸、嘴动等特征。
与相近概念的区别:
- 残差连接 vs 跳跃连接
跳跃连接是大类。残差连接是其中一种。
- 跳跃连接:只要信息跨过一些层传过去,都算。
- 残差连接:特指把输入和分支输出相加,常见形式是 `F(x)+x`。
所以:残差连接属于跳跃连接,但不是所有跳跃连接都是残差连接。
- 残差连接 vs 拼接连接
拼接连接常见于 U-Net、DenseNet:
`y = concat(F(x), x)`
残差连接是:
`y = F(x) + x`
区别:
- 相加:形状必须一样;输出维度通常不变。
- 拼接:沿通道维拼起来;输出维度会变大。
- 相加更轻量。
- 拼接保留信息更显式,但计算和内存更大。
- 残差连接 vs 恒等映射
恒等映射是 `y=x`,完全不改。
残差连接是 `y=F(x)+x`,既能保留原输入,也能加入修改量。
如果 `F(x)=0`,残差连接就退化成恒等映射。
- 残差连接 vs 门控连接
门控连接会学一个“开关”:
`y = gate * F(x) + x`
或者类似形式。
残差连接通常直接相加,没有显式开关。
门控更灵活,但也更复杂。残差连接更简单稳定。
- 残差连接 vs 归一化
归一化,比如 BatchNorm、LayerNorm,主要让数值分布更稳定。
残差连接主要让信息和梯度更容易通过。
它们经常一起用,但解决的问题不完全一样。
当前局限:
事实:
- 残差连接不是万能药。
- 它不能保证模型一定更准。
- 如果模型设计很差,只加残差也救不了。
- 如果 `F(x)` 和 `x` 形状不一致,必须做投影或调整。
- 残差相加可能让特征尺度变大,所以常配合归一化、缩放或合适初始化。
- 在非常深的网络里,残差结构仍然需要仔细设计,比如归一化放在前面还是后面。
未来可能作用:
事实部分:
- 残差连接已经是深度模型的基础组件。
- 它在 CNN、Transformer、语音模型、视频模型、多模态模型中都会继续使用。
- 它对训练深层网络仍然很重要。
推测部分:
- 未来模型可能会更常使用“可学习残差强度”,让模型决定保留多少旧信息、加入多少新信息。
- 在音视频说话人日志中,残差结构可能继续用于更长上下文建模,比如长会议、多人重叠语音、音视频联合建模。
- 多模态模型中,残差连接可能帮助模型在融合时不过度破坏单模态信息,例如保留纯音频说话人线索,同时加入人脸和嘴动信息。
学习资料建议:
Dive into Deep Learning 的 ResNet 章节适合用来“看代码理解”。重点看两点:第一,残差块怎么写;第二,为什么加了旁路后深层网络更容易训练。不要只背 ResNet 名字,要亲手跑一个小残差块。
- 为什么说残差连接让网络更容易学“什么都不做”?
- 如果 `F(x)` 的输出形状是 `[32, 128]`,而 `x` 是 `[32, 64]`,为什么不能直接相加?应该怎么办?
- 在 Transformer 里,为什么注意力模块和前馈模块外面通常都要加残差连接?