Appearance
Informer 调试流程图
Abstract
这份笔记对应 debug_informer.py。 目标不是跑 benchmark,而是把
输入数据 -> embedding -> encoder -> decoder -> 输出这条链路和每一步张量 shape 对上。
1. 整体流程图
2. 一步一步看 tensor
| 阶段 | 张量名 | shape | 含义 |
|---|---|---|---|
| 输入 | x_enc | [2, 96, 7] | encoder 看到的历史序列 |
| 输入 | x_mark_enc | [2, 96, 4] | 历史时间特征,h 频率下对应 4 维 |
| 输入 | x_dec | [2, 72, 7] | decoder 输入,前 48 步是真实历史尾部,后 24 步是 0 |
| 输入 | x_mark_dec | [2, 72, 4] | decoder 这 72 步对应的时间特征 |
| 归一化 | mean_enc | [2, 1, 7] | 每个 batch、每个变量在时间维上的均值 |
| 归一化 | std_enc | [2, 1, 7] | 每个 batch、每个变量在时间维上的标准差 |
| 编码嵌入 | enc_out | [2, 96, 32] | 数值 embedding + 时间 embedding + 位置 embedding 之和 |
| 编码器中间 | EncoderLayer #1 输出 | [2, 96, 32] | 注意力后长度不变 |
| 编码器中间 | ConvLayer 输出 | [2, 49, 32] | distil=True 时做降采样 |
| 编码器输出 | enc_out_final | [2, 49, 32] | 给 decoder 做 cross-attention 的 memory |
| 解码嵌入 | dec_out | [2, 72, 32] | decoder 输入经过 embedding |
| 解码器输出 | decoder output | [2, 72, 7] | 线性投影回变量维度 |
| 最终输出 | output | [2, 24, 7] | 只保留最后 pred_len 步 |
3. 模块参数表
| 模块 | 参数 | 当前值 | 作用 |
|---|---|---|---|
| 输入 batch | B | 2 | batch size |
| 输入窗口 | seq_len | 96 | encoder 输入长度 |
| decoder 历史段 | label_len | 48 | decoder 可以看到的历史长度 |
| 预测窗口 | pred_len | 24 | 最终要输出的未来步数 |
| 变量维 | C | 7 | 多变量时间序列里的变量数 |
| embedding | d_model | 32 | 每个时间步映射后的隐藏维度 |
| FFN | d_ff | 128 | Transformer 中前馈网络的隐藏层维度 |
| 注意力 | n_heads | 4 | 多头注意力头数 |
| 编码器 | e_layers | 2 | encoder layer 数量 |
| 解码器 | d_layers | 1 | decoder layer 数量 |
| ProbSparse | factor | 3 | 稀疏注意力的采样因子 |
| Dropout | dropout | 0.0 | dropout 比例 |
| 时间编码 | embed | timeF | 使用线性时间特征编码 |
| 时间频率 | freq | h | 小时级频率,时间特征维数为 4 |
| 激活函数 | activation | gelu | FFN 激活函数 |
| 注意力输出 | output_attention | False | 是否额外返回 attention map |
| 编码器降采样 | distil | True | 是否启用 Informer 的 distilling |
| 任务类型 | task_name | short_term_forecast | 决定走 short_forecast() 分支 |
4. 参数名到底从哪来
这是你现在最容易混的地方。这里分成两套来源看。
4.1 在 debug_informer.py 里
这里的参数名全部是你手工塞进 SimpleNamespace 里的:
python
configs = SimpleNamespace(
seq_len=96,
label_len=48,
pred_len=24,
enc_in=7,
dec_in=7,
c_out=7,
d_model=32,
...
)也就是说,在这个调试脚本里:
- 参数来源不是 TFB 配置系统
- 参数来源不是数据集自动推断
- 参数来源就是你手写的
configs.xxx
所以这份脚本更适合看“模型内部怎么流”,不适合拿来理解“TFB 框架怎么给参数”。
4.2 在真实 TFB 运行里
真实 TFB 里,参数来源是分层叠加的:
真实路径里比较关键的几个来源:
| 参数名 | 在 debug_informer.py 里 | 在真实 TFB 里 |
|---|---|---|
seq_len | 手写 | adapter 自动需求参数,通常来自 benchmark 的 input_chunk_length |
pred_len | 手写 | 实际上常由 horizon 同步过来 |
label_len | 手写 | 常在 DeepForecastingModelBase 里自动设成 seq_len // 2 |
enc_in/dec_in/c_out | 手写 | 会根据数据列数自动推出来 |
freq | 手写为 h | 会根据时间索引频率自动推出来 |
norm | 这个脚本没显式用 | benchmark 配置里决定是否归一化 |
batch_size/lr/num_epochs | 这个脚本里没用到训练 | 真实训练时来自 adapter 默认值或命令行覆盖 |
5. 哪些参数是 Informer 真正直接用到的
不是所有参数名都会被 Informer 本体用到。
| 参数名 | Informer 直接使用 | 备注 |
|---|---|---|
seq_len | 否 | 主要在别的任务分支或外层数据构造中重要 |
label_len | 是 | decoder 历史段长度 |
pred_len | 是 | 最终输出长度 |
enc_in | 是 | encoder 输入通道数 |
dec_in | 是 | decoder 输入通道数 |
c_out | 是 | projection 输出通道数 |
d_model | 是 | embedding 和 Transformer 主维度 |
n_heads | 是 | 多头注意力头数 |
e_layers | 是 | encoder 层数 |
d_layers | 是 | decoder 层数 |
d_ff | 是 | FFN 隐藏层维度 |
factor | 是 | ProbSparse 注意力因子 |
dropout | 是 | dropout 比例 |
embed | 是 | 时间 embedding 类型 |
freq | 是 | 时间 embedding 输入维度依赖它 |
activation | 是 | FFN 激活函数 |
output_attention | 是 | 是否输出 attention |
distil | 是 | 是否插入 ConvLayer 下采样 |
task_name | 是 | 决定走 short_forecast() 还是别的分支 |
moving_avg | 否 | 这个是共享参数,Informer 本体没直接用 |
num_kernels | 否 | 这个是共享参数,Informer 本体没直接用 |
6. 论文术语到代码对象的映射
| 论文里的词 | 代码里对应什么 |
|---|---|
| Input Time Series | x_enc |
| Time Features | x_mark_enc, x_mark_dec |
| Value Embedding | TokenEmbedding |
| Temporal Embedding | TimeFeatureEmbedding 或 TemporalEmbedding |
| Positional Embedding | PositionalEmbedding |
| ProbSparse Self-Attention | ProbAttention |
| Encoder Stack | Encoder([...]) |
| Distilling | ConvLayer |
| Decoder Input | x_dec |
| Self-Attention in Decoder | DecoderLayer.self_attention |
| Cross-Attention | DecoderLayer.cross_attention |
| Final Projection | nn.Linear(d_model, c_out) |
7. 你现在最该打的断点
按顺序打,不要一上来乱钻。
debug_informer.py 断在
output = model(...)Informer.py 断在
forward()Informer.py 断在
short_forecast()里归一化后Embed.py 断在
DataEmbedding.forward()Transformer_EncDec.py 断在
Encoder.forward()和Decoder.forward()
8. 一句话总结
你现在最该形成的不是“Informer 很复杂”的印象,而是下面这个稳定映射:
原始序列 [B,L,C] -> embedding [B,L,d_model] -> encoder memory [B,L',d_model] -> decoder hidden [B,L_dec,d_model] -> projection [B,L_dec,C] -> 最后截取 pred_len
只要这条链你能复述出来,后面你再去看真实 TFB batch、adapter、训练循环,就不会再散。