Skip to content

Informer 调试 Checkpoints

Abstract

这篇只服务于当前这一轮目标:

在不改变 benchmark 外壳的前提下,把模型从 DLinear 换成 Informer,建立 Informer 与代码的映射。

1. 当前例子

当前最小命令:

text
--config-path rolling_forecast_config.json
--data-name-list ETTh1.csv
--model-name time_series_library.Informer
--adapter transformer_adapter
--model-hyper-params {"batch_size":4,"d_model":32,"d_ff":128,"dropout":0.0,"lr":0.0001,"num_epochs":1,"num_workers":0,"seq_len":96,"horizon":24}
--strategy-args {"horizon":24,"tv_ratio":0.8,"train_ratio_in_tv":0.75,"stride":24,"num_rollings":48}
--num-workers 1
--timeout 600
--save-path debug\ETTh1_Informer_rolling_min

这轮调试里,不变的部分:

  • 数据集:ETTh1.csv
  • strategy:rolling_forecast
  • adapter:transformer_adapter
  • 外层 benchmark 主线

变化的部分:

  • model-name: DLinear -> Informer

2. 这轮调试的第一性

这轮不是重新学 benchmark。

这轮只回答一个问题:

同一套 benchmark 壳下,Informer 是从哪一行开始替代 DLinear,并且内部主链怎么组织。


3. 断点顺序

按这个顺序打,不要乱跳:

  1. TransformerAdapter._process(...)
  2. Informer.forward(...)
  3. Informer.short_forecast(...)
  4. DataEmbedding.forward(...)
  5. Encoder.forward(...)
  6. Decoder.forward(...)

对应文件:


4. Checkpoint 1:外层哪里开始分叉

问题

在完整 benchmark 主线里,哪一行代码之前和 DLinear 完全一样,哪一行开始真正进入 Informer?

- 参考答案

TransformerAdapter._process(...) 为止,外层主线和 DLinear 基本一样: run_benchmark -> pipeline -> eval_model -> _eval_batch -> forecast_fit / batch_forecast -> self._process(...)

真正开始分叉的是:

python
output = self.model(input, input_mark, dec_input, target_mark)

当前模型是 Informer 时,这里就进入:

python
Informer.forward(x_enc, x_mark_enc, x_dec, x_mark_dec)

5. Checkpoint 2:统一四输入接口

问题

TransformerAdapter._process(...) 传给 Informer 的四个输入分别是什么?

- 参考答案

映射关系是:

  • input -> x_enc
  • input_mark -> x_mark_enc
  • dec_input -> x_dec
  • target_mark -> x_mark_dec

其中:

  • input.shape = (4, 96, 7)
  • input_mark.shape = (4, 96, 4)
  • dec_input.shape = (4, 72, 7)
  • target_mark.shape = (4, 72, 4)

6. Checkpoint 3:dec_input 是怎么来的

问题

为什么 Informer 不直接吃 target,而要先构造 dec_input

- 参考答案

TransformerAdapter._process(...) 会构造:

python
dec_input = target[:, :label_len, :] + zeros[horizon]

在当前例子里:

  • label_len = 48
  • horizon = 24

所以:

  • 前 48 步是历史尾部
  • 后 24 步是未来零占位

这符合 Informer/Transformer forecasting 的 decoder 输入语义。


7. Checkpoint 4:Informer.forward(...) 做了什么分派

问题

进入 Informer.forward(...) 后,这个例子实际走的是哪条分支?

- 参考答案

当前 task_name 在 adapter 默认配置里是 short_term_forecast

所以 Informer.forward(...) 会走:

python
short_forecast(x_enc, x_mark_enc, x_dec, x_mark_dec)

然后最后返回:

python
dec_out[:, -self.pred_len :, :]

也就是 (B, pred_len, C)


8. Checkpoint 5:embedding 前后 shape

问题

DataEmbedding 前后,张量 shape 怎么变?

- 参考答案

