Appearance
Level 4 单任务桥接层
Abstract
入口:
pythonstrategy.execute(series_name, model_factory)这一层解释:
Level 3 里被
schedule(...)提交出去的单任务体,怎样先经过ForecastingStrategy.execute(...)这个通用外壳,再进入RollingForecast._execute(...),最后把控制权交给_eval_batch(...)。
1. 上一层与当前层位置
上一层是:
当前层对应上一层中的这两个节点:
3B 被调度任务体3C RollingForecast 任务主体
更具体地说,Level 4 从上一层承接的是这条已经在 23 中解释清楚的顺序链:
text
schedule(strategy.execute, (series_name, model_factory))
-> strategy.execute(series_name, model_factory)
-> ForecastingStrategy.execute(...)
-> self._execute(...)
-> RollingForecast._execute(...)更准确地说:
Level 3负责说明:eval_model(...)怎样把任务提交出去
Level 4负责说明:- 被提交出去的这个任务体,内部先后怎样推进
所以这一层不是凭空跳出来的。
它就是上一层这条边的展开:
text
3A-2 schedule(...)
-> 3B ForecastingStrategy.execute(...)
-> 3C RollingForecast._execute(...)1.5 这一层的关系类型说明
这一层要同时看两个函数,但它们不是并列顶层对象,而是:
ForecastingStrategy.execute(...)- 通用外壳
RollingForecast._execute(...)- 具体策略实现入口
所以这一层的结构是:
text
单任务桥接层
├─ 4A ForecastingStrategy.execute 通用外壳
└─ 4B RollingForecast._execute 策略实现入口其中:
4A负责设 seed、取 data/meta_info、调用self._execute(...)4B负责实例化模型、判断路由、进入_eval_batch(...)
2. 当前层第一性
这一层的第一性是:
把 Level 3 里“已提交的单序列任务”,推进成“真正进入 rolling batch 主体
_eval_batch(...)的具体执行链”。
所以这层的功能不是:
- 训练模型
- 做预测
- 算指标
而是:
- 衔接
schedule(...)和真正业务主体 - 把通用策略外壳和 rolling 策略入口串起来
3. 当前命令的最小例子
当前例子里:
series_name = "ETTh1.csv"model_factory = DLinear 对应的 ModelFactorystrategy = RollingForecast(...)
所以 Level 3 里真正提交出去的任务是:
python
strategy.execute("ETTh1.csv", model_factory)而 Level 4 解释的就是这句内部会发生什么:
python
ForecastingStrategy.execute(...)
-> self._execute(...)
-> RollingForecast._execute(...)
-> self._eval_batch(...)4. 先看顺序图
这张图回答的是:
Level 3 里那个被调度任务体,在时间顺序上到底怎样推进到
_eval_batch(...)。
5. 再看抽象索引树
这棵树回答的是:
为了理解被调度任务体,人脑应该先把它分成哪两个桥接节点。
6. 职责树
6.1 4A ForecastingStrategy.execute(...)
职责:
- 读取
deterministic和seed - 固定随机性
- 从
DataPool中取:datameta_info
- 把控制权交给
self._execute(...)
6.2 4B RollingForecast._execute(...)
职责:
- 调
model_factory()实例化本次任务使用的模型 - 判断走:
_eval_sample(...)- 还是
_eval_batch(...)
- 在当前例子里进入
_eval_batch(...)
7. 输入输出接口
7.1 本层总入口接口
python
strategy.execute(series_name, model_factory)输入:
series_namemodel_factory
7.2 4A 的出口
python
self._execute(data, meta_info, model_factory, series_name)7.3 4B 的出口
当前例子里出口是:
python
self._eval_batch(series, meta_info, model, series_name)8. 函数 / 文件关系图
9. 当前例子的具体落地
9.1 Level 3 到 Level 4 的真实连接点
在 eval_model(...) 里真正提交的是:
python
eval_backend.schedule(strategy.execute, (series_name, model_factory))所以进入 Level 4 的真实入口不是“凭空出现的 RollingForecast”,而是:
python
strategy.execute("ETTh1.csv", model_factory)这句会先进入 ForecastingStrategy.execute(...),对应代码骨架是:
python
def execute(self, series_name, model_factory):
deterministic_mode = ...
seed = ...
data_pool = DataPool().get_pool()
data = data_pool.get_series(series_name)
meta_info = data_pool.get_series_meta_info(series_name)
single_series_results = self._execute(
data, meta_info, model_factory, series_name
)
return single_series_results9.2 为什么后面会到 RollingForecast._execute(...)
因为:
strategy当前实际类型是RollingForecast- 但
execute(...)定义在ForecastingStrategy基类里 execute(...)内部会调:
python
self._execute(data, meta_info, model_factory, series_name)而当前 self 是 RollingForecast,
所以这句最终会动态分派到:
python
RollingForecast._execute(...)这就是 Level 3 和 Level 4 真正接上的地方。
9.3 当前例子的完整桥接代码
对当前 RollingForecast 例子,可以直接压成:
python
strategy.execute("ETTh1.csv", model_factory)
-> ForecastingStrategy.execute("ETTh1.csv", model_factory)
-> self._execute(data, meta_info, model_factory, "ETTh1.csv")
-> RollingForecast._execute(data, meta_info, model_factory, "ETTh1.csv")然后 RollingForecast._execute(...) 里再继续:
python
model = model_factory()
return self._eval_batch(series, meta_info, model, series_name)10. 下一层入口
下一层只继续展开:
python
RollingForecast._eval_batch(...)也就是当前层索引树里的:
4B-3 进入 _eval_batch(...)
对应:
11. 只留一句
Level 4 不是“突然从 eval_model 跳到 RollingForecast”,而是把
schedule(strategy.execute, ...)这条被提交任务体,继续展开成ForecastingStrategy.execute(...) -> RollingForecast._execute(...) -> _eval_batch(...)。