跳转至


课程  因子投资  机器学习  Python  Poetry  ppw  tools  programming  Numpy  Pandas  pandas  算法  hdbscan  聚类  选股  Algo  minimum  numpy  回测  数据标准化  algo  FFT  模式识别  配对交易  GBDT  LightGBM  XGBoost  statistics  CDF  KS-Test  monte-carlo  VaR  过拟合  algorithms  machine learning  strategy  python  sklearn  pdf  概率  数学  面试题  量化交易  策略分类  风险管理  Info  interview  career  强化学习  监督学习  AI量化  复权  数据  tushare  akshare  xgboost  PCA  wavelet  时序事件归因  SHAP  Figures  Behavioral Economics  graduate  arma  garch  人物  职场  Quantopian  figure  Banz  金融行业  买方  卖方  story  量化传奇  rsi  zigzag  穹顶压力  因子  ESG  因子策略  投资  策略  pe  ORB  Xgboost  Alligator  Indicator  factor  alpha101  alpha  技术指标  wave  quant  algorithm  pearson  spearman  套利  LOF  白银  因子分析  Alphalens  涨停板  herd-behaviour  momentum  因子评估  review  SMC  聪明钱  trade  history  indicators  zscore  波动率  lightgbm  顶背离  另类数据  freshman  resources  others  AI  DeepSeek  network  量子计算  金融交易  IBM  weekly  进化论  logic-factor  machine-learning  neutralization  basics  LLT  backtest  backtrader  研报  papers  UBL  quantlib  jupyter-notebook  scikit-learn  pypinyin  qmt  xtquant  blog  static-site  duckdb  工具  colors  free resources  barra  world quant  Alpha  openbb  risk-management  llm  prompt  CANSLIM  Augment  arsenal  copilot  vscode  code  量化数据存储  hdf5  h5py  cursor  augment  trae  Jupyter  jupysql  pyarrow  parquet  数据源  quantstats  几何收益  实盘  clickhouse  polars  滑动窗口  notebook  sqlite  sqlite-utils  fastlite  大数据  PyArrow  UV  Pydantic  Engineering  redis  remote-agent  AI-tools  Moonshot  回测,研报,tushare  dividend 

残差连接:深度学习成功的关键技术

最后更新: 2026-03-23


残差连接:深度学习成功的关键技术

1. 先问一个问题:为什么深度神经网络会退化?

1.1 直觉上的矛盾

直觉告诉我们: 网络越深 → 表达能力越强 → 效果越好

但现实是: 网络太深 → 反而效果变差 → 训练困难

1.2 打个比方:抄书的故事

场景:让你把一本书从第1页抄到第100页 【方法A:直接抄】 第1页 → 第2页 → 第3页 → ... → 第100页 ↓ 中间抄错了10处

【方法B:每抄完一页,对照原文检查】 第1页 → 对照原文 → 检查对不对 第2页 → 对照原文 → 检查对不对 ... 第100页 → 对照原文 → 检查对不对 ↓ 错误被大大减少! 残差连接就是"对照原文"的机制!


2. 什么是残差连接?

2.1 一句话定义

残差连接 = "捷径连接" = 把输入直接传到输出,中间层只需要学习"需要改变的部分"

2.2 数学公式

普通网络(没有残差):

\[ y = F(x) \]

其中 F 是多层神经网络的映射。

带残差连接的网络:

\[ y = F(x) + x \]

即:输出 = 网络学到的变化 + 原始输入

2.3 核心思想

【普通网络的任务】 输入 x = 80分 理想输出 y = 85分 网络需要学习:F(x) = 85

【残差网络的任务】 输入 x = 80分 理想输出 y = 85分 网络需要学习:F(x) = 5(只需要学"差值"5分)

然后 y = F(x) + x = 5 + 80 = 85

优点:学习"差值"比学习"绝对值"容易得多!

3. 图解残差连接

3.1 普通卷积层

3.1 普通卷积层

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
输入 x
│
▼
┌────────────────┐
│   Conv Layer   │
│  (多层神经网络) │
└────────────────┘
│
▼
输出 y = F(x)

3.2 带残差连接的卷积层

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
输入 x ────────┐
│
▼
┌────────────────┐
│   Conv Layer   │
│  (多层神经网络) │
└────────────────┘
│
▼
y' = F(x)
│
│
┌───────────┴───────────┐
│                       │
▼                       ▼
y' + x              投影(维度不同时)
│
▼
输出 y = F(x) + x

