Lesson 04 · 支柱 A · 预测
Neural ODE 预测区域温度
用连续时间微分方程学建筑热演化——这是 BrainBox 自称"96% 精度"的那一根支柱。
第 3 课你已经看到:区域温度服从 C_z·dT/dt = (T_out−T_z)/R + … 这种 ODE。现在把它反过来用——不手写物理参数,而是让神经网络学这个 ODE 的右端,再用 ODE 求解器积分出未来温度轨迹。这就是 Neural ODE,也是 BrainBox 预测层的核心机制。
这一课给你完整的可跑实现:从数据准备,到定义 dz/dt = f(z,t),到用 torchdiffeq 积分、训练、6 小时前瞻预测。第 5 课再在它上面加物理正则化。
一、Neural ODE 到底在做什么
普通网络是一层一层离散地变换隐状态:z₁ = f(z₀), z₂ = f(z₁)…。Neural ODE 把"层"换成一个连续微分方程:
dz/dt = f_θ(z, t) # θ 是网络参数,z 是隐状态 z(t₁) = ODESolve(z(t₀), f_θ, t₀, t₁) # 用数值积分器从 t₀ 推到 t₁
对建筑温度预测来说:z 是区域热状态(温度、可能含墙体蓄热等),f_θ 是网络学到的"热演化律",t₀→t₁ 就是从现在推到 6 小时后。结构和第 3 课的 1R1C 同形——只不过右端 f 从手写公式变成了学习的网络。
二、两个求解器:odeint vs odeint_adjoint
torchdiffeq 给两个主接口,差别在梯度怎么算:
| 接口 | 梯度方式 | 内存 | 速度 | 什么时候用 |
|---|---|---|---|---|
odeint | 普通反向传播(穿过每步求解) | 随步数线性涨 | 较快 | 轨迹短、原型阶段 |
odeint_adjoint | adjoint 敏感度(反向再解一次 ODE) | O(1) 恒定 | 约慢 1.5–2× | 长时序、6h 前瞻、显存敏感 |
三、动手做:训一个 Neural ODE 温度预测器
数据来源用第 2 课的 Sinergym:让 PID 基线跑一年,把每一时间步的 zone 温度 + 外部扰动存下来,就是训练数据。这里给完整训练脚本。
动手做 4.1 · 采集训练数据(Sinergym 跑一年,存 CSV)
import gymnasium as gym, sinergym, numpy as np, csv env = gym.make("Eplus-5zone-hot-continuous-stochastic-v1") obs, _ = env.reset(seed=0) rows = [] for _ in range(env.get_wrapper_attr("max_ep_data") - 1): # 用随机/规则动作采集;这里先随便给个动作 action = env.action_space.sample() obs, reward, term, trunc, info = env.step(action) # 存:[时间索引, 室外温度, 太阳辐射, zone温度(5个), 能耗] rows.append([*obs.tolist(), info.get("total_power", 0.0)]) if term or trunc: obs, _ = env.reset() env.close() with open("zone_data.csv", "w", newline="") as f: csv.writer(f).writerows(np.array(rows)) print("采集到", len(rows), "步")
动手做 4.2 · 训练 Neural ODE,6 小时前瞻(核心)
import torch, torch.nn as nn, numpy as np from torchdiffeq import odeint_adjoint as odeint # —— 1. 数据:滑窗构造 (t0 状态 → 未来 6h=24 步 轨迹) —— data = np.loadtxt("zone_data.csv", delimiter=",") T_zone = data[:, 3:8] # 取 5 个 zone 温度列(按你的列调整) dt = 0.25; horizon = 24 # 6h = 24 × 15min def make_seqs(arr, lookback=1, horizon=24): X, Y = [], [] for i in range(len(arr) - horizon): X.append(arr[i]); Y.append(arr[i:i+horizon]) # 起点 → 未来轨迹 return torch.tensor(X, dtype=torch.float32), torch.tensor(torch.tensor(Y)) X, Y = make_seqs(T_zone) Y = Y.squeeze(-2) # [N, horizon, zones] # —— 2. 定义 dz/dt = f_θ(z, t) —— class ODEFunc(nn.Module): def __init__(self, dim=5): super().__init__() self.net = nn.Sequential( nn.Linear(dim, 32), nn.Tanh(), nn.Linear(32, 32), nn.Tanh(), nn.Linear(32, dim)) def forward(self, t, z): return self.net(z) # 这里先纯数据驱动;第 5 课注入物理项 func = ODEFunc(dim=5) opt = torch.optim.Adam(func.parameters(), lr=1e-3) t_grid = torch.linspace(0, dt*horizon, horizon) # 0 → 6h # —— 3. 训练循环 —— for epoch in range(30): opt.zero_grad() pred = odeint(func, X[:64].unsqueeze(-2)..., ...) # 见下方说明 # odeint 返回 [T, batch, dim],转成 [batch, T, dim] 对齐 Y pred_traj = odeint(func, X[:64], t_grid, method="dopri5", rtol=1e-3, atol=1e-3) pred_traj = pred_traj.transpose(0, 1) # [batch, horizon, dim] loss = nn.MSELoss()(pred_traj, Y[:64]) loss.backward(); opt.step() print(f"epoch {epoch} mse={loss.item():.4f}")
注意:上面训练循环里那行带 ... 的是示意,请用下面那行干净的 odeint(func, X[:64], t_grid, ...)。odeint 第一参数是函数、第二是初值 z(t0)、第三是时间网格。
四、训练之外:怎么算"96% 精度"
BrainBox 的"96% predictive accuracy"是一个具体口径,复刻时要对齐,否则数字不可比。
| 口径 | 公式 | 说明 |
|---|---|---|
| MAPE 反算 | acc = 1 − mean(|y−ŷ|/|y|) | 最常见,本课用这个对齐 |
| R² 决定系数 | 1 − SS_res/SS_tot | 越接近 1 越好,但与"96%"口径不同 |
| CV-RMSE | RMSE / mean(y) | ASHRAE Guideline 14 常用,工程验收口径 |
with torch.no_grad(): pred = odeint(func, X[-200:], t_grid, method="dopri5").transpose(0,1) mape = (torch.abs(pred - Y[-200:]) / torch.clamp(torch.abs(Y[-200:]), 1e-6)).mean() accuracy = 1.0 - mape.item() print(f"6h 前瞻精度 ≈ {accuracy*100:.1f}%(MAPE 口径)")
五、这一课的局限:纯数据驱动的 Neural ODE 还不够"BrainBox"
你刚才训的 Neural ODE 是纯黑箱——右端 f 完全由网络学,没有物理。它能拟合数据,但有两个问题:
- 数据外推不稳:碰到训练时没见过的极端天气,可能预测出物理上不可能的温度(比如负的、或飙升到 50°C)。
- 没有用上"我们已经知道热方程"这个先验——相当于把第 3 课白捡的物理知识扔了。
BrainBox 的精髓在于把物理接回去。这正是第 5 课 PINN 的主题——也是"少数据、更准"的真正来源。
1. Neural ODE = 学一个 dz/dt = f_θ(z,t) 再积分,结构和建筑热 ODE 同形,这是它适合 HVAC 的根本原因。
2. torchdiffeq 两个接口:odeint(快、吃显存)/ odeint_adjoint(O(1) 显存、慢)。长时序前瞻用 adjoint。
3. 你跑通了一个完整训练管线:Sinergym 采数 → 滑窗构造 → Neural ODE 训练 → 6h 前瞻 → MAPE 口径算精度。
4. 但纯黑箱还不够——它没用到已知的物理。第 5 课把它变成 BrainBox 式的灰箱。
关于 Neural ODE 在 HVAC 预测上的优势,下面哪个说法不准确?
对了。"训练比 LSTM 快"是错的——Neural ODE 因为要反复调用 ODE 求解器,每个 epoch 通常比 LSTM 慢。它的优势在数据效率和物理一致性(更少数据学得更准、外推更稳),不在速度。其他三项都是准确的优势描述。
odeint 的 method 怎么选(dopri5/rk4/euler 区别)?训练发散/NaN 怎么调?怎么把多个 zone 和外部扰动一起塞进 z?——都能展开。
- Neural ODE 论文(Chen 2018, NeurIPS Best Paper):arxiv.org/abs/1806.07366
- torchdiffeq 仓库:github.com/rtqichen/torchdiffeq
- torchode(并行加速):arxiv.org/abs/2210.12375
- UvA Neural ODE 教程:uvadlc-notebooks
- BrainBox Advancing AI:brainboxai.com/…/advancing-ai