Skip to content

学习缺口与自检 Checkpoints

Abstract

这篇只回答两个问题:

  1. 你按当前这套 BFS 学下来,还欠缺什么
  2. 你怎么用最小例子做自检,避免重新掉进 DFS 式钻牛角尖

0. 先给结论

你现在已经完成了两件关键事情:

  1. 你已经把 最小完整例子 串通了
    也就是:

    • debug_tfb_framework.py
    • run_benchmark.py + ETTh1 + DLinear + rolling_forecast
  2. 你已经建立了一套 正确的代码理解方法
    也就是:

    • 自顶向下
    • 先顺序,后分块
    • 先 BFS,后 DFS
    • 用抽象索引树辅助理解真实执行链

你现在真正欠缺的,不是继续把 DLinear 往更细的数学层面钻透,而是下面这 4 个能力。


1. 你当前真正欠缺的 4 个能力

1.1 缺“口头压缩复述”的能力

你已经有很多文档,但不等于你已经真正掌握。

真正掌握的标准不是:

  • 你看过多少图
  • 你记住多少函数名

而是:

你能不能不用看文档,把最小例子的完整主链压缩讲出来。

你现在最大的风险不是“不会”,而是:

看懂时觉得懂,离开文档后无法重建。


1.2 缺“同层横向对照”的能力

你已经把一条路径打通了:

  • ETTh1
  • DLinear
  • rolling_forecast
  • transformer_adapter

但你还没有系统比较:

  • DLinear vs Informer
  • rolling_forecast vs fixed_forecast
  • transformer_adapter vs 其他 adapter
  • debug_tfb_framework.py vs 完整 benchmark

也就是说,你现在的理解是 1x1 的:

  • 一个数据
  • 一个模型
  • 一个策略

下一步要慢慢扩成 m x n 的分支树


1.3 缺“分支树地图”的能力

你已经能跟住主线:

text
run_benchmark -> pipeline -> eval_model -> strategy -> _eval_batch -> forecast_fit / batch_forecast

但你还没有真正建立这套仓库的“分支树地图”,比如:

  • 不是所有策略都走 rolling_forecast
  • 不是所有模型都走 TransformerAdapter
  • 不是所有任务都走 forecast
  • 不是所有模型都用 batch 预测

你现在知道主干,但还没系统掌握树的旁枝。


1.4 缺“从框架切回模型/论文”的迁移能力

你已经能把 DLinear 放回 benchmark 坐标里。

但真正对后续研究更重要的是:

你能不能把 Informer / PatchTST / 其他模型 也用同样的框架坐标重新放一遍。

如果不能迁移,那当前学习仍然是“记住了这个例子”,而不是“掌握了方法”。


2. 你当前阶段的正确定位

如果要给你现在的状态下定义,我会这样写:

你已经完成了“最小科研脚手架理解”的第一轮。

更具体一点:

  • 你不是“只会跑命令”
  • 也不是“已经具备独立研究判断”
  • 你现在处于:

框架主链已打通,正在从单例理解过渡到分支树理解。

所以当前阶段最应该做的,不是:

  • 继续加深一个函数的局部细节
  • 继续补更多超细文档

而是:

  1. 先做自检
  2. 再做横向扩展
  3. 再把方法迁移到第二个模型

3. 最小例子自检标准

最小例子就是:

  • debug_tfb_framework.py
  • run_benchmark.py + ETTh1 + DLinear + rolling_forecast

你必须至少能独立回答下面 4 类问题。


4. Checkpoints A:最小例子的高层主链

A1

你能说出:

python
log_filenames = pipeline(
    data_config,
    model_config,
    evaluation_config,
)

这句的第一性是什么。

正确标准:

pipeline(...) 负责把已经组装好的 data/model/evaluation 配置,变成最终落盘的日志文件路径列表。

A2

你能说出 pipeline(...) 的四大块。

正确标准:

  1. 准备数据
  2. 准备模型工厂
  3. 执行评测
  4. 收集结果并写日志

A3

你能说出 eval_model(...) 的第一性。

正确标准:

把模型工厂 + 序列列表 + 评测配置,变成已提交的评测任务和可收集结果的 EvalResult

A4

你能说出 RollingForecast._eval_batch(...) 的四段。

正确标准:

  1. 配置与切数
  2. 训练
  3. 预测
  4. 打分与收尾

5. Checkpoints B:训练线

B1

你能说出 _eval_batch(...) 里的训练入口为什么是 fit_method(...)

正确标准:

fit_method 是统一训练入口变量,用来兼容 forecast_fit(...)fit(...) 两种模型接口。

B2

你能说出当前例子里为什么实际走的是 forecast_fit(...)

正确标准:

因为当前模型对象提供了 forecast_fit(...),所以 fit_method = model.forecast_fit

B3

你能说出 forecast_fit(...) 到训练循环入口前做了哪几件事。

正确标准:

  1. covariates 合并
  2. 数据依赖参数补齐
  3. _init_model()
  4. train_val_split
  5. forecasting_data_provider
  6. criterion / optimizer / early_stopping

B4

你能说出训练循环里每个 batch 的真正核心步骤。

正确标准:

text
取 batch
-> _process(...)
-> output 与 target 对齐
-> loss
-> backward
-> optimizer.step

B5

你能说出当前例子里为什么 target(4,72,7) 变成 (4,24,7)

正确标准:

因为监督时只取未来 horizon=24 步: target[:, -config.horizon:, :]


6. Checkpoints C:预测线

C1

你能说出 _eval_batch(...) 的预测子块不是“一次性预测 test_data”,而是在做什么。

正确标准:

它先生成 rolling 位置 index_list,再用 batch maker 把这些位置组织成预测请求,再批量送进 batch_forecast(...)

C2

你能说出 batch_forecast(...) 的第一性。

正确标准:

从 batch maker 拿一批 rolling 请求,做预处理、构造时间标记,再进入 _perform_rolling_predictions(...)

C3

你能说出 _perform_rolling_predictions(...) 的第一性。

正确标准:

通过重复调用 _process(...),不断滚动生成新的预测片段,直到累积够目标 horizon。

C4

你能说出为什么当前 DLinear 例子里 _perform_rolling_predictions(...) 通常一轮就够。

正确标准:

因为当前目标 horizon = 24,而单轮前向本身就输出 24 步。


7. Checkpoints D:adapter 与模型

D1

你能说出 adapter 的第一性。

正确标准:

adapter 是接口翻译层,把框架统一接口翻译成具体模型 forward 接口。

D2

你能说出 TransformerAdapter._process(...) 做了什么。

正确标准:

  1. target 构造 dec_input
  2. self.model(input, input_mark, dec_input, target_mark)
  3. 返回 {"output": output}

D3

你能说出当前例子里 dec_input 的 shape 和语义。

正确标准:

  • shape:(4, 72, 7)
  • 语义:label_len 段历史尾部 + horizon 段零填充

D4

你能说出 DLinear 在统一四输入接口里真正主要依赖哪个输入。

正确标准:

主要依赖 x_enc

D5

你能说出 DLinear 的真实计算主干。

正确标准:

text
forward
-> forecast(x_enc)
-> encoder(x_enc)
-> series_decomp
-> Linear_Seasonal / Linear_Trend

8. Checkpoints E:当前例子的关键数字

这些数字你不一定要背死,但至少要能解释来源。

E1

为什么:

  • series.shape = (17420, 7)

E2

为什么:

  • train_length = 13936
  • test_length = 3484

E3

为什么:

  • label_len = 48

E4

为什么训练 batch 是:

  • input = (4, 96, 7)
  • target = (4, 72, 7)

E5

为什么 DLinear 输出是:

  • output = (4, 24, 7)

E6

为什么 rolling 评测里只取:

  • num_rollings = 48

9. 一套最实用的自检方法

不要做开放式复习。
直接按下面 3 步。

第一步:空白复述

不看文档,写出:

text
run_benchmark
-> pipeline
-> eval_model
-> strategy.execute
-> _eval_batch
-> 训练 / 预测 / 打分

如果这条链写不出来,说明高层主线还没稳定。

第二步:补 8 个关键变量

写出:

  • series.shape
  • train_length
  • test_length
  • seq_len
  • label_len
  • horizon
  • dec_input.shape
  • output.shape

如果写不出来,说明“流程”和“具体例子”还没绑定。

第三步:讲两条支线

分别口头讲:

  • 训练线
  • 预测线

如果你只能讲训练线,不能讲预测线,说明 _eval_batch(...) 仍然没有真正闭环。


10. 你现在最适合的下一轮 BFS 扩展

你已经打通了 1x1

  • 一个数据:ETTh1
  • 一个模型:DLinear
  • 一个策略:rolling_forecast

下一步应该开始构建分支树。

第一组扩展:模型维度

从:

  • DLinear

扩到:

  • Informer

目标不是重新学一遍整个框架,而是建立对照:

  • 哪些部分不变
  • 哪些部分变了

第二组扩展:策略维度

从:

  • rolling_forecast

扩到:

  • fixed_forecast

目标是理解:

  • 为什么 _eval_batch(...) 的组织方式不同
  • 什么是“同一模型,不同评测协议”

第三组扩展:adapter 维度

从:

  • transformer_adapter

扩到:

  • 其他 adapter 家族

目标是理解:

  • 框架统一接口和模型家族接口之间到底有哪些不同风格的翻译层

11. 你现在不应该做什么

不要继续深挖一个函数的局部实现

比如:

  • 一直抠 SequentialBackend
  • 一直抠 DLinear.encoder 数学细节
  • 一直抠 DataLoader 内部机制

这会重新掉回 DFS 陷阱。

不要在没有分支树地图前就急着找创新点

你现在最该做的不是:

  • “这个框架我能怎么改出论文”

而是:

先把“这套框架里有哪些稳定主干,哪些是可替换分支”建立清楚。


12. 如果用一句话描述你下一阶段该做什么

从“打通一个最小例子”进入“给这个最小例子建立分支树地图”。

也就是:

  1. 先用 checkpoints 自检最小主链
  2. 再做第二个模型的映射
  3. 再做第二种策略的映射
  4. 慢慢把 1x1 扩成 m x n

13. 最终完成标准

你下一阶段真正完成,不是指你又多写了几篇文档。

而是你能做到这三件事:

  1. 你能独立复述最小主链,不依赖文档
  2. 你能把第二个模型放进同一坐标系里
  3. 你能说明哪些是框架固定逻辑,哪些是模型/策略分支

如果这三件事做到了,你就不再只是“看懂了一个例子”,而是:

开始具备把 TFB 当科研脚手架使用的能力。

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