3.3 更详细的结构

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
┌─────────────────────────────────────────────────┐
│                  残差块 (Residual Block)         │
│                                                  │
│              输入 x (skip connection)            │
│                 │                               │
│                 │                               │
│    ┌───────────┴───────────┐                     │
│    │                       │                     │
│    ▼                       ▼                     │
│  ┌───────┐           ┌───────────┐               │
│  │LayerNorm│          │ (如果需要) │               │
│  └───────┘           │ 投影层     │               │
│    │                 └───────────┘               │
│    ▼                       │                     │
│  ┌────────┐                 │                     │
│  │ Dilated │                │                     │
│  │ Conv    │                 │                     │
│  └────────┘                 │                     │
│    │                       │                     │
│    ▼                       │                     │
│  ┌────────┐                 │                     │
│  │ ReLU   │                 │                     │
│  └────────┘                 │                     │
│    │                       │                     │
│    ▼                       │                     │
│  ┌────────┐                 │                     │
│  │ Dropout│                 │                     │
│  └────────┘                 │                     │
│    │                       │                     │
│    ▼                       │                     │
│  ┌────────┐                 │                     │
│  │LayerNorm│                 │                     │
│  └────────┘                 │                     │
│    │                       │                     │
│    ▼                       │                     │
│  ┌────────┐                 │                     │
│  │ Dilated │                 │                     │
│  │ Conv    │                 │                     │
│  └────────┘                 │                     │
│    │                       │                     │
│    ▼                       │                     │
│  ┌────────┐                 │                     │
│  │ ReLU   │                 │                     │
│  └────────┘                 │                     │
│    │                       │                     │
│    ▼                       ▼                     │
│  输出 y' ──────────→ (+) ────→ 输出 y = y' + x   │
│                                                  │
└─────────────────────────────────────────────────┘

4. 金融例子:理解残差的价值

4.1 股价预测的类比

场景:预测明天股价 【普通网络思维】 输入:今天收盘价 100元 网络直接学习:明天收盘价 = 105元 问题:学一个绝对值很难,波动大

【残差网络思维】 输入:今天收盘价 100元 网络学习:明天比今天多多少 = +5元 最终:明天价格 = 100 + 5 = 105元 优点:学习"变化量"比"绝对值"简单得多!

4.2 更复杂的例子

【股价 today = 100元】

理想情况1:明天涨到 105元 残差 = +5元 网络输出:100 + 5 = 105 ✓

理想情况2:明天跌到 98元 残差 = -2元 网络输出:100 + (-2) = 98 ✓

理想情况3:明天基本不变 100.5元 残差 = +0.5元 网络输出:100 + 0.5 = 100.5 ✓

关键洞察:

  • 当数据变化很小时,残差 ≈ 0
  • 网络可以轻松输出接近0的值
  • 这比直接预测绝对值要稳定得多

4.3 图示

残差连接的优势

情况A:输入100,输出105(涨5%) 普通:直接学 F(100) = 105 残差:学 F(100) = 5,然后 +100 = 105 ↑ 更容易

情况B:输入100,输出100.5(几乎不变) 普通:直接学 F(100) = 100.5(要精确到0.5) 残差:学 F(100) = 0.5(接近0,容易) ↑ 更容易得多!


5. 为什么残差连接有效?

5.1 梯度流动的角度

