Appearance
DLinear 在完整 benchmark 中的全链坐标总图
Abstract
这篇不是某一层的下钻文档。
它对应的是:
- 对
21-32主线文档的收束复盘- 用 DLinear 这个最小例子,把训练线、预测线和外层 benchmark 坐标重新压回一张总图
Abstract
这篇不是再开新分支。
它只做一件事:
把你已经拆开的
run_benchmark -> pipeline -> eval_model -> _eval_batch -> DLinear重新压回一条完整主线。目标是回答:
DLinear 在完整 benchmark 里,到底处在哪,输入从哪来,训练和预测分别怎么进入它。
1. 这篇在整个文档树里的位置
这篇是收束文档,不是新的 BFS 层级。
它建立在这些文档之上:
- 10-run_benchmark与pipeline-总图
- 25-Level5-_eval_batch四段总览
- 26-Level6-5B-训练子块-fit_method与forecast_fit
- 27-Level6-5C-预测子块
- 29-Level7-forecast_fit训练循环
- 30-Level8-_process到DLinear.forward
- 31-Level7-batch_forecast主链
- 32-Level8-_perform_rolling_predictions
2. 第一性
从第一性讲,这条完整链只是在回答一个问题:
一条命令怎样最终让 DLinear 在
ETTh1.csv上完成训练、rolling 预测、打分和日志落盘。
把这个问题拆开后,本质只有 5 层:
- 最外层实验调度
- 单模型单序列评测组织
- rolling 任务主体
- 模型训练主链
- 模型预测主链
3. 一张总图
这张图是整套学习材料最关键的一张。
它明确了:
- DLinear 不在外层
- DLinear 也不直接出现在
pipeline(...) - DLinear 真正出现两次:
- 训练线前向
- 预测线前向
4. 抽象索引树
这棵树的意义是:
让你在脑中快速定位 DLinear 在整套 benchmark 里的抽象坐标,而不是只记一条长调用栈。
5. 顺序和树结构怎么一起看
这条链有两个维度:
5.1 顺序维度
回答:
代码执行时先后发生什么。
5.2 索引维度
回答:
为了理解这条链,人脑应该把它分成哪几个层次和子树。
你之前提的那个类比是对的:
像 B+ 树一样,一边是线性执行路径,一边是人脑建立的索引结构。
这篇文档就是把这两个维度重新压到一起。
6. 当前例子的完整落地
当前命令:
text
python scripts/run_benchmark.py
--config-path rolling_forecast_config.json
--data-name-list ETTh1.csv
--model-name time_series_library.DLinear
--adapter transformer_adapter
--model-hyper-params {"batch_size":4,"d_model":32,"d_ff":128,"moving_avg":25,"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_DLinear_rolling_min_allmetrics会落成下面这组关键数字:
数据侧
ETTh1.shape = (17420, 7)
train/test 切分
tv_ratio = 0.8train_length = 13936test_length = 3484
模型参数
seq_len = 96label_len = 48horizon = pred_len = 24batch_size = 4enc_in = dec_in = c_out = 7
训练 batch
input.shape = (4, 96, 7)target.shape = (4, 72, 7)input_mark.shape = (4, 96, 4)target_mark.shape = (4, 72, 4)
adapter 构造
dec_input.shape = (4, 72, 7)
DLinear 输出
output.shape = (4, 24, 7)
rolling 配置
stride = 24num_rollings = 48
7. 训练线和预测线的对照
7.1 训练线
训练线里,DLinear 的角色是:
提供每个训练 batch 的预测输出,供外层训练循环算 loss 和更新参数。
7.2 预测线
预测线里,DLinear 的角色是:
在 rolling 预测内循环中,不断生成未来预测片段,直到累积够目标 horizon。
8. DLinear 在这条链里到底“是不是核心”
答案要分两层说。
8.1 从 benchmark 框架角度
DLinear 不是最外层核心。
最外层核心是:
pipeline(...)eval_model(...)RollingForecast._eval_batch(...)
因为它们决定:
- 怎么切数据
- 怎么训练
- 怎么 rolling 预测
- 怎么打分
- 怎么保存结果
8.2 从模型计算角度
DLinear 是真实计算核心。
因为最终真正做数值映射的是:
DLinear.forward(...)DLinear.encoder(...)
也就是说:
外层决定实验协议,DLinear 决定模型算什么。
9. 为什么 adapter 这一层必须存在
如果没有 TransformerAdapter._process(...),外层训练循环就必须直接知道:
- decoder 输入怎么构造
- 每个模型 forward 需要什么形参
- 哪些模型需要
x_mark - 哪些模型只真正用
x_enc
有了 adapter 后,外层训练循环只需要知道:
python
out_loss = self._process(...)
output = out_loss["output"]所以 adapter 的意义是:
把“框架统一接口”翻译成“具体模型接口”。
10. DLinear 在当前例子里的真正输入输出
在当前例子中:
传给 DLinear.forward(...) 的形参
x_enc = input = (4, 96, 7)x_mark_enc = input_mark = (4, 96, 4)x_dec = dec_input = (4, 72, 7)x_mark_dec = target_mark = (4, 72, 4)
但 DLinear 真正主要使用的
x_enc
因为它内部的 forecast 路径本质上是:
python
dec_out = self.forecast(x_enc)
return dec_out[:, -self.pred_len :, :]这说明:
当前 DLinear 被包进了统一 transformer-family 接口,但它本质仍是一个以
x_enc为核心输入的线性预测模型。
11. 这条主链学习完成后,你真正应该掌握的 8 句话
run_benchmark.py负责组装配置并调用pipeline(...)。pipeline(...)负责数据准备、模型工厂、评测执行、日志落盘。eval_model(...)把模型工厂和评测配置变成可调度任务。ForecastingStrategy.execute(...)负责固定随机性并从DataPool取出具体序列。RollingForecast._eval_batch(...)是单序列 rolling 评测的业务主体。- 训练线通过
fit_method -> forecast_fit -> 训练循环 -> _process -> DLinear.forward进入模型。 - 预测线通过
batch_forecast -> _perform_rolling_predictions -> _process -> DLinear.forward进入模型。 - adapter 负责接口翻译,DLinear 负责真实数值计算。
12. 你接下来最合理的两个方向
方向 A:切回 Informer
现在你已经有了完整 benchmark 坐标,可以回去看:
TransformerAdapter._process(...)Informer.forward(...)- encoder / decoder
这时你不会再把:
- 框架逻辑
- 模型逻辑
混在一起。
方向 B:继续在 TFB 内换第二个模型
最合适的对照对象是:
Informer
这样你能第一次真正比较:
- 简单线性模型 DLinear
- 复杂 transformer 模型 Informer
在同一 benchmark 框架里的接入方式和前向路径差异。
13. 只留一句
这条完整主链说明:TFB 决定“实验怎么跑”,adapter 决定“接口怎么接”,DLinear 决定“预测怎么算”。