当前输入:

  • x_enc.shape = (4, 96, 7)
  • x_mark_enc.shape = (4, 96, 4)
  • x_dec.shape = (4, 72, 7)
  • x_mark_dec.shape = (4, 72, 4)

经过 DataEmbedding 后:

  • encoder 侧变成 (4, 96, d_model)
  • decoder 侧变成 (4, 72, d_model)

当前 d_model = 32,所以实际可理解为:

  • enc_out.shape = (4, 96, 32)
  • dec_out.shape = (4, 72, 32)

9. Checkpoint 6:x_mark_* 在 Informer 里为什么重要

问题

为什么在 DLinear 那里你可以先弱化 x_mark_*,但 Informer 里必须重视它?

- 参考答案

因为 Informer 的 DataEmbedding 会显式把:

  • value_embedding(x)
  • temporal_embedding(x_mark)
  • position_embedding(x)

加在一起。

所以 x_mark_enc / x_mark_dec 不只是陪衬,而是 embedding 的一部分。

在小时频率 freq='h' 下,x_mark 常见对应 4 维时间特征。


10. Checkpoint 7:Encoder 在主链里的职责

问题

Encoder.forward(...) 在当前主链里的职责是什么?

- 参考答案

Encoder 接收的是 embedding 后的历史窗口表示:

  • 输入大致是 (4, 96, 32)

它的职责是:

  • 用多层 EncoderLayer
  • 结合 AttentionLayer
  • 在 Informer 中用 ProbAttention
  • 把历史窗口编码成更高层的上下文表示

它输出:

  • enc_out
  • attns

11. Checkpoint 8:Decoder 在主链里的职责

问题

Decoder.forward(...) 在当前主链里的职责是什么?

- 参考答案

Decoder 接收两类输入:

  • dec_out:decoder 侧 embedding 后的输入
  • enc_out:encoder 输出的上下文

它的职责是:

  • 先在 decoder 自身序列上做 attention
  • 再和 encoder 输出做 cross attention
  • 最后通过 projection 映射回 c_out

当前例子里可理解为:

  • 输入大致 (4, 72, 32)
  • 输出大致 (4, 72, 7)

12. Checkpoint 9:为什么最终输出还是 (4, 24, 7)

问题

Informer 明明 decoder 输出长度是 72,为什么最后外层看到的还是 (4, 24, 7)

- 参考答案

因为 Informer.forward(...) 最后只取:

python
dec_out[:, -self.pred_len :, :]

当前:

  • pred_len = 24
  • c_out = 7

所以最终返回:

  • output.shape = (4, 24, 7)

13. Checkpoint 10:和 DLinear 的真正边界

问题

这轮对照里,哪些部分和 DLinear 完全一样,哪些部分是真正新学的?

- 参考答案

完全一样的部分:

  • run_benchmark.py
  • pipeline(...)
  • eval_model(...)
  • RollingForecast._eval_batch(...)
  • forecast_fit(...)
  • 训练循环
  • TransformerAdapter._process(...)

真正新学的部分:

  • Informer.forward(...)
  • short_forecast(...)
  • DataEmbedding
  • Encoder
  • Decoder
  • ProbAttention

14. 这一轮过关标准

如果你能不看文档回答下面 5 句,这轮就算过关:

  1. Informer 在完整 benchmark 里的外层坐标和 DLinear 哪些相同。
  2. TransformerAdapter._process(...) 传给 Informer 的四个输入分别是什么。
  3. DataEmbedding 前后 shape 怎么变化。
  4. EncoderDecoder 在主链里的职责分别是什么。
  5. 为什么最终输出仍然是 (B, pred_len, C)

15. 下一步

这轮 checkpoints 通过后,再按这个顺序继续:

  1. 单独写清 Informer.forward(...) 主链
  2. 单独写清 DataEmbedding
  3. 单独写清 Encoder
  4. 最后再看 Decoder

*记录并在线阅读我的笔记*