没有残差(普通网络): 梯度反向传播: ∂L/∂x = ∂L/∂y · ∂y/∂x = ∂L/∂y · (F'(x) + 1)

优点:即使 F'(x) 很小,加上1也不会梯度消失 → 梯度能顺畅传回去

5.2 恒等映射的角度

假设最优映射就是恒等变换(输入=输出): 普通网络:需要 F(x) = x 但网络很难学到完美的恒等映射

残差网络:只需要 F(x) = 0 因为 y = F(x) + x = 0 + x = x

学"让输出变成0"比"让输出等于输入"容易得多!

5.3 一句话总结

残差连接让网络的学习目标从"绝对映射"变成"相对变化",大大降低了学习难度。


6. 投影层:处理维度不匹配

6.1 问题

当输入和输出的维度不同时,直接相加会报错:

x = [64个特征] ← 输入维度 F(x) = [128个特征] ← 输出维度

x + F(x) = ? ← 无法相加!

6.2 解决方案:投影矩阵

如果维度相同: y = F(x) + x

如果维度不同: y = F(x) + W_proj · x

其中 W_proj 是投影矩阵,把 x 映射到和 F(x) 相同的维度

6.3 投影的种类

1
2
3
4
5
# 维度相同,不需要投影
self.shortcut = nn.Identity()  # 直接传递

# 维度不同,用 1x1 卷积投影
self.shortcut = nn.Conv1d(in_channels, out_channels, kernel_size=1)

7. 代码实现

7.1 简单残差块

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class SimpleResidualBlock(nn.Module):
    """
    简单的残差块
    """
    def __init__(self, channels):
        super().__init__()
        self.conv1 = nn.Conv1d(channels, channels, 3, padding=1)
        self.conv2 = nn.Conv1d(channels, channels, 3, padding=1)
        self.relu = nn.ReLU()

    def forward(self, x):
        """
        x: (batch, channels, length)
        """
        residual = x  # 记住输入

        out = self.conv1(x)
        out = self.relu(out)
        out = self.conv2(out)

        out = out + residual  # 残差连接
        out = self.relu(out)

        return out

7.2 TCN 残差块

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
class ResidualBlock(nn.Module):
    """
    TCN 的残差块,包含两个因果卷积 + LayerNorm + 残差连接
    """
    def __init__(self, in_channels, out_channels, kernel_size=3, dilation=1):
        super().__init__()

        # 第一个卷积
        self.conv1 = CausalConv1D(in_channels, out_channels, kernel_size, dilation)
        self.ln1 = nn.LayerNorm(out_channels)

        # 第二个卷积
        self.conv2 = CausalConv1D(out_channels, out_channels, kernel_size, dilation)
        self.ln2 = nn.LayerNorm(out_channels)

        self.relu = nn.ReLU()
        self.dropout = nn.Dropout(0.2)

        # 投影层(维度不同时)
        if in_channels != out_channels:
            self.shortcut = nn.Conv1d(in_channels, out_channels, 1)
        else:
            self.shortcut = nn.Identity()

    def forward(self, x):
        """
        x: (batch, channels, length)
        """
        residual = self.shortcut(x)  # 保存原始输入

        # 第一个卷积块
        out = self.conv1(x)
        out = out.transpose(1, 2)      # (B, L, C)
        out = self.ln1(out)
        out = out.transpose(1, 2)      # (B, C, L)
        out = self.relu(out)
        out = self.dropout(out)

        # 第二个卷积块
        out = self.conv2(out)
        out = out.transpose(1, 2)
        out = self.ln2(out)
        out = out.transpose(1, 2)
        out = self.relu(out)
        out = self.dropout(out)

        # 关键:残差连接 + 投影
        out = out + residual

        return out

7.3 多层残差网络

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class TCN(nn.Module):
    """
    多层 TCN,每层都有残差连接
    """
    def __init__(self, input_dim, num_channels, kernel_size=3):
        super().__init__()

        layers = []
        for i in range(len(num_channels)):
            in_ch = input_dim if i == 0 else num_channels[i-1]
            out_ch = num_channels[i]
            dilation = 2 ** i  # 膨胀率 1, 2, 4, 8, ...

            layers.append(
                ResidualBlock(in_ch, out_ch, kernel_size, dilation)
            )

        self.network = nn.ModuleList(layers)

    def forward(self, x):
        """
        x: (batch, channels, length)
        """
        for block in self.network:
            x = block(x)  # 每层都有残差连接
        return x

8. 对比:有没有残差连接

8.1 训练角度

特性 普通网络 带残差的网络
梯度流动 逐层衰减 直接传递到前面层
训练难度 深网络难训练 深网络也能训练
恒等映射 难以学到 容易学到(F=0)
参数量 相同 相同(多了shortcut)

8.2 金融预测场景

场景:预测下个月股价

【普通网络:直接预测】 输入:过去30天数据 输出:下个月价格 = 105元

问题: - 需要记住"起点"是100元 - 中间预测错了会累积误差 - 网络容量被用来记忆绝对值

【残差网络:预测变化】 输入:过去30天数据 输出:变化量 = +5元 最终:100 + 5 = 105元

优点: - 不需要记住绝对价格 - 关注"变化"这个核心问题 - 更稳定,更容易训练

8.3 形象比喻

【普通网络】像接力赛跑 第1棒 → 第2棒 → 第3棒 → 第4棒 → 终点 ↓ ↓ ↓ 每棒都 每棒都 每棒都 可能错 可能错 可能错 误差累积 误差累积 误差累积

【残差网络】像跑步 + 导航 跑步(多层网络) ↓ 同时有GPS导航(残差连接) ↓ 每跑一段就对照GPS纠偏 ↓ 不会跑偏太远


9. 残差连接在 TCN 中的作用

9.1 TCN 为何需要残差

TCN 的问题:

  • 网络很深(4-10层)
  • 每层都有因果卷积
  • 梯度容易消失 残差的作用:

  • 每层都有"捷径"

  • 梯度直接传回去
  • 训练稳定

9.2 多层感受野叠加

Layer 1 (d=1): 看到 3 个点 + 残差(看到全部原始输入) ↓ Layer 2 (d=2): 看到 5 个点 + 残差(保留 Layer 1 的信息) ↓ Layer 3 (d=4): 看到 9 个点 + 残差(保留 Layer 1-2 的信息) ↓ Layer 4 (d=8): 看到 17 个点 + 残差(保留 Layer 1-3 的信息) ↓ 总的感受野 = 31 个点 信息层层传递,不会丢失


10. 总结

问题 答案
什么是残差? 残差 = 目标值 - 输入值 = 需要学习的变化量
为什么叫残差连接? 因为它连接的是"残差"(变化量)
为什么有效? 学习"变化"比"绝对值"容易
梯度为什么不会消失? 因为有 +1 的梯度(恒等映射)
什么时候需要投影? 输入输出维度不同时
TCN 为什么要用残差? 让深层网络稳定训练,保留浅层信息

一句话理解残差连接:

残差连接就是"搭便车"——让原始信息坐"直通车"传到后面,同时让网络专门学习"还需要改变什么"。

公式记忆:

\[ y = F(x) + x \quad \text{或} \quad y = F(x) + W_{proj} \cdot x \]

解读:输出 = 网络学到的变化 + 原始输入