跳转到内容

历史窗口 ​

历史窗口让模型读取过去若干步的观测或动作,适合描述惯性、输送延迟和未被直接测量的过程状态。本页以温度预测为例,说明窗口选择、数据对齐、训练与连续推理的方法。

使用场景 ​

相同的当前读数可能对应不同的后续变化。例如,两台设备当前都是 22°C,一台刚结束强加热,另一台刚从高温冷却下来;由于内部储热不同,接下来一段时间的温度变化也不同。过去几步的温度和动作能帮助模型区分这两种情况。

任务当前读数缺少的信息可考虑的历史输入
温控与暖通升降温趋势、墙体或设备储热温度、供热动作
水处理药剂输送、混合及仪表延迟投加命令、流量、余氯观测
三容水箱上游动作经过容积传递的影响液位、泵流量

先核对时间对齐和当前状态是否充分,再决定是否加入历史。若三容水箱的全部液位都已测得,当前状态可能已经包含足够的储水信息;若只测到末端液位,历史输入通常更有意义。

示例:观察温度变化趋势 ​

源码 examples/thermal_workflows/history.yaml 使用一分钟采样,在当前温度之外加入过去三步温度。以下是该文件中的节点片段:

yaml
graph:
  nodes:
    delta_temperature:
      inputs: [temperature, heat, fan, ambient, load, "temperature@[-3:]"]
      network:
        backbone: thermal_tutorial_mlp
        custom_params: {width: 16}
      output_dist: normal

在 t=3 预测时,模型同时看到当前 T[3] 和过去 T[0]、T[1]、T[2],预测下一步 T[4]。当前值与历史窗口分别声明,便于区分当前状态和过去的变化趋势。

历史窗口覆盖当前时刻之前的观测,当前值单独输入,下一时刻为预测目标

图:历史窗口不包含当前值;当前输入直接使用变量名,未来标签不作为历史输入。

训练数据需要保留连续采样顺序与轨迹边界。不能将两次独立运行的末尾和开头拼成一个窗口。缺测、变采样周期和传感器延迟应在数据准备时处理。

配置窗口与补齐方式 ​

历史输入语法 ​

写法覆盖的时刻
var@-k第 t−k 步
var@[-k:]t−k 到 t−1
var@[-k:-j]t−k 到 t−j−1
var@[-a,-b,-c]指定的若干历史时刻

历史索引使用负数;当前值直接写 var。含方括号的引用在 YAML 中加引号,例如 "temperature@[-3:]"。历史定义在状态变量上,使用 obs@-1,不使用转移目标 next_obs@-1。

根据业务时间尺度选择长度 ​

可以用“需覆盖的过程时长 ÷ 采样周期”估计窗口初值。例如输送延迟约 30 分钟、每 5 分钟采样一次,可先试 @[-6:]。本例三步窗口覆盖三分钟,适合演示温度趋势输入。

窗口越长,输入维数越大。一个三维变量读取 12 步历史时,拼接宽度为 36。保持验证条件一致,比较不同窗口下的多步误差与推理耗时,再决定长度。

起始历史不足时的设置 ​

yaml
graph:
  history:
    default_pad_mode: repeat_first
    default_output_format: concat
    init_fill_mode: repeat
    detach_history: true
字段用途
default_pad_mode数据轨迹开头历史不足时采用 repeat_first、zeros 或 none
default_output_formatconcat 拼成长向量;stack 保留时间轴,需与网络输入接口匹配
init_fill_mode推理初始化时以 repeat、zeros 或 none 处理缺失历史
detach_history是否截断跨步历史梯度

窗口长度写在 inputs 的 @ 表达式中。补齐方式应符合启动过程:重复初值相当于假设此前读数接近当前值,补零则引入另一种初始条件。有真实历史时,优先用真实前缀初始化。

训练并检查效果 ​

在仓库根目录执行。已有数据时跳过生成步骤,重新生成会覆盖示例数据。

bash
python examples/thermal_workflows/prepare_data.py
revive validate --config examples/thermal_workflows/history.yaml
revive train --config examples/thermal_workflows/history.yaml --run-id thermal_history

该配置使用连续序列训练,训练 horizon 为 4,验证 horizon 为 8。历史窗口提供的是预测起点以前的信息,horizon 表示从起点向后预测的长度,两者应分别设置。

查看 示例目录下的 logs/thermal_history/report.md。比较有、无历史的模型时,使用相同轨迹和预测窗口,关注温度趋势、外扰发生后的恢复过程及误差随预测步数的变化。

连续推理与部署 ​

真实前缀、当前状态与未来输入 ​

下面的命令使用训练好的模型,读取示例轨迹的真实前缀并推演八步:

bash
python examples/thermal_workflows/consume.py \
  --model examples/thermal_workflows/logs/thermal_history/models/env.pt --source replay
text
真实前缀          当前状态与动作          预测结果
T[0:3]       →   T[3], u[3], e[3]    →   T̂[4] ... T̂[11]
未来外部条件:   e[3], e[4], ... e[10]

后续温度来自模型递推。动作和外部条件 e(环境温度、负载)按时间逐步提供,未来温度标签只用于评估误差。示例的 --source 标记输入来源,实际读取同一数据文件;业务预测应换成在决策时已经发布的计划、天气预报或负载预测。

为每条轨迹保存状态 ​

带历史窗口的模型需要在调用间保存运行时状态。每条设备运行或每条独立轨迹各自维护状态,新轨迹重新初始化,同一轨迹逐步更新。

高层 EnvModel.infer_k_steps(..., prefix_data=...) 可接收真实前缀;外部序列通过 env.graph.set_static_vars(...) 声明,再按步注入。低层图预热使用 [T,B,D] 前缀,策略部署按 runtime manifest 规定的轴排列。完整代码见有状态模型调用。

导出 ONNX 后,按 manifest 的 init、warmup、step 接口完成初始化、预热和状态回传。将环境或批量切换为另一组轨迹时,应重新初始化。

常见问题 ​

现象处理方法
YAML 无法解析将含 @ 窗口和方括号的输入用引号括起来
提示只能使用过去索引使用负索引,当前值直接写变量名
next_obs 无法声明历史使用转移前的基础变量 obs
轨迹开头误差偏大检查历史补齐假设,尝试提供真实前缀
换设备或新轨迹后输出异常检查是否重用了上一条轨迹的历史状态
加长窗口没有改善检查数据对齐、可观测性和分工况误差,再调整窗口或网络

普通网络的输入拼接顺序与 inputs 声明一致;GRU 等有状态网络的训练和部署路径按输入键字母序规范化。自定义网络按 FeatureMapping 读取编译后的实际布局。改变输入布局后重新训练,避免复用不同结构的权重。