Skip to content

Latest commit

 

History

34 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

world-model-lab

世界模型 + rollout + 可靠视界评测的最小可复现框架。 场景锚点:UAV / 无线通信(本框架先用 CartPole 级任务把训练循环跑通,再换场景,只动 wmlab/envs/)。

这个仓库解决什么问题

世界模型(world model)在 rollout 到第 N 步之后会失准,但几乎没人明确回答"第几步开始不准、为什么"。 本仓库的目标是把这件事做成可测量、可复现、可对比的:

  • 统一的环境接口(envs),换场景不改模型与评测代码
  • 最小的世界模型实现(models),编码器 + 潜空间转移 + 解码器
  • 潜空间 rollout(rollout),支持任意视界
  • **可靠视界(reliable horizon)**定义与测量(eval)——第 h 步自身的预测误差 首次超过阈值的那一步("逐点"口径;用累积口径会系统性抬高 H*,见 §设计约定 7)
  • 通信接入层(envs/channel.py)——把世界模型接到丢包/时延信道 + AoI 记账, 把 H* 读成"多久必须传一次"(X24/X25/X26)
  • 时延地板(eval/tracking.py)——时延真的延迟信息之后,误差多出一个 与模型无关的下界 2(1 − ρ_o(D))(X27):这是"生成年龄 ≠ 传输年龄"的实测证据

快速开始

# 1) 环境(本机已建好 ai-lab,见项目文档)
conda activate D:\devtools\miniconda3\envs\ai-lab
# 或在 VSCode 里直接用任务:Terminal -> Run Task -> wmlab: 环境自检

# 2) 环境自检(15 项,含中文字体链路)
python scripts/00_check_env.py

# 3) 随机策略 baseline,产出第一张图
python scripts/01_random_baseline.py

# 4) 训练一个世界模型,产出 loss 曲线 + 多步预测误差曲线
python scripts/02_train_world_model.py

# 5) 分析误差增长的形态(饱和 / 线性累积 / 自我放大,三选一)
python scripts/03_analyze_horizon_curve.py outputs/02_world_model_pendulum.json

# 6) 通信接入:X24 等价性 + X25 调度帕累托 + X26 解析对账(约 3 min,全程 CPU)
python scripts/04_channel_tracking.py --config configs/channel.yaml
python scripts/04_channel_tracking.py --config configs/channel.yaml --quick   # 冒烟

# 7) X26 对账细节(离线曲线 vs 在线实测、插值敏感性、H* 两口径)—— 读 04 的产物,不重训
python scripts/05_diagnose_x26_gap.py

# 8) X27 时延地板(读 04 的 checkpoint,不重训;约 1–2 min)
python scripts/06_delay_floor.py --quick   # 冒烟:2 条 × 200 步
python scripts/06_delay_floor.py

# 9) X3/X4:种子重复 × 阈值敏感性(CPU,约 13 min;含 5 次完整重训)
python scripts/07_seeds_threshold.py --quick            # 冒烟:2 种子、小 epoch
python scripts/07_seeds_threshold.py --seeds 0 1 2 3 4

# 10) 自检(68 项,不依赖 pytest;每个用例对应一次真实踩过的坑)
python tests/test_channel_and_aoi.py

# 11) X22:C17 的 safe horizon 在本场景**能不能实证**(12 项断言,秒级;不训练、不需 GPU)
python scripts/08_x22_theory_check.py

# 12) X30:任务锚定的 H*(UAV 闭环控制,约 2 min CPU;误差阈值 vs 任务失败的比值)
python scripts/16_task_horizon.py

换环境只换配置,代码不动(长视界那轮就是这么做控制变量的):

python scripts/02_train_world_model.py --config configs/pendulum.yaml --tag 02_world_model_pendulum

所有结果图写入 outputs/(不进版本库)。

目录结构

wmlab/
  envs/     环境适配层。统一接口,换 UAV/信道场景只加 Adapter
  models/   世界模型。编码器 / 潜空间转移 / 解码器
  rollout/  潜空间多步 rollout,以及误差随视界增长的测量
  eval/     指标:NMSE、可靠视界、预测区间覆盖率
  utils/    设备选择(CPU/云 GPU 无痛切换)、随机种子、统一绘图样式
scripts/    可直接运行的入口脚本(编号即依赖顺序;00 = 环境自检)
configs/    YAML 配置(device: auto 时自动选 cuda 或 cpu)
outputs/    ★ 结果图与日志,已 gitignore

设计约定(为云 GPU 迁移服务)

  1. 设备无关:任何 .to(...) 都走 wmlab.utils.device.get_device(),代码里不出现硬编码 .cuda()。 本机无独显(CPU 起步),云端租 GPU 后 --device cuda 即可,不改代码。
  2. 种子固定:set_seed() 统一设置 python / numpy / torch,保证曲线可复现。
  3. 配置外置:超参走 configs/*.yaml,不写死在脚本里,便于扫参。
  4. 结果落盘:所有图与指标写 outputs/,README 里引用的图都从它来。
  5. 样式随代码走:中文字体由 wmlab.utils.plot.apply_style() 显式设置(探测 YaHei / PingFang / Noto CJK 等并逐个回退),不依赖 MPLCONFIGDIR 等进程环境—— 换机器、换终端、上云,图里中文都不会变方块;负号渲染同步修复。
  6. 依赖锁定:requirements.lock.txt 记录本机全量依赖(torch 为 +cpu 版, 上云时替换为对应 CUDA 版本即可)。
  7. ★ 口径必须显式(2026-09-20 立):任何"误差"数字都要写清三件事 —— 逐点还是累积、在哪个评测集上、除以哪个方差。原因不抽象:H* 这一个指标, 在同一个 Pendulum 模型上就出现过 64.83 / 51.96 / 42.99 / 39.01 / 25.71 / 25.57 六个数,全部"正确",只是口径不同。代码层面已做成默认安全: multi_step_error_curve() / closed_loop_error_curve() 同时返回两个口径; reliable_horizon(..., calibration="cumulative") 会发警告; NmseCurve 在 lengths 不匹配时直接抛错(而不是静默截断)。
  8. ★ 报 H* 还要写第四件事:种子数与滑窗采样数(2026-09-20 X3/X4 补)。 H* 是"首次穿越",属于曲线的极值泛函,对种子和采样量都比曲线本身敏感得多: 5 个种子的 H* 落在 13.13 – 42.99(CV 0.42);n_samples 从 256 提到 4096 又会系统性挪动它。所以 reliable_horizon 的输入是"一条曲线",而一条曲线本身也不够 —— ⇒ 正确形式是 H* = 26.9 ± 11.4 (5 seeds, n_samples=4096, θ=0.05) 或直接报对 θ 的幂律标度 α(那个在均值上是稳的)。 ★ 推论:NaN/Inf 不得静默通过 —— NaN <= 阈值 恒为 False, 会被当成"已超阈"返回虚假偏小的 H*(实测触发过:弱模型观测空间闭环第 131 步后爆到 3.9e34)。 现在会直接 raise ValueError。

结果(CPU,全部可复现;同种子重跑逐位一致)

① 随机策略 baseline

random baseline

CartPole-v1,600 集随机策略:平均回报 22.9(std 11.9),最长 69 步,共 13733 步。 随机策略平均 20 步出头就倒 —— 这也是当下 horizons 上限取 15 的原因。

② 世界模型与可靠视界(第一轮:CartPole,短视界)

world model

指标 值(逐点口径) 累积口径(历史)
环境 / 数据 CartPole-v1,600 集随机策略,13,733 步 同
参数量 67,652 同
train / val loss 0.1502 → 0.0005 / 0.0013 同
可靠视界(开环) 12.95 ← 逐点口径才能测出 None(视界上限 15 步内测不出)
可靠视界(闭环) 6.96 10.1

注意:这一轮的结论后来被修正了两次(详见 ③ 与"误差口径"一节)。当时由图④ 得到 「误差在自我放大」,但有两个问题:

  • 15 是数据上限,不是模型上限 —— 随机策略在 CartPole 上平均只活 22.9 步, horizons 物理上就设不到更大,所以「开环 > 15」什么也没测到;
  • 图④ 的口径有缺陷 —— 当时写的是 inc = np.diff(nmse),而 horizons 间隔不等 (…2, 2, 3, 5, 5, 10…),直接差分会把「采样间隔变大」混进「误差增长加速」;
  • H* 的误差口径也不对(2026-09-20 发现)—— 当时用累积平均 NMSE, 它把前 h-1 步的误差摊成均值,穿越阈值更晚 ⇒ H* 被抬高,开环甚至直接测不出。 换成逐点口径后:开环从 None 变成 12.95,闭环从 10.1 变成 6.96。

③ ★ 核心结果:Pendulum 长视界(2026-09-18)

long horizon

换到 Pendulum-v1(每集固定 200 步)把视界抬到 190。 模型 / 损失 / 优化器 / 阈值全部不动,只换数据供给 —— 这是控制变量,不是调参:

指标 值(逐点口径 ★) 累积口径(2026-09-18 首次报出)
环境 / 数据 Pendulum-v1,300 集随机策略,60,000 步(每集 200.0 步) 同
参数量 67,267(obs_dim=3,连续动作) 同
train / val loss 0.7298 → 0.0007 / 0.0005 同
可靠视界(开环) 42.99 64.83
可靠视界(闭环) 39.01 51.96
阈值 NMSE > 0.05(rel 口径,与上一轮同口径,未改) 同

为什么两个数字不一样:累积口径算的是 mse(pred[:, :h], tgt[:, :h])(把前 h 步 一起平均),而 reliable_horizon 问的是"第 h 步本身首次超阈"。 前者是后者的运行平均,穿越阈值必然更晚 ⇒ 累积口径系统性抬高 H* (开环 +50.8%、闭环 +33.2%)。"开环 > 闭环"的方向不变,"误差饱和"的形态判定也不变。

三条结论(每步增量表可用 scripts/03_analyze_horizon_curve.py 复现):

  1. 开环 H* 第一次是个有限数字:42.99 步(逐点口径)。上一轮那个「> 15」是区间下界。

  2. 误差增长是「饱和」,不是「自我放大」。 每步增量在 h≈88 处到达峰值 (开环 9.4e-3、闭环 3.5e-3 每步),之后掉头:开环回撤 17%、闭环回撤 63%。 上一轮之所以看到「自我放大」,是因为 CartPole 只测到 15 步,整段都落在饱和曲线的上升段 —— 用短视界数据外推长视界行为,得到的是错觉。正确描述是: 每步误差增长率先升后降,最终饱和到目标方差(NMSE → 1,即「完全不可预测」的上界)。

  3. 两条曲线在 h ≈ 100–150 处交叉:中期闭环更差,超长视界开环更差。

    视界 开环 NMSE 闭环 NMSE 谁更差
    50 0.0203 0.0311 闭环
    75 0.0704 0.2728 闭环(差 3.9×)
    100 0.3051 0.3612 闭环(略)
    150 0.6951 0.6191 开环
    190 1.0313 0.7613 开环(差 1.4×)

    机制解释 —— ★ 两者测的不是同一件事(早在 CartPole 那轮读代码时就发现了, 见 D:\workbuddy\researchproject\04-实验与代码\实验记录\2026-09-17-... §8):

    实现 误差在哪累积
    开环 multi_step_error_curve encode 一次 → 潜空间连推 H 步 → 最后统一 decode 潜空间,全程无纠错,误差无界
    闭环 closed_loop_error_curve 每步 encode → transition → decode,输入是上一步的预测观测 观测空间,每步自带一次隐式纠错

    所以:中期闭环更差,是因为每步多了一次 encode/decode 的往返误差在叠加; 超长视界开环更差,是因为潜空间 rollout 没有任何机制把状态拉回编码器流形附近, 误差无界增长(NMSE > 1 即比「直接预测均值」还差)。 交叉现象本身可复现,但机制归因仍属推测 —— 要坐实需补第三种曲线(潜空间闭环)。

怎么读这张图:子图② 是对数坐标的 NMSE 曲线 —— 实线是逐点口径(H* 的定义口径), 淡色虚线是累积口径,两者的间距就是这个口径选择的影响力,不需要另开一张图解释。 子图③ 是一条真实轨迹的 190 步开环预测:前 30 步基本贴合,之后相位逐渐偏移。 子图④ 直接画逐点误差(nmse_per_step)—— 它本身就是"每一步有多准", 不需要再对累积曲线做差分(那正是 2026-09-18 修掉的那处口径缺陷)。

诚实的边界:以上都是随机策略数据、CPU、MLP 世界模型。 跨环境数字不可比 —— Pendulum 与 CartPole 的 H* 不能直接比较(状态维度、动作空间、 每集长度都不同),这里只作「各测一次」。也尚未回答「该不该预测」这个科研问题(那是消融实验的事)。 ★ H* 的数值同时依赖三个字段:口径(逐点/累积)、评测集、归一化分母 —— 换任何一个都会变(同一个 Pendulum 模型:短 val 集上 42.99,held-out 长集 + global 分母上 25.71)。 引用 H* 时必须三个一起写。

⚠️ 单种子限定(2026-09-20 补,见 §⑥)

上面这两个数(42.99 / 39.01)是 seed = 0 一个种子的结果。 补跑 5 个种子后:H*(开环) = 26.9 ± 11.4,五个种子的原始值是 42.99 / 32.09 / 13.13 / 20.22 / 26.20 —— 最大值是最小值的 3.3 倍。

⇒ 42.99 属于"最好的那个种子"。本节的机制结论(饱和、开环>闭环、h≈100–150 交叉) 在 seed=0 上成立且被 §⑥ 证明不依赖阈值选择,但任何一个 H* 的具体数值都不可单独引用。 这不是瑕疵,是这类"首次穿越"指标的固有性质 —— 详见 §⑥。

④ ★ 通信接入:把 H* 当成"多久必须传一次"(2026-09-20,X24 / X25 / X26)

channel

在 wmlab/envs/channel.py 加一层薄信道适配器(Bernoulli 丢包 + 时延), 把世界模型接到一个 AoI(信息年龄)记账器上,问三个问题:

编号 问题 结果
X24 信道层有没有偷偷改动力学? ✅ 三层等价性全过:E1 动力学 bit-exact(max|diff| = 0.0)、E2 裸 env 与 p=0 信道的 H* 逐位一致、E3 实测 E[age] 收敛到理论 p/(1-p)(p=0.9 时 8.924 vs 9.000)
X25 把 H* 当"多久必须传一次",它值不值? 传输率–NMSE 帕累托前沿画出来了;Kneedle 拐点在间隔 62.5 步(NMSE 0.205),而 H*(闭环)=25.6 落在拐点左侧 ⇒ 按 H* 传输是保守的(多花通信换误差)。容忍丢包率 p*(H=25.6, δ=1%) = 0.8408 ⇒ 在 Pendulum 上通信不是瓶颈
X26 离线测的 NMSE(h) 曲线能不能预测在线跟踪误差? ✅ 能。改用同口径后,解析 vs 仿真的中位相对偏差 9.9%(修正前是 56%,但那是口径造成的假缺口)

★ X24 为什么必须先做:信道层一旦污染了动力学,所有历史结论作废。E1 的判据写死为 逐位相等(np.array_equal,不是 allclose),且信道用自己的 RNG(seed + 7919 偏移), 只有 loss_prob > 0 时才消耗随机数 —— 所以"加一层信道"不会顺带换掉被采样的轨迹。

★ X25 的可复用结论:H* 与"最优传输间隔"不是同一个数,两者差 2.4 倍。 把 H* 直接当发送周期用会过度通信。真正的决策量是帕累托拐点,H* 只给出"误差容忍度"。

★ X26 的价值在方法:E[NMSE(age)] = Σ pmf(age)·NMSE(age) 需要对曲线插值, 所以"离线曲线 ↔ 在线跟踪"的口径必须严格一致。下面这张图就是这次对账:

x26 reconciliation

四联图说明:(a) 离线逐点曲线与在线实测(按 age 分组)落在同一量级; (b) 在线/离线 中位比值:P(T=8)=1.05、P(T=50)=0.99、P(T=100)=0.97、R(p=0.99)=0.87 —— 映射成立; (c) 线性插值 vs 保形插值(PCHIP)对结论影响不大(大间隔处相差 ~1%), 所以不需要为插值引入 scipy;(d) 曲线在大视界段是凹的(饱和), 这正是 Jensen gap 变号的区间 —— 也是下面这条结论的依据。

★ 一条可以直接写进论文的结论(Jensen 效应):在相同平均 AoI 下, age 方差更大的调度族(随机丢包)误差更高 —— 40/40 个匹配点上成立,中位比值 20.8×。 这是"只优化平均 AoI 不够,必须管尾部"的直接证据,也是本课题与 "任务级 AoI 拆成生成年龄 + 传输年龄"(讲座①)的接口。

这次对账还揪出了两个 bug,都是"数字记下来了但条件没记下来"的同一类:

  1. 累积 vs 逐点口径(见上面的 H* 更正表);
  2. NmseCurve 静默截断:把稠密的逐点数组(长度 190)配给稀疏的 horizons(19 个) 时,np.asarray(nmse)[order] 不报错、直接截断,于是把"第 1..19 步的值"当成了 "视界 1..190 的值",大间隔调度的解析值离谱地小(T=200:解析/仿真 = 0.016/0.703)。 现在 NmseCurve 直接抛错,并有回归测试锁住。

⑤ ★ 时延:不用模型 vs 用模型,差在哪(2026-09-20,X27)

delay floor

delay 在此之前是个空参数 —— 它只参与 age_gen = age_tx + delay 这个加法, 没有任何信息真的被延迟(每步送达的都是当步观测)。所以讲座①那条 「任务级 AoI = 生成信息年龄 + 传输信息年龄」的分解从未被验证。 现在 run_tracking 用在飞包 FIFO 真正延迟到达,于是有四个可判定的问题:

问题 结果
收到陈旧观测就直接当当前状态用(naive),误差是多少? 它是模型无关的:2(1 − ρ_o(D))。在线仿真 vs 数据侧复算,11 个时延点最大相对偏差 1.9e-9
先用动作把陈旧观测向前推进到当前时刻(forward)呢? 误差回到模型的 D 步视界:forward ÷ 离线闭环(D) ∈ 0.87–1.22,无一个点偏离 1 超过 25%
两者差多少? forward/naive 从 0.0012(D=3,差 830 倍)到 0.22(D=45)
双年龄真的分开了吗? ✅ p=0 时 E[传输年龄] ≡ 0 而 E[生成年龄] ≡ D

三条结论:

  1. 时延的代价几乎全在"怎么用它",不在时延本身。 同一个 D=5, naive 误差 0.491、forward 误差 0.00073 —— 差 674 倍。 ⇒ 对 E[NMSE(age)] 的正确拆法是 f(时延的处理方式) + rollout(age), 而不是把时延和丢包混进同一个 age 里。

  2. 在 Pendulum 上,1 步时延比丢 70% 的包贵得多。 纯丢包 p=0.7 → NMSE 3.9e-4; 纯时延 D=1 → 0.023(59.5 倍)、D=2 → 0.087(224.7 倍)。 原因:短视界 rollout 很强(H* ≈ 39),丢包几乎被模型补掉;时延注入的是"内容陈旧"。

  3. ★ forward 有效的前提是模型够好 —— 这句话不能省。 用随机初始化的模型跑, D=1 时 forward ≈ 1.006 而 naive ≈ 0.021(糟 47 倍)。 把一个不会预测的模型顶上去,当然不如直接用陈旧但真实的观测。 ⇒ 「世界模型对通信有用」必须带模型质量这个前置条件,否则是空话。

两条独立路径的验证(沿用 X26 的纪律):naive 在线 ≡ 2(1−ρ_o(D))(1.9e-9); forward 在线 ≡ 「全起点手工复算 D 步闭环 rollout」(逐位一致)。

这次又踩到一个"数字与条件分离"的坑:离线闭环曲线的 n_samples=64 时它自己就不稳, D=30 处单次估计 0.0937、而全起点真值 0.1017 ⇒ 凭空造出一个 5.4 倍的假缺口; 给到 2048 才收敛。 报"两条曲线的比值"之前,先确认两条曲线各自都收敛了。

⑥ ★ H* 到底有多可信:5 种子 × 5 阈值(2026-09-20,X3 / X4)

seeds and thresholds

到 §⑤ 为止报出的每一个 H* 都是单次测量。而 H* 是"误差首次超阈", 属于曲线的极值泛函 —— 比曲线本身对噪声敏感得多。这一节补两块: X3(种子重复)、X4(阈值敏感性)。 跑法:python scripts/07_seeds_threshold.py(CPU,约 13 min,含 5 次完整重训)。

先做前置检验,否则后面全是假象:窗口采样数 n_samples 不够时, 同一个模型两次测出的 H* 都不同,那种子之间的"差异"里就混着采样噪声。 扫 n_samples ∈ {256 … 4096}:最后一档的相对变化 0.45% < 2% ⇒ 判为收敛,采用 4096。

X3 · 种子重复:单次 H* 不能作为结论

seed val_loss(单步预测) H*(开环) H*(闭环)
0 0.000537 42.99 40.66
1 0.000307 32.09 28.17
2 0.000520 13.13 13.16
3 0.001444 20.22 25.12
4 0.000872 26.20 23.54
汇总 — 26.93 ± 11.41(CV 0.424) 26.13 ± 9.89(CV 0.378)

三个必须一起读的事实:

  1. 最大值是最小值的 3.3 倍(42.99 vs 13.13)。 ⇒ 单点 H* 不是一个成立的结论形式,§③ 那个 42.99 属于"最好的那个种子"。

  2. ★ 单步训练损失不能预报长视界可靠性。 seed=0 与 seed=2 的 val_loss 只差 3.2% (0.000537 vs 0.000520),H* 却差 3.1–3.3 倍。 Pearson r = −0.359、Spearman ρ = −0.200(n=5 —— 符号与强度都还不稳,只作定性)。 ⇒ "训练 loss 收敛"和"多步预测可靠"是两件事,长视界可靠性必须单独测量。 这正是这个世界模型值得被单独评测、而不是从训练曲线推断的理由。

  3. 口径复现性交叉验证:Part A 在 n_samples=512 处给出 42.99209、n_samples=256 处给出 39.01098 —— 与 §③ 记录的 42.99 / 39.01 逐位一致,代码没有漂移。 (顺带暴露一个此前没注意的事实:§③ 那两条曲线其实是在不同采样精度下测的 —— 512 vs 256。)

X4 · 阈值敏感性:绝对值不可靠,但标度行为很稳

θ H*(开环) H*(闭环)
0.01 17.38 ± 6.84 13.04 ± 2.49
0.02 21.68 ± 7.94 18.31 ± 4.53
0.05(主口径) 26.93 ± 11.41 26.13 ± 9.89
0.10 30.67 ± 13.37 30.31 ± 12.15
0.20 41.98 ± 17.48 34.88 ± 14.45
  • H*(θ) 服从干净的幂律:开环 62.19 · θ^(+0.277)(R² = 0.981)、 闭环 63.35 · θ^(+0.327)(R² = 0.967)。 阈值加倍,H* 只增加约 2^0.28 ≈ 1.21 倍 —— 次线性。 即便绝对值有 ±40% 的种子波动,这个标度指数是稳的,可以作为一个被引用的量。

    ⚠️ 2026-09-21 更正:此式原写作 θ^(−0.277)(负号),与本表方向 (θ↑ ⇒ H*↑)相反。用 outputs/07_seeds_threshold.csv 独立复算: α = +0.2696 ± 0.0869(open_sparse,5 seeds);按原式代入实测阈值, 相对偏差最大达 +1290.8%。系数 62.19 与数量级本身是对的,错的只有指数符号。 详见 2026-09-21-X22-与理论界对账.md §4.4。

  • ★ 开环 > 闭环的序在全部 5 个阈值下一致(排序反转点:无)。 这是本节唯一一条不依赖阈值选择的强结论 —— §③ 的"开环能推得更远"因此站得住。

  • CV 不随 θ 系统变化(0.37–0.44)⇒ 方差不是阈值选择造成的,而是模型本身的。

顺带量化出来的一个历史精度缺陷

config 的 horizons 在长视界段很稀(100 → 150 → 190)。在同一批曲线上比较 稀疏网格插值与逐步(稠密)插值得到的 H*:最大差 19.57 步。 §③/§④/§⑤ 报的所有 H* 都基于稀疏网格 ⇒ 长视界段的插值误差最多可达约 20 步 (子图⑤ 显示这个误差主要来自开环曲线,闭环的小一个数量级)。

结论:H* 正确的报法

  • ❌ 不要报 H* = 42.99 —— 那是一个种子的运气
  • ✅ 报 H* = 26.9 ± 11.4(5 seeds,θ=0.05),或直接报幂律标度 α ≈ 0.28
  • ✅ 需要绝对长度时,报中位数 / 范围,不要报单点

怎么读这张图:③ 是采样收敛性证据(撑起整节的可靠性); ⑥ 是本节最关键的散点(s0 与 s2 在横轴上几乎重合、纵轴上差 3 倍); ① 是 5 个种子的逐点 NMSE 带 ±1σ;② 是 H*(θ) 与幂律拟合;④ 是 CV(θ);⑤ 是稀疏网格误差。

⑦ ★ 与理论界对账:结论是"对不上",而且原因是可证明的(2026-09-21,X22)

x22 theory check

动机:C17(Imperfect World Models are Exploitable,arXiv:2605.15960)给出了 safe horizon 的 紧界闭式解,但纯理论、零实验,且原文明确限定 finite MDP。 原计划是"把实测 NMSE 当 δ 代进去,与实测 H* 报出 gap"。

结论:这个动作在数学上不成立,理由有三条,全部可复现(scripts/08_x22_theory_check.py,12 项断言):

# 断裂点 内容
① measurand 不同 C17 的 H 约束「策略序反转幅度 ≤ ε」(含回报 J 与折扣 γ);本仓库的 H* 是「预测误差首次超阈的步数」(不涉及策略、价值、γ)
② δ 取不到有分辨力的值 δ 是两转移模型的 TV 距离。本仓库环境确定性(Pendulum/CartPole 的 step() 无噪声,实测同一 (s,a) 三次得到逐位相同的 s')且模型确定性(transition 是 MLP 点估计,无方差头,实测同输入同输出)⇒ T 与 T′ 都是点质量 ⇒ TV ∈ {0,1},取 max 后 δ ≡ 1
③ 空间不同 本仓库的转移在潜空间,δ 定义在状态-动作空间;原文亦限定 finite MDP,自陈不适用于连续 / 潜空间

δ = 1 时代数化简(两条独立路径核对,最大绝对差 2.22e-16):

(1−ε)² + 4ε = (1+ε)²  ⇒  √(...) = 1+ε  ⇒  H(ε, 1) = 1 + ε

定理条件于是退化为 1/(1−γ) ≤ 1+ε ⟺ γ ≤ ε/(1+ε):

ε 允许的最大 γ
0.01 0.0099
0.05 0.0476
0.10 0.0909
0.20 0.1667

⇒ 对任何有实际意义的 γ(0.9 / 0.99)条件都不满足。δ = 1 给出 H 的全局最小值, 而 H 在本场景里永远落在 (1, 1+ε] —— 右图那条红色窄带就是它的全部可能取值, 而实测 H* 是 13–66 步。不是"差多少倍",而是两边不在同一个量上。

★ 所以本仓库不报任何 "gap 数值"。 若强行代入(δ 取实测 NMSE 0.05)会得到 H = 1.63 与实测 42.99 相差 26 倍 —— 但那是假缺口,相除没有数学意义(对应 R13 的精神: 比值只有在两个量各自有定义时才可比)。

这条负面结论反而加硬了所在位置:调研把"测量理论界与实测的 gap"判为唯一确定还空着的环节。 本次给出更本质的原因 —— 这座桥没人走,不是没人想到,而是 C17 的 δ 是 TV 距离, 而 TV 距离在确定性动力学上不携带误差幅度信息,"保守多少"在现有定义下问不出来。

两条补救路径(都还没做):

路径 做法 归属
A 给环境注入过程噪声,让 T 变成真分布 ⇒ δ 才连续 X14 换场景时顺带(玩具环境上不值得单独开一轮)
B 换 Wasserstein-1 / 潜空间距离 替代 TV,自己重推对应的 safe horizon 理论工作,阶段 3–4

诚实边界:① 本次没有产生任何 gap 数值;② δ ≡ 1 依赖"环境确定 + 模型确定"两个前提 (均以 assert 实测),若模型换成随机版(B1 的 H_t + Z_t 因子化),前提失效,本文结论需重做; ③ 只读了 C17 的定理与局限段,未逐页精读其证明,没有独立验证该定理本身; ④ 全程 CPU、0 元、无训练。

⑧ ★ 第三种曲线 = 纠错频率 K;δ 连续化;C17 对账闭合;UAV 场景(2026-09-22 凌晨,X11 / X28 / X29 / X14)

X11(scripts/11_latent_roundtrip.py) —— "第三种曲线"的正确形态不是再画一条, 而是把两条现有曲线的唯一差异(往返映射 R = encode∘decode 的施加频率)变成自变量:

  • 端点恒等式被证明(assert 逐位):K=1 ≡ 闭环、K=∞ ≡ 开环(最大差 1.2e-11);
  • 150 epoch 下 H*(K) 平坦(22.50±2.48 vs 23.53±6.18,效应 < 种子噪声);
  • K 的效应随模型质量衰减(ΔH*:+6.1@5ep → +1.0@150ep;趋势成立、幅度不可引用);
  • "轨迹漂出训练分布"假说被推翻(Mahalanobis 距离几乎不随视界变化)。

X28(scripts/12_delta_continuity.py) —— 救活 §⑦ 的死路:注入过程噪声 + 概率模型(GaussianWorldModel,NLL 训练),δ 第一次可测:

  • δ 可分辨 ⇔ 模型均值误差 ≲ 潜空间分布宽度 ⇔ latent_dim=4(D≥8 饱和回 1);
  • δ(mean/median)随 σ_env 单调下降:1.00 → 0.84 → 0.59 → 0.34 (★ 宽分布"兜住"均值误差 —— 与直觉相反,实测方向为准);
  • δ_max 在 σ≤0.1 仍饱和 ⇒ C17 的 max 定义在实践中过强 (平均意义上很好的模型得到几乎为零的保证 —— 可写进论文的实证批评);
  • 方差头粗校准:σ_pred ≈ σ_true(系统性略偏大)—— B1 的第一块。

X29(scripts/13_x29_reconcile.py) —— δ 可测之后的 C17 对账(⑧ 环闭合):

σ_env δ_med H(ε,δ) 理论 H* 实测 H*/H
0.1 0.61 1.08 18.85 17.5×
0.3 0.31 1.15 9.76 8.5×

gap ≈ 8.5–23.8×,数量级真实;保守性来源可实证(max 定义 + measurand 双重过强)。 ⚠️ measurand 断裂点仍在(序反转 vs 误差超阈)⇒ gap 只能定性引用,不能当倍数宣称。

C17 reconciliation

X14 首跑(configs/uav.yaml + envs/uav_track.py) —— 自建 2D UAV 跟踪场景 (双积分器 + 阻尼 + 风扰过程噪声):

  • 架构声明首次实测:02 训练管线零改动跑通新场景(唯一例外 = env kwargs 透传 1 处);
  • H*(σ=0.15,3 种子,逐点口径):开环 11.41 ± 4.10 / 闭环 9.00 ± 4.44 (CV 0.36 / 0.49,与 Pendulum 的 0.42/0.38 同量级;开环>闭环在 3/3 种子一致);
  • 闭环误差饱和于 NMSE≈1(噪声环境的理论特征)。
  • σ 敏感性(3 种子 × {0, 0.15, 0.5}):H* 随噪声单调下降(开环 16.1→11.4→8.8) —— 通信压力在 UAV 上显出梯度(Pendulum 上"调度全部差不多"的死寂不见了); ★ σ=0 时排序反转(闭环 > 开环,2/3 种子;std≈均值,3 种子不足以下强结论,待确认)。

X12-min(scripts/15_sigma_calibration.py) —— σ 头校准检查(B1 第一块):

  • 逐维 std(r) = [1.06, 1.11, 1.01, 1.06],τ = 1.058(仅 6% 过度自信);
  • 覆盖率:名义 95% → 实测 93.2%,温度缩放后 94.5%;
  • 口径声明:这是潜空间单步转移的校准,obs 空间多步校准是 X12 完整版。

⑨ ★★ 任务锚定的 H*:误差阈值 ≠ 任务边界(2026-09-22,X30)

scripts/16_task_horizon.py + wmlab/control.py + configs/uav_task.yaml。

此前所有 H* 都是 NMSE > 0.05 定义的 —— 这个阈值与任务无关。 X30 第一次把「误差 → 任务」的映射测出来:UAV 跟踪场景 + 解析 PD 控制器, 控制器只看得见估计状态(丢包时世界模型 rollout 顶上)⇒ 模型误差会 反过来改变真实轨迹(compounding 第一次真正接上;此前 run_tracking 的动作来自离线数据,轨迹与模型无关)。

核心数字(100 集/点,周期调度 T ∈ [1,128])

口径 定义 H* / H*_err
H*_err 离线闭环 NMSE 逐点 > 0.05(沿用 X2/X14) 26.1 1.00
H*_escape 逃逸率 ≤ 基线 +0.02 24 0.92
H*_escape 逃逸率 ≤ 基线 +0.05 32 1.22
H*_dist 稳态距离 ≤ 基线 ×1.2 / ×2 / ×3 1 / 2 / 8 0.04–0.31

task-anchored horizon

  • 同一批数据上 H*_task 跨 32 倍(1–32 步),而 H*_err 只有一个数 ⇒ 换任务指标就会换结论。0.05 这个阈值恰好处在"灾难性失败"一侧 (H_escape/H_err=1.22),对"性能可感知退化"(距离口径)则保守 30 倍。
  • 闭环放大:同口径对账(在线估计误差按 age 分布平均 vs 离线曲线), 中位数比值 1.69(max 4.9)⇒ 闭环控制放大了模型误差,离线 H* 偏乐观。
  • 模型 vs persistence 基线:T=64 时逃逸率 0.42 vs 0.92;T≥96 时 persistence 全军覆没(1.00)而模型仍 0.46–0.50 ⇒ 世界模型顶上的价值随通信变差而放大。

★ 诚实交代(本实验的边界)

  1. 此时测到的视界是 (模型, PD 控制器, 周期调度) 三元组的属性,不是模型单独的属性;
  2. PD 增益是闭式解(kp=ω_n²=6.25, kd=2ζω_n−κ=4.5),稳态误差解析值 0.40 m (旋转坐标系向量解;第一版标量式 0.58 m 是错的——把正交的向心项与阻尼项相加了), 实测 0.89 m(含风扰,Jensen ⇒ 只会更高);确定性环境下自检验证到 1.4%;
  3. 加了 250 步预热隔离初始捕获瞬态:不加预热时 T=1 实测 2.86 m、|a| 全程饱和, 看起来像"解析错了",实际是 episode 只有 200 步、瞬态(~400 步)没走完。 —— 第 11 次自我修正,与前 10 次同根因:从图上"看出"数字就直接解释。

自检 ⑫–⑮(共 53 项)覆盖:增益闭式解、稳态=解析解、n_tx/E[age] 闭式解精确匹配、 T=1 估计误差恒为 0、NaN 闭环必须抛、estimator 开关接线。

⑩ ★ 自己写的 PPO,与「数据从哪来」的消融(2026-09-21,X5 / X6 / X7)

wmlab/agents/ppo.py + scripts/09_train_ppo.py + scripts/10_behavior_ablation.py。

X5(scripts/09_train_ppo.py) —— 不抄库,手写 PPO;文件头留完整推导 (策略梯度 → 重要性采样 → clip 为什么要双分支取 min → GAE → 三项 loss 的符号):

  • 确定性评估 500.0 ± 0.0(20 条全满),判据 PASS;
  • ★ 踩坑:Tanh trunk 让 79.6% 的激活饱和 ⇒ 梯度断流 ⇒ critic explained-variance 仅 0.24; 换 ReLU 后 209 → 500。同一份超参,差别只在激活函数。

ppo cartpole

X6 / X7(scripts/10_behavior_ablation.py) —— 世界模型的训练数据从哪来,决定了它的可靠视界:

训练数据来自 在 PPO 策略分布上的回报
随机策略 1.20 ± 0.35
PPO 策略(训练过的) 47.84 ± 6.27

3 种子配对差 +46.6 ± 6.1,3/3 同向。★ 不对称性:好策略的数据向下兼容差策略的分布,反之不成立 —— 所以"用随机策略采数据训世界模型"不是省事,是把模型上限压死。

behavior ablation

⑪ ★★ 突发信道:「突发」到底让误差变大还是变小?(2026-09-22,X31)

scripts/17_burst_channel.py + wmlab/eval/tracking.py::GilbertElliottChannel + configs/uav_burst.yaml

X24–X27 的信道是无记忆伯努利丢包;真实无线信道是突发的。X31 换成 Gilbert–Elliott 两状态模型,固定平均丢包率 p̄=0.5,只扫平均突发长度 L。

★ 第一个反直觉点:L=1 不是 i.i.d. —— 无记忆条件是 ρ₁ = 1−α−β = 0, 代入参数化得 L_iid = 1/(1−p̄) = 2。L=1 是"通/丢交替"(ρ₁=−1),L>2 才是真突发。 网格 1→32 连续穿过「交替 → 无记忆 → 强突发」三种机制。

核心数字(p̄=0.5,60 集/点,稳态口径)

L ρ₁ E[age]=p̄·L E[NMSE] 相对 i.i.d. 闭式偏差 一阶项占比
1 −1.000 0.50 0.00035 0.25× −2.6% 100%
2 0.000 1.00 0.00145 1.03× +2.8% 78%
4 +0.500 1.96 0.00480 3.4× −8.9% 67%
8 +0.750 3.94 0.01995 14.1× −0.5% 59%
16 +0.875 7.29 0.06888 48.9× −4.1% 59%
32 +0.938 14.57 0.20006 141.9× +1.4% 84%
  • ★★ 平均丢包率完全相同(50%),跟踪误差跨 570 倍(0.25× → 142×)。
  • ★★ 闭式恒等式 E[NMSE] = p̄·[f(L) + J(L)] 成立,相对偏差中位 −1.5% (f = 离线闭环 NMSE 曲线,J = Jensen 项;推导见 GilbertElliottChannel 类 docstring)。 ⇒ X26 的解析式从 i.i.d. 推广到任意突发信道,而且不需要实测 age 直方图。
  • ★ 一阶项 f(L) 平均占 74% ⇒ 突发的影响主要是一阶地拉长条件信息年龄, 不是 Jensen 高阶效应(J 全部 ≥ 0:凸性只是"雪上加霜",不是主因)。
  • L < L_iid(通/丢交替)反而更好 —— 条件年龄被压到 1 步。
  • 锚点:L = L_iid = 2 时 GE 与 i.i.d. 基线的 E[NMSE] 比值 1.029(两个独立实现接上了)。

burst channel

★ 两个必须写下来的口径陷阱(都是"看着完全合理"的假结果)

  1. 离线曲线被自己的最大视界挤进瞬态区:起点范围 t0 ∈ [0, T−h_max−1), h_max=190、episode 451 步 ⇒ 起点只能落在前 260 步,而 UAV 捕获瞬态占前 ~250 步 ⇒ f(1) 高估 49%、f(6) 高估 11%(偏差随 h 收敛,极易被误读成机制)。 修法:离线加 t0_min、在线加 warmup,两边都在稳态区;episode 拉长到 700 步 (否则稳态起点只剩 10 个)。对齐后在线实测 f_online(k) 与离线 f(k) 吻合到 5% 以内。
  2. n_tx 与 n_steps 不在同一区间:n_tx 在预热期也累加、n_steps 只记预热之后 ⇒ L=1 时算出丢包率 0.222 而非 0.5(差 23σ)。X26/X27 因 warmup=0 从未触发。

★ 第 13 次自我修正:凹凸性诊断必须局部化。全区间 mean(Δ²) = −0.12 会判成 "凹 ⇒ 突发更好",而相关区间(h ≤ L_max=32)内 Δ² 全为正(凸),实测 Jensen 项也全 ≥ 0。 原因是曲线末端进入饱和(幂指数跌到 −0.47),两个大负值把均值拉翻了,而 age 分布 根本取不到那么大的 h —— 用全区间均值判定,正是规范 R2 说的"看图下结论"。

任务层(闭环控制,60 集/点):逃逸率在 L≤8 时仍为 0,L=16 起 6.7%、L=32 达 25% ⇒ 任务对突发有明确容忍边界;稳态跟踪距离 2.9 → 7.2 m。 与 A 层同向(与 X30 不同:X30 里误差阈值与任务边界差 32 倍,这里两者方向一致)。

自检 ⑯–⑳(共 53 项)覆盖:GE 解析量、无记忆点不是 L=1、条件年龄恒为 Geom(β)、 tx_rate 与 warmup 同区间、t0_min 真的抬高起点。

⑫ ★★ 丢包率 × 突发结构:两个因子是解耦的吗?(2026-09-23,X31-b)

scripts/18_burst_sweep.py + configs/uav_burst_sweep.yaml(p̄ ∈ {0.2,0.35,0.5,0.65} × L ∈ {2,4,8,16,32})

X31 只在 p̄=0.5 一个点上验过 E[NMSE] = p̄·[f(L)+J(L)]。单点值不可引用 (X3/X4 的教训)⇒ 把 p̄ 也铺成网格。★ 模型与离线曲线各只算一次、全网格共享 —— 否则"模型质量"会混进 p̄ 的效应,检验直接失效。

待验的强预言:Gilbert 下条件年龄分布恒为 Geom(β),与 p̄ 无关;p̄ 只决定 P(age=0)=1−p̄,又 f(0)=0 ⇒ E[NMSE] = p̄·G(L),其中 G 只依赖 L。 ⇒ C1 数据塌缩(不同 p̄ 的 E[NMSE]/p̄ vs L 曲线重合)、C2 线性于 p̄(过原点直线)。

L G(L)(4 个 p̄ 的平均) 跨 p̄ 的 CV 种子内噪声 CV 比值
2 0.00271 1.2% 3.2% 0.38
4 0.00995 8.0% 4.7% 1.68
8 0.03816 2.3% 8.7% 0.26
16 0.13997 12.9% 7.5% 1.71
32 0.38716 5.2% 6.4% 0.81
  • ★ 5 个 L 里有 3 个的跨 p̄ 离散度低于噪声本身(比值 <1)⇒ 差异完全可由噪声解释。 最大比值 1.71 ⇒ C1 弱成立:解耦基本成立,残余依赖量级接近噪声。
  • G(L) 跨度:L=2 → L=32 是 143 倍;而 p̄ 只贡献一个线性因子。 ⇒ 通信上可分开设计:丢包率由链路预算决定,突发长度由信道时变性/移动速度决定。
  • 闭式恒等式相对偏差中位 −0.7%(最大 31.5%,出现在长突发+高丢包处)。
  • C2 线性:过原点直线的最大相对残差 29.4%(L=16)。

burst sweep

★ 第 14 次自我修正(一串,根因都是"统计检验的口径")

  1. TV 阈值不能用 3/√n:TV 是多类别之和,噪声随分布支撑集增长 —— Geom(β) 的 Σ√p_k = √β/(1−√(1−β)),β=1/32 时 ≈ 11.2 ⇒ n=6076 时 E[TV]≈0.057, 而 3/√n 只有 0.038 —— 阈值比纯噪声还小,必然误杀。改用 KS。
  2. 有效样本量不是 age 样本数:游程内 age 是 1…n 的确定性序列,一个游程只有 1 个独立样本,用 n_pos 会把检验功效高估 √L 倍。
  3. 多重比较:20 个网格点各做一次 α=0.05 检验 ⇒ 至少一个误报的概率 64%。 实测正是第 13 个点 KS 判"显著"(只超 4%),而同一份数据均值检验 z=+2.3 正常。 ⇒ 改 Bonferroni(临界值 1.36/√n → 1.83/√n)。
  4. 没有噪声基准就不能下结论:单种子版跑出 CV 16.7%,无从判断是机制还是噪声 ⇒ 加 --seeds 重复,用「跨 p̄ 的 CV / 种子内噪声 CV」判定。

⑬ ★★ 物理层:量化精度 × 调制阶数的速率—可靠权衡(2026-09-23,X32)

scripts/19_physical_layer.py + wmlab/eval/physical.py + configs/uav_physical.yaml

★ 不是"SNR→丢包率"查表(那对 X31 零增量)。本实验做的是真 tradeoff: 每时隙固定 N_sym = d 个符号,要传 d·b 比特 ⇒ 每符号必须承载 m = b 比特 ⇒ M = 2^b,b=2/4/6/8 恰是 4/16/64/256-QAM。

b ↑  量化更精细(误差 ∝ 2^(−2b))   但 M ↑ ⇒ 星座更密 ⇒ BER ↑ ⇒ PER ↑ ⇒ 丢包更多
b ↓  星座抗噪(PER 低)             但量化粗糙(**每次到达都注入**误差)

核心结果一:b* 随 SNR 单调增(每点 40 集)

SNR 5dB 10dB 15dB 20dB 25dB 30dB
b* 2 4 4 6 6 8

⇒ 链路越好,越该把比特花在精度上而不是抗错上。

核心结果二(★ 这才是被数据支持的那个):模型的价值随 PER 增长

SNR/b PER 量化占比 model persistence 增益
30dB b=2 ~0 100% 0.05147 0.05147 ×1.00
15dB b=4 0.10 98% 0.00409 0.00438 ×1.07
20dB b=6 0.26 42% 0.00058 0.00131 ×2.26
25dB b=8 0.46 1% 0.00110 0.00387 ×3.51
15dB b=6 0.91 2% 0.06311 0.26673 ×4.23

低 PER(<0.05) 平均 ×1.03;高 PER(>0.3) 平均 ×3.10。 且逐点看,增益不是由 PER 单独决定,而是由丢包在总误差中的份额决定 (15dB/b=4 量化占 98% ⇒ 仅 ×1.07;15dB/b=6 量化占 2% ⇒ ×4.23)。 ⇒ 世界模型补的是丢包(时间上的空缺),不是量化精度(每次到达都存在的地板)。

physical layer

★ 预写判据的命运:我跑前写的是 P1(b*_model > b*_persistence,理由"模型能扛 PER ⇒ 敢用更高阶调制")。实测 b* 两者相等(P2)。但数据支持的是更精确的版本: 模型没有移动最优点,而是把 U 形的右支(高 PER 区)整体压低 3–4 倍。 ⇒ 推理方向对,但"移动 b*"这个表述错了。

★ 第 15 次自我修正:我最初以为"模型能补信息损失 ⇒ 可用更粗量化 ⇒ b* 下移"。 错在没分清两种损失的性质:量化每次到达都注入,是硬地板;丢包只在丢时出现。

⚠ 待核:M-QAM 误码率用的是教科书近似式(Proakis/Goldsmith),绝对数值未与 标准表核对。已自证的只有:M=4 退化为 QPSK 精确式 Q(√γ_s)、PER 单调性、SER 饱和在 1−1/M。⇒ 本实验的结论(b* 的存在与增益趋势)只依赖定性结构; 任何"在 SNR=X dB 时 PER=Y"的定量表述,核对前不得写进论文。 ★ 已发现的公式失效区:BER ≈ SER/log2(M) 在 SER 饱和时不再成立 (256-QAM 饱和时它给出 BER=0.124,而物理上应趋近 0.5),已显式标记 formula_valid。

⑭ ★★ 跨层预报:丢包 × 量化能不能闭式算出来(2026-09-24/25,X33)

scripts/20_additivity.py + configs/uav_additivity.yaml + wmlab/rollout/imagine.py(新增 payload_fn)+ wmlab/eval/tracking.py

★ 这是把 X31/X32 两条支线合并的实验。 前面每个实验都只动一个旋钮;真实链路是 「物理层出 PER ⇒ 链路层出年龄分布 ⇒ 应用层出跟踪误差」三层串起来。X33 问的是: 能不能只量两条离线曲线,就把在线误差算出来?(这是 X34 联合设计的前提)

核心观测量:离线曲线 g_b(h) —— 从被量化过的起始状态出发做闭环 rollout 的误差 (对比 X31 的 f(h):从真实状态出发)。在线误差的闭式预报就是

E[NMSE] = Σ_h P_age(h) · g_b(h)      只用离线曲线 + 信道参数 (p̄, L),不碰该点的在线实测

★ 网格必须"反解 SNR",不能列 SNR(第一版 20 个点里 19 个作废): 4-QAM@25dB 的 BER≈1e−71 ⇒ PER 直接下溢成 0 ⇒ E[age]=0 ⇒ 判据全假。 ⇒ 改成按目标 PER 二分反解 SNR(snr_for_target_per),PER ∈ {0.005…0.7}。

主判据 W(闭式预报,72 个工作点)

口径 中位 |偏差| 90 分位 最大
解析年龄分布(真·闭式) 5.0% 45.6% 620%
换成实测年龄直方图 3.4% 17.3% 34.3%
不带量化的 X31 旧结论 10.0% — —

⇒ W2:定性成立、定量不够。 但换成实测直方图后最大值从 620% 掉到 34% ⇒ 那 620% 不是分解式错了,是"整段测量只撞见约 3 次突发"的采样问题 (最差点全在 PER=0.005, L=32 与高 b 处,那里误差绝对值只有 1e−5 量级,分母极小)。 引用时这两个数字必须成对出现:中位 5.0% 与 90 分位 45.6%。

★ 副判据 A:误差不可加(第 15 次自我修正)

预写的是"量化误差会被 rollout 的雅可比放大"。实测 Δ_b(h) = g_b(h) − f(h) 随年龄衰减:Δ_b(K)/Δ_b(0) = −2.26 (b=2) / −6.45 (b=4) / −15.5 (b=6) / −182 (b=8)。 ⇒ 量化误差被 rollout 洗掉了,不是被放大。 4/4 个 b 同向(A2 判据)。

放大倍数 A = (N_full − N_drop)/N_quant 的两个预写假设都错了,照报:

预写 实测 结论
H1:A > 1 普遍成立且与 E[age] 正相关(ρ>0.5) A_model 中位 0.985,>1 的点仅 22/72;Spearman ρ = −0.04 ✗
H2:persistence 的 A 比 model 小(零阶保持不传播 q) A_persist 中位 1.010 > A_model 0.985 ✗(方向反了)

⇒ 说明「量化误差在 rollout 里被传播/放大」这个直觉模型是错的: rollout 是个收缩映射,注入的扰动会被动力学本身衰减。

★ 第 15 次自我修正(方法论):第一版判据用在线做差算 A,结果 b=2 给 0.52、 b=6 给 4.69(同一 PER/L,符号相反)⇒ 那是噪声不是机制。 ⇒ 换成离线曲线 g_b(h)(统计量好 1–2 个数量级),在线 A 降级为"次级诊断,不得单独引用"。

★ 与 X32 的一致性:quant_share(量化在总误差中的份额)从 b=2 的 99.99% 降到 b=8/PER=0.7 的 0.08% —— 与 X32「模型补的是丢包不是量化精度」同向,两条独立路径互证。

additivity

⑮ ★★ 联合设计:发送周期 T × 量化精度 b(2026-09-25,X34)

scripts/21_period_design.py + configs/uav_period.yaml + wmlab/eval/tracking.py(新增 periodic_age_pmf / periodic_mean_age / periodic_age_tail / periodic_lossy_schedule)

★ X34 是 X33 的直接用途:既然误差能闭式算出来,那"发送周期 + 量化精度"这对 设计变量就可以不跑闭环仿真地扫。物理约束是每时隙只有 d 个符号:

T 步发一次 ⇒ 一个包摊到 T·d 个符号 ⇒ 每符号 m = b/T 比特 ⇒ M = 2^m

⇒ 周期和精度在同一份符号预算里互相挤:想发得勤(T 小)就得每符号多扛比特 (m 大 ⇒ 高阶 QAM ⇒ PER 高);想发得细(b 大)就得要么高阶调制、要么拉长周期。

★ 周期发送的年龄分布(本实验的新闭式,② 类证据写在 tracking.py 里)

P(age = h) = (s/T)·q^⌊h/T⌋ ,   s = 1−q
E[age]     = T·q/s + (T−1)/2

T=1 退化为 X31 的 i.i.d. 几何分布;q=0 退化为 (T−1)/2 —— 周期本身就是信息代价:一个包都不丢,年龄也在 0…T−1 上循环。

主判据(修正尾部判据后的全量,694 s,32 个 (SNR,b) 组见到周期真的起作用)

判据 预写 实测 结论
D1 闭式预报 |偏差| 中位 < 15% 中位 3.1%,90 分位 7.0% ★ 成立
D2 闭式 argmin T* vs 仿真 一致或相邻 54/54 一致(相邻 54/54) ★ 成立
D3 T*_model ≥ T*_persist ≥75% 的配置 100%(中位 2 vs 2 步) ★ 成立(但中位数相等 ⇒ 只支持"不劣于",不支持"更长")

⇒ 设计曲线可以不跑闭环仿真地算出来,且选出来的点是真的最优点。 D1 的 90 分位 7.0% 集中在高 PER 档(最大单点偏差 +11.9%,26dB/b=16/T=4)。

★ 反直觉的一点:PER=0 时 T=1 并不总是最优

b=4 的候选只有 T∈{1,2}。在 10→30dB 全部 5 档里,PER 都是 0,但 T*=2(0.00394) 一致地优于 T=1(0.00411)。差额只有 4%,但 5 档数字完全相同(不是采样噪声)。

机制:多推一步会把量化噪声洗掉 —— 即 X33 的 A2 结论(Δ_b(h) 随 h 衰减) 在联合设计里的直接后果:闭环动力学是收缩的,注入的量化扰动会被动力学本身衰减, 而"每步都送"反而把这个免费的平滑机会浪费掉了。

★ 但这条必须限定在 b=4:由 30dB(两条候选的 PER 都是 0)反解, b=4 的 g(1) = 2×0.00394 − 0.00411 = 0.00377 < g(0) = 0.00411(洗掉的多于模型一步误差); 而 b=6/8/16 在同档位都是 T 越小越好(T*=1 / 1 / 2)⇒ 量化地板一旦降下去, "洗噪声"的收益就盖不过"多等一步"的代价。 ⚠ 幅度只有 4%,且只在最粗的量化档出现 ⇒ 引用时必须标注这两条限定, 不得写成"应该拉长周期"的一般结论。

★ 第 16 次自我修正(R12):第一版的"年龄分布截断判据"写成了 1 − (1−q)^{K/T}("至少一次失败"的概率),而这里要的是 q^{K/T}("全部失败")。 两者都随丢包率增大,但量级差约 160 个数量级(q=0.019, T=2, K=190:错式 83.8%, 正确 ≈1e−160)⇒ 第一版把 PER>0 的点全部误判为截断丢掉,网格里只剩 PER≈0 的退化点, 于是 D2 只有 26 组、且看不到 U 形内点最优。 ⇒ 现已抽出库函数 periodic_age_tail,并在自检 ㉛ 里与暴力求和逐点对齐、 同时钉死方向(随丢包率单调增)与量级(0.019/2/190 必须 < 1e−100)。 (我在写这条注释时一度把方向也写反了 —— 是 ㉛ 的单调性断言把它抓出来的。)

period design


⑯ X35「任务锚定的联合设计」:闭式选的 (T, b) 还是不是任务最优的?(2026-09-25)

python scripts/22_task_design.py            # 全量(SNR 5 档 × 10 个 (b,T) ⇒ 46 个工作点)
python scripts/22_task_design.py --quick    # 冒烟

★ 与 X34 的唯一关键差别:真闭环。 X33/X34 的 run_tracking 是开环回放 (动作来自预先采好的 episode ⇒ 轨迹与模型无关);X35 用 control.run_closed_loop_control, 动作来自 controller(est) ⇒ 模型误差会改真实轨迹,量化器 payload_fn 第一次真正进入闭环。

★ 一句话答案:60% 一致,40% 不是

判据 预写 实测 结论
闭式 argmin T == 任务 argmin T — 12/20(60%) ★ 按 NMSE 闭式设计,10 次里有 4 次选不到任务最优点
T2 Spearman(est_nmse, 跟踪距离) ρ ≥ 0.8 +0.778 ★ 未达标 ⇒ NMSE 不能当任务代理(这正是本实验要的结论)
T2 Spearman(est_nmse, 逃逸率) ρ ≥ 0.8 +0.354 ★ 更不能(且 44/46 点逃逸率恒为 0 ⇒ 该指标在本网格无分辨率)
T1 任务退化 / NMSE 退化 ≥ 2× 中位 0.07×(≥2× 的点 6/20) ★ 预写不成立:任务指标对设计点比 NMSE 钝得多
T3 任务差距 / NMSE 差距(距离) ≥ 1.2× −0.18× ★ 预写不成立(见下,这是本实验最硬的负面结论)
T3 任务差距 / NMSE 差距(逃逸率) ≥ 1.2× 1.70× ✅ 成立(但 n 有效点少,只可定性)
T5 闭式预报 → 闭环实测 |偏差| 显著大于开环 中位 8.1%(p90 23.0%) ✅ 成立:X34 开环口径中位是 3.1% ⇒ 闭环把偏差放大约 2.6×

★★ T3 = −0.18×:模型把 NMSE 降到 1/2.3,却没换来跟踪距离

量化精度 b NMSE 比(model/persist) 尾段距离比(model/persist) 模型反而更差的点
4 0.871 1.446 8/10
6 0.462 1.048 6/10
8 0.406 0.922 5/12
12 0.357 0.954 5/14

⇒ 趋势是单调的:量化越粗(模型的相对优势越小)⇒ 模型在任务上越可能反而更差。 ⚠️ 机制未查清,不得编解释。 已排除的不是机制:① 不是窗口口径(mean_dist 全程 / 尾段 / p95 三个口径同向,ep_len 都是 300 ⇒ 不是删失);② 不是两个 head 被搞混 —— T=1 且 PER=0 时 两者逐位相同(4.426 vs 4.426、4.681 vs 4.681,比值 1.000)⇒ 管线正确。 候选机制(只是候选):PD 控制器的 D 项作用在估计值的变化率上,模型估计每步由 rollout 更新 ⇒ 高频抖动比"保持上一帧"的 persistence 更大,粗量化下这份抖动放大成控制代价。待查。

⚠️ 引用 X35 必须同时带上的三条警告

  1. 本网格里没有点真正收敛:尾段距离中位 3.9 m(范围 2.6–19.3 m),而 X30 同场景的稳态是 亚米级 ⇒ 距离指标主要反映"追不上",不是"稳态偏移"。在这个区间上比较任务指标, 结论的强度弱于"稳态工况下的比较"。
  2. 逃逸率在本网格基本无分辨率:44/46 点恒为 0 ⇒ T1/T2/T3 里所有基于逃逸率的数只可定性。
  3. 删失 4/46 点(episode 因逃逸提前结束,ep_frac 最低 0.42)⇒ 这些点的 E[age] 与 NMSE 都偏低。 已做敏感性对照(未删失 44 点):T2[距离] 0.778 → 0.746、T5 仍 8.1%、argmin 一致 11/19 ⇒ 方向不变。

★ 第 17 次自我修正(容差不能拍百分比)

第一版 S_a 写「实测 E[age] vs 闭式相对差 ≤ 8%」,在 64-QAM@14dB(PER=0.9502, T=1)被打穿: 实测 17.51 vs 闭式 19.08(−8.2%)。诊断(纯调度空跑 24 种子,不含控制与删失)显示闭式无偏 (19.0067 ± 0.8935,偏差 −0.38%),错的是容差:该点 E[age]=19.08 而 sqrt(Var(age))=19.6 ——标准差与均值同量级,40×450 步只有约 900 次到达 ⇒ 单次实测标准误就有 4.7%, 8% 只是 1.8σ 的噪声。 ⇒ 现改为容差 = 3 × 本点采样标准误(SE 由纯调度 MC 估出,见 Var(age) = T²q/s² + (T²−1)/12、 自检 ㉜);删失点只做单侧断言(删失只会把均值拉低,偏高必是真 bug)。 修正后:46 点 |偏差| 中位 0.04σ、最大 2.08σ、超 3σ 的点 0 个。

task design


⑰ X36「突发信道下的联合设计」:只知道丢包率,够不够做设计?(2026-09-25)

python scripts/23_burst_design.py            # 全量(3 SNR × 5 (b,T) × 6 信道档 ⇒ 75 点)
python scripts/23_burst_design.py --quick    # 冒烟

★ 由来:X31 实测"同丢包率下突发让误差跨 570 倍",但 X34/X35 的设计闭式里信道只压缩成一个数 PER。 ⇒ 本实验问:做 (T,b) 设计时,总丢包率够不够用?

★ 物理模型(三条假设,跑前定死)

  1. 链路层阻塞 = Gilbert–Elliott 两状态链,按「尝试」演化(每 T 步走一步链);Good 全通、Bad 全丢(X31 同口径)。
  2. 非阻塞期叠加物理层逐包噪声丢包 PER(b,m,SNR)(X32/X34 同口径)。
  3. 一次尝试成功 ⇔ (Good) 且 (无噪声错包) ⇒ s = (1−p̄)(1−PER)。p̄ 是环境参数、PER 是设计参数。

★ 新闭式(精确 2×2 矩阵,不靠仿真):以「尝试次数」为单位的到达间隔 P(D_a=d) = v0·F^{d−1}·s,再由更新过程的平稳年龄公式 P(age=h) = P(D_a ≥ ⌊h/T⌋+1)/(T·E[D_a])、E[age] = T·(E[D_a²]−E[D_a])/(2E[D_a]) + (T−1)/2。 四条退化已验(自检 ㉝/㉞):L=L_iid ⇒ 与无记忆口径逐点相等(2.6e-12); T=1, PER=0 ⇒ p̄·L(X31 闭式,1e-10);pmf 自洽(1e-9);调度仿真 TV ≈ 0.003。

★★ 一句话答案:不带突发结构,预报会系统性低估误差(中位 −86.6%,49/49 同向)

口径 全部 75 点 无记忆档 k=1(26 点) 突发档 k>1(49 点)
突发感知 |偏差| 中位 8.1% 3.4% 16.1%
无记忆 |偏差| 中位 73.3% 3.4% 86.6%
无记忆 带符号中位 −73.3% +0.8% −86.6%(负值占 100%)
E[age]:突发 / 无记忆 2.23 / 1.01(1.92×) 1.19 / 1.19(1.00×) 3.93 / 1.01(4.00×)

⇒ E2 ✅ 成立且很强:倍数 9.10×;且符号完全一致地指向低估 —— "把突发当无记忆"会画出一条乐观得多的曲线,据此选出的工作点在实际里达不到。

★ E1 未达标(1/12 = 8%)—— 但必须连同机制一起读

预写"≥50% 的组 T* 会随突发长度偏移",实测只有 1 组移动(14dB/b=8/p̄=0.1:T* 4→2)。 机制不是"突发不影响设计",而是设计空间饱和: E[age] = (T−1)/2 + T·p̄·L 对 T 单调递增(PER≈0 的档位)⇒ 最优 T 永远想更小; 而 b=4 的候选 T 只有 {1,2}、6/6 组 T* 已经顶在 T=1,没有更小的档可去。 ⇒ 更精确的表述是:在 (T,b) 这两个旋钮上,突发改变的是「能做到多好」(误差从 0.006 涨到 0.19,约 30 倍),不是「该怎么做」。 想让设计点真的随突发移动,必须引入别的自由度 (功率、重传、自适应速率),T 这个旋钮不够用。

其余判据

判据 预写 实测 结论
E3 T* 随 L 单调不增 ≥70% 1/1 = 100% ✅ 方向一致,但只有 1 组发生了变化 ⇒ 不足以支撑一般结论
E4/S_d R12:改 L 必须改变实测 ≥1 组 26 组 ✅ 突发真的接进调度了
S_iid L=L_iid 时两口径一致 <0.5% 0.00%(26 点) ✅ 新闭式退化成立

⚠️ 引用必带:① 突发档的预报 |偏差| 中位 16.1%、90 分位 34.8% ⇒ 定量不够,只可定性; ② 阻塞(GE)与物理层噪声是两个叠加的独立机制,本实验没有把 SNR 映射进 GE 状态转移 (即没有做"阴影衰落 ⇒ SNR 下降 ⇒ PER 上升"的联合物理模型)⇒ 结论讲的是结构不是绝对数值。

burst design

⑱ X38「触发式调度」:等传输预算下,周期 / 年龄阈值 / 不确定性触发谁更好?(2026-09-27)

python scripts/24_triggered_scheduling.py            # 全量(6 PER × (10 T + 11 K + 8 U阈值) 闭环点)
python scripts/24_triggered_scheduling.py --quick    # 冒烟

★ 由来:X34 / X35 / X36 都隐含同一个假设 —— 发送是周期的(每 T 步发一次)。 而母论文那句话是 "schedules sensing updates based on task urgency and predictive uncertainty",说的是调度策略本身,不是"周期取多少"。 ⇒ 周期只是基线。本号把周期换成"按年龄 / 按不确定性触发",在同样的传输预算下比。

★ 文献归属(跑前钉死,不许抢功):「采样率约束下最优采样是阈值策略、且显式优于 uniform(周期)」已由 Sun–Polyanskiy–Uysal-Biyikoglu 解决(arXiv:1701.06734、1707.02531)。 ⇒ P1 / P2 不是新贡献,定位是「复现 + 移到 闭环控制 + 学习得到的世界模型 这个场景」。 真正的新问题在他们自己划的那条线上:signal-independent(周期 / 年龄阈值)vs signal-dependent(世界模型自报的累积不确定度 U) ⇒ P3 才是本号的贡献点。

Part A · P1(解析,等预算):✅ 阈值 ≤ 周期;✅ U 形也成立(但我差点因为网格截断判它不成立)

PER 最优 K 等预算 T = sK+1 阈值 E[age] 周期 E[age] 比值
0 1 2.00 0.500 0.500 1.000
0.1 1 1.90 0.585 0.661 0.885
0.3 4 3.80 2.271 3.029 0.750
0.5 8 5.00 4.600 7.000 0.657
0.7 32 10.60 17.277 29.533 0.585
0.9 32 4.20 21.571 39.400 0.547

⚠️ 表中 PER≥0.7 两行的 K=32 就是网格上界,不是解析最优(解析在 PER=0.9 上要 K≈128 才到 0.527) ⇒ 这张表给的是"在 K≤32 的可行集里能拿到多少",不含"最优 K 是多少"的结论。

  • ✅ PER=0 恒等(阈值 K ≡ 周期 T=K+1)与 K=0 ≡ i.i.d. 几何,由自检 ㉟ 逐位钉死(<1e-12); 等预算下"阈值 ≤ 周期"由 ㊱ 在 65×PER 网格上钉死;阈值 schedule 的有状态/可 reset 由 ㊲ 锁住。

  • ✅ 预写「比值随 PER 呈 U 形、存在内部最大增益点」成立 —— 但不是从上表看出来的。 ★★ 闭环网格只有 6 档 PER(最右 0.9)且 K ≤ 32,在该网格上比值看起来"单调下降", 我一度据此写下"不是 U 形、最优在边界"。这是第 19 次自证伪:解析细网格(PER 0.02–0.98 × 49 档, 已并入脚本 Part A)显示拐点就在 PER≈0.88–0.96,我的网格恰好卡在拐点左边:

    K 上限 最小比值 @PER 两端(PER=0.02 / 0.98)
    32(= 实验网格) 0.5459 0.88 0.9716 / 0.6871
    64 0.5304 0.92 0.9716 / 0.5985
    200 0.5152 0.96 0.9716 / 0.5239

    ⇒ 形状这类结论必须在解析式上扫细网格(免费),不许从 6 个闭环点的趋势推。 更丢人的是:自检 ㊱ 里本来就写了 U 形断言并通过,我却让 README 与自检互相矛盾并存 —— 预写判据的结论必须回头与实验输出对账。

Part B · P2(真闭环):★ NMSE 上阈值完胜,任务距离上几乎打平(第二次撞上 X35)

PER 阈值/周期 est_nmse 中位(更优率) 阈值/周期 mean_dist_tail 中位(更优率)
0 1.032(0/9) 1.000(3/9)
0.1 0.843(6/9) 1.000(4/9)
0.3 0.567(8/9) 0.955(5/9)
0.5 0.481(8/9) 0.988(5/9)
0.7 0.339(9/9) 0.967(6/9)

⇒ ★★ 这是 X35 之外第二个独立场景复现同一件事:est_nmse 最多降到 1/2.95, 而任务距离中位始终在 0.955–1.000、更优率只有 3/9–6/9 ⇒ NMSE 的收益在闭环里没换成任务收益。 配合 X35 的 Spearman(NMSE, 距离) = 0.778 < 0.8 ⇒ 现在可以说:本课题里 「NMSE 不能当任务代理」不是一次性的噪声,而是结构性的。

Part C · P3 ★★ 核心(负面结论,照报):U 只是 age 的替身

不条件看 ρ(U, err) = +0.365 像是"σ 有用";给定 age = h 之后:

量 值 含义
条件 ρ 中位 −0.029 几乎为 0
条件 AUC 中位 0.419 比随机(0.5)还差
ρ(U, h) +0.966 U 几乎只由 h 决定
CV(U) 不条件 / 条件 0.337 / 0.062 条件后只保留 18%
单步 σ 的 CV 0.071 ≈ 上面那个 18% ⇒ σ 头学到的就是个近乎同方差的常数

⇒ 判为 (a)「U 只是 age 的替身」,而不是 (b)「U 有方差但没校准」—— 因为条件后残余的变异量级正好等于单步 σ 自身的抖动,即 U 里根本没有状态依赖成分。

⚠️ 边界(不许过度推广):这是本场景的结论。本环境(解析 PD 控制器 + 小过程噪声) 本身近乎同方差 ⇒ σ 头 CV 只有 7.1%,既可能是"没训出来"也可能是"没什么可训"。 要区分必须做 X38-b:注入状态依赖噪声(风速随位置/高度变化),看 σ 头 CV 是否上升。 在 X38-b 做完之前,只能说"在这个场景下 σ 触发没有超出年龄的价值",不许推广成 "世界模型的不确定性对调度无用"。

Part D · P4:U 触发 ≈ 年龄阈值(与 P3 一致 ⇒ 这是证伪保护,不是新发现)

U触发 / 年龄阈值 中位:est_nmse 0.945–1.053、mean_dist_tail 0.976–1.018 ⇒ 基本恒等。 S_g(R12):6/6 个 PER 档上改 U 阈值使发送率变化 >5% ⇒ 不确定性触发确实接线了,不是空跑。 ⇒ P3 说"U ≈ f(h)"、P4 说"换触发量没差别",两者互相印证。P4 的价值在于: 若 P3 得 0 而 P4 有收益,那就说明我的测法有问题;现在两者一致 ⇒ 可以放心报负面结论。

预写判据结算

判据 预写 实测 结论
P1 等预算阈值 E[age] ≤ 周期 ≤1(PER=0 恒等) 0.547–1.000 全部 ≤1 ✅(恒等式也 ✅)
P1(b) 比值随 PER 呈 U 形 存在内部最小点 解析细网格:拐点 @PER 0.88–0.96(三档 K 上限全部内部) ✅(但闭环 6 档网格看不到 ⇒ 差点误判,第 19 次自证伪)
P2 闭环同 tx_rate 阈值更优 NMSE 与任务同向 NMSE ✅(最低 0.339)/距离 ❌(≈1.0) ⚠️ 不同向(X35 复现)
P3 ρ_cond ≥ 0.3 且 AUC_cond ≥ 0.6 U 有独立信息 ρ_cond −0.029、AUC 0.419 ❌ 负面结论成立
P4 U 触发 ≤ 年龄阈值 有收益 中位 0.945–1.053(≈1) ❌ 无差别(与 P3 一致)
S_e R12:σ 头真有变化 CV > 1% CV 7.1%(单步)/ 33.7%(累积) ✅ 不是"没训出来"导致的 0
S_f 年龄闭式在闭环里成立 全部 ≤3×SE 96/96 通过(中位 0.36σ、最大 1.99σ) ✅

⚠️ 引用必带:① 任务距离中位数 3.9–5.2 m,没有任何点真正收敛(与 X35 同口径); ② PER=0.9 档因三方 tx_rate 区间无重叠,P4 缺该档;③ 删失点 1/96,只做单侧断言。

triggered scheduling

⑲ X38-b「σ 头到底学没学出来?」:把 X38 的负面结论关进笼子(2026-09-27)

python scripts/24_triggered_scheduling.py --p3-only --wind-amp 0    # 同方差(X38 原档)
python scripts/24_triggered_scheduling.py --p3-only --wind-amp 4    # 强异方差

★ 由来(必须做,否则 X38 的结论站不住):X38 的 P3 说"U 只是 age 的替身", 但机制量显示 σ 头学到的单步 σ 跨样本 CV 只有 7.1% ⇒ 这件事有两种完全不同的解释:

  • (a) 环境本身同方差 ⇒ 根本没什么可学(那结论只是本场景的);
  • (b) σ 头没学会状态依赖 ⇒ 那是训练/模型的问题。

X38 自己无法区分这两者。X38-b 引入状态依赖的阵风场 σ(p) = σ₀·(1 + amp·g(p)) (g 是光滑的静态正弦场,只看位置;amp=0 时逐位退化为原环境,自检 ㊳ 钉死), 造出真异方差,看 σ 头能不能学出来 —— 学出来了才谈得上"U 有没有独立信息"。

★★ 结果:σ 头学得出来(是环境同方差,不是头不行)

wind_amp 真实 σ 的 CV 模型预测 σ 的 CV ρ(σ_pred, σ_true) 条件 ρ 中位 条件 AUC 中位
0(X38 原档) 0.0000 0.0709 NaN(真实 σ 为常数 ⇒ 无定义) −0.029 0.419
1 0.1828 0.2345 +0.665 −0.148 0.423
2 0.2678 0.2696 +0.883 −0.018 0.448
4 0.3354 0.3589 +0.851 +0.347 0.601

⇒ σ 头一旦有东西可学,就能学到 ρ ≈ 0.67–0.88(预报真实 σ)。 ⇒ X38 那 7.1% 是 (a) 环境同方差,不是 (b) σ 头不行 —— X38 的负面结论必须加"本场景"限定。

★ 剂量—反应:U 的独立信息是涌现的,不是线性的

ρ_cond 随异方差强度的走向是 −0.029 → −0.148 → −0.018 → +0.347:

  • amp ≤ 2 时 U 仍然没有超出年龄的信息(ρ_cond ≈ 0、AUC ≈ 0.42–0.45);
  • 只有 amp=4(真实 σ 跨 1×–5×)才跨过预写门槛 ρ_cond ≥ 0.3 且 AUC_cond ≥ 0.6 (实测 +0.347 / 0.601,AUC 刚好压线)。

⇒ "世界模型的不确定度对调度有没有用"不是一个是/否问题,而是取决于环境的异方差强度。 弱异方差下它确实只是年龄的替身;强异方差下它开始携带年龄以外的信息。 ⚠️ AUC=0.601 只比随机高 0.1 ⇒ 这条"达成"是压线的,不许当成强结论引用。

★ 第 20 次自证伪(判据里的拍系数)

诊断消息原本用「CV_cond > 0.5 × CV(U) ⇒ U 没退化」这个拍出来的 0.5 判退化。 U 是 h 步累积量 ⇒ CV(U) 被 h 那一维撑大 ⇒ 在 amp=4 档这个判据把 CV_cond = 0.539 也判成了"接近常数"(实际并不)。 ⇒ 改成拿单步 σ 的 CV 作参照(0.539 / 0.359 = 1.50× ⇒ 没退化), 且最终判定交给直接校准量 ρ(σ_pred, σ_true),不再让启发式下结论。 (同一个共因的第 20 次:拍一个"看起来合理"的系数当阈值,没先算它的量级。)

其余

  • S_e:σ 头 CV 从 7.1%(amp=0)升到 35.9%(amp=4)⇒ 不是"没训出来"。
  • 产物:outputs/24_triggered_scheduling_wind{0,1,2,4}.json (★ 第一版文件名只按 homo/hetero 分 ⇒ 4 个剂量档互相覆盖只剩最后一个,已修)。
  • 自检 ㊳:wind_amp=0 逐位等于 noise_std;CV(真实 σ) 随 amp 单调增; 同一位置的 σ 必须相同(场是静态函数,不是随机项);不同位置必须不同。

⑳ X39「阵风场下的闭环触发式调度」:把离线信息量搬到闭环(2026-09-29)

承接 §⑲。X38-b 只跑了 --p3-only(离线信息量):U 有独立信息(ρ_cond 0.347 / AUC 0.601 压线)。 但「离线有信息」≠「闭环有收益」—— 缺的正是最后一跳。本号把 X38 的完整流程 (Part A 解析 / Part B 闭环 P2 / Part C P3 / Part D P4)搬到 **wind_amp=4(强异方差)**重跑。 产物:outputs/24_x39_final_wind4.{json,png};图:assets/25_x39_triggered_wind4.png。

★ 一句话答案:P2'/P4' 双双不成立;而且 P4' 这条判据本身与实现自相矛盾

PER 阈值/周期 NMSE 中位 阈值/周期 距离中位 U触发/年龄阈值 距离中位 U触发/年龄阈值 NMSE 中位
0.1 0.813(8/9) 0.993 1.020 1.334
0.3 0.642(8/9) 0.982 1.018 1.338
0.5 0.481(8/9) 0.950 1.031 1.172
0.7 / 0.9 — 不可评估 — — —

预写 P4' 要求 U触发/年龄阈值 距离中位比 < 0.98 ⇒ 实测 1.018–1.041,方向反了。

★★ 机制:闭环 ρ(U, age) = 0.9941 ⇒ 全局阈值 ≡ 年龄阈值

utrigger 的阈值就是 thr = median(U[:, h*−1])(按名义触发年龄标定),而闭环里 U 几乎是 age 的确定性单调函数(0.994)⇒ U ≥ thr 与 age ≥ h* 是同一件事。 ⇒ 我一边用 P3 证明「U ≈ age 的替身」,一边预写「U 触发应优于年龄阈值」——两条不可能同时成立。 ⇒ 本号只能证明「全局阈值不行」,不能证明「U 无用」 ⇒ 直接催生 §㉑。

⚠️ 引用必带

  • PER=0.7/0.9 不可评估:原因是 periodic 族可比点塌缩(2 个 / 1 个),不是窗口太窄 ⇒ 强衰落区(PER ≥ 0.7)在本场景做不了等预算比较(脚本会打印原因,不静默跳过)。
  • diverged(NMSE>1 或 E[age]>max_age_K)对三族统一施加(2026-09-29 修:原先只作用于 utrigger)。 离线重算:X38 三族 0/0/0(零影响)、X39 结论不变 ⇒ 负面结论稳健。
  • 前置检查全过:S_f 年龄闭式 96/96;σ 校准 ρ(σ_pred,σ_true)=0.851; P3 条件信息 ρ_cond 0.347 / AUC 0.601(与 X38-b 一致);S_g 接线 6/6。

㉑ X40「条件化触发」:U 的边际任务价值是不是 0(2026-09-29)

承接 §⑳。把「U 的边际价值」与「安全网」分开:残差只准加速,安全网 K 不动。 产物:outputs/24_x40_final_wind4.{json,png};图:assets/26_x40_conditional_wind4.png。

★★ 一句话答案:H1 ❌ / H0 ✅ —— U 的任务边际价值 = 0,且该结论与实现无关

版本 触发规则 检验什么 结果
X39 utrigger U ≥ thr(按名义年龄标定) 全局阈值 ❌ 与年龄阈值数学等价(ρ(U,age)=0.9941)⇒ 判据作废
X40 ① resid z ≥ τ,z=(U−Û(age))/Ŝ(age) 撤掉安全网的纯残差 ❌ 净有害:同率下 E[age] 7.9–14.6 vs 年龄阈值 4.0
X40 ② hybrid age ≥ K 或 z ≥ τ ★ 干净的边际价值 ❌ H1 在全部可评估档位不成立
PER hybrid/年龄阈值 距离中位 (更优) hybrid/年龄阈值 NMSE 中位
0 1.147 0/9 4.107
0.1 1.094 0/9 1.820
0.3 1.023 2/9 1.907
0.5 1.035 1/9 2.276
0.7 / 0.9 — 不可评估 — —

⇒ 预写 H1(< 0.98)❌;H0(边际价值 = 0)✅,且实测系统性 > 1: 把「模型自报的额外不确定度」用来加速发送,比单纯把年龄阈值调小更差。 机制:U 的残差不是误差的预报器(条件 AUC 仅 0.601,只比随机高 0.10) ⇒ 加速发生的时刻不是真正需要的时刻 ⇒ 等预算下"用错地方的通信"换掉了"用对地方的通信"。

退化钉死(S_h,三条全过)

τ=+∞ ⇒ E[age] 1.0000 vs 纯阈值闭式 1.0000(相对差 0.00%);K=1 / τ=−∞ ⇒ 0.0000,与 T=1 一致 ⇒ 「只准加速」确实只加速(没有偷偷改掉安全网)。

★ 本轮修掉的三个 bug(全都在本节的代码路径上,都有回归测试)

  • ㉒ diverged 口径不对称(原只在 utrigger 分支算)⇒ 判定上移到 _mkrow,三族统一。
  • ㉔ 残差 τ 用原始残差的全局分位 ⇒ 尺度随 age 变 ⇒ 假结果(中位 4.77×、0/9) ⇒ 改 z 分数(Ŝ = 1.4826×MAD)。
  • ㉕ 配对窗口守卫太松(hi > lo×1.0001)⇒ 用 5% 跨度的窗口造出「9/9 更优」的假头条 ⇒ 抽出 wmlab/eval/pairing.py(hi ≥ lo×1.5 + 每族 ≥3 点 + 不可评估必须打印原因),自检 ㊵。
  • 另修一处图形缺陷:图 suptitle 原先硬编码 "X38 触发式调度" ⇒ X39/X40 的产物图全顶着 X38 的名字 (payload["experiment"] 早已派生,图漏了)⇒ 现改为从 args 派生(含 trigger 与 wind_amp)。

⚠️ 引用必带

  • PER=0.7/0.9 不可评估(periodic 族点塌缩,非窗口问题)⇒ 强衰落区做不了等预算比较。
  • hybrid 14/90 个点发散,已按统一口径剔除;任务距离中位仍 6–12 m、没有点真正收敛(承 §⑯ X35)。

㉒ X41「U 边际任务价值的剂量—反应」:信息涨 12%,价值还是 0(2026-09-29)

承接 §㉑。审前提:X40 的「边际价值 = 0」只在 wind_amp=4 一档成立,而该档离线判别力 AUC_cond = 0.601 只比随机高 0.10 ⇒ 不能排除"信息更强一点、价值就会涌现"。 产物:outputs/24_x41_dose_wind{8,16,32}.json(离线补扫 3 档)+ 24_x41_hybrid16_wind16.{json,png}(闭环); 图:assets/27_x41_dose_response.png;脚本:scripts/25_x41_dose_response.py(只读产物、秒级可复算)。

★★ 一句话答案:离线信息涨了 12%(0.601 → 0.674),任务边际价值仍然是 0

amp CV(σ_true) AUC_cond ρ_calib 距离比中位 NMSE 比中位 diverged
4(§㉑) 0.335 0.601 0.851 1.0648(n=4) 2.0915 14/90
16 0.454 0.674 0.819 1.0122(n=5) 1.3133 0/186

⇒ B1 判据(距离中位比 < 0.98 才算"价值涌现")不成立;5 个 PER 档里只有 1 档低于 1, 中位系统性 > 1 ⇒ X40 的负面结论在"信息最强档"上加固,替代解释「信息不够强」被排除。 ⇒ ★ amp=16 的证据比 amp=4 更硬:零发散(0/186)、5 档全部可评估(窗口跨度 2.11×–8.38×)、 σ 校准逐位复现(ρ(σ_pred,σ_true)=0.8188,与同档 --p3-only 完全相同 ⇒ 两边是同一个模型)。

★ 七档离线剂量:AUC 非单调 ⇒「信息随异方差单调增强」这个直觉是错的

0.419 / 0.423 / 0.448 / 0.601 / 0.600 / **0.674** / 0.520(对应 amp = 0/1/2/4/8/16/32)

  • amp=4 与 amp=8 几乎相同(0.601 / 0.600);峰值在 amp=16;amp=32 崩塌到 0.520。
  • ★ 崩塌的根因是 σ 头学不动:ρ(σ_pred,σ_true) 在 amp≤16 稳定在 0.815–0.883, amp=32 断崖到 0.448 ⇒ 这是模型能力上限,不是环境没信息。
  • ★ ρ_cond 与 AUC 不同步(amp=4 的 ρ_cond 最高 +0.347,但 AUC 只有 0.601)⇒ 两者不能互换。

★ 剂量轴的"上限"是场景级的(outputs/_temp/_x41_gust_scan.py,env 直接采样)

解析式 CV = amp·std(g)/(1+amp·mean(g)) 在 amp≤16 吻合 ≤2.2%;且 std(g)/mean(g) 在 7 档里稳定在 0.50–0.57 ⇒ 本 env 的异方差强度上限 ≈0.55 ⇒ 要更强必须改环境设计(wind_period / 轨迹覆盖),不是把 wind_amp 调大。 ⚠️ amp=32 处解析比实测低 13.8%,且方向与"分布漂移"相反(实测 std(g) 反而下降) ⇒ 来源未查清,照实标注(自证伪 ㉖)。

⚠️ ★★ 引用必带 —— 三条 2026 新作让结论收窄(不写这段就是抢功)

  • C29(arXiv:2609.15801,2026-09-14)已经把「预测信息量本身不决定下游损失」一般化地提出, 并给出构造性反例(两个转移律可有相同的 occurrence 信息与条件方差、却需要相反决策)⇒ "信息与价值脱钩"不是本课题的发现。
  • C30(arXiv:2607.01537)用 calibrated rollout-drift envelope 在 matched sensing budget 下 赢过了 expected-belief 调度 ⇒ 差异在「校准」⇒ 本课题的结论只能写成 「未经校准的自报不确定度 U 没有边际任务价值」。
  • C31(arXiv:2609.10954)的 fork ledger(预注册决策点 + 共同随机数)配对协议 比本课题的等预算插值严;其"总是更新 ⇒ 三个任务全部降回报"与 X40「纯残差触发净有害」同构。

⇒ 我方剩余增量:① 闭环通信调度的等预算实测倍数;② 机制(U 与 age 闭环共线 ρ=0.994、 条件判别力非单调且封顶 0.674);③ 剂量—反应把"信息涌现"与"价值涌现"画在同一条轴上。 ⇒ ★ 下一步(明确):把"自报 σ"换成 conformal 校准后的量(对齐 C30), 再看边际价值是否从 0 变正 —— 这是从"证伪"走向"方法"的一步。

㉓ X42「共形(conformal)校准的误差信封触发」:校准把"更差"变成"持平",但没变出正价值(2026-09-29)

承接 §㉒ 的"下一步"。规则结构逐字沿用 X40 的 hybrid(age ≥ K 或 触发,安全网 K 不动、 触发只准加速)⇒ 只换统计量、不换结构(消融封死混淆变量)。 唯一差别:X40 卡 z=(U−Û(age))/Ŝ(age) ≥ τ(τ = z 池分位点,尺度锚在调度上); X42 卡 Ê_α(h,U) ≥ tol,其中 Ê_α(h,U)=ĝ(h,U)+Ŝ(h)·Q_α (ĝ = 逐年龄 PAVA 单调拟合、Q_α = 分数 (e−ĝ)/Ŝ 的 ⌈(n+1)(1−α)⌉ 阶统计量), tol = 能容忍多大误差(尺度锚在任务上)。

★★ 一句话答案:H0 成立 —— 换成有覆盖保证的校准量后,边际任务价值仍为 0

臂(--conf-target) 跨 PER 任务距离比中位 跨 PER NMSE 比中位 配对符号检验(vs 同档自报 z)
pos(位置维误差 = 控制器吃进去的量,任务对齐) 0.9969(n=5 档,0 发散) 0.9897 4/5 档同向,p=0.188 ⇒ 不可分辨
nmse(全维误差,与 X38/X40 同口径) 0.9962(n=5 档,0 发散) 0.9932 5/5 档同向,p=0.031
—— 对照:X41-B 自报 z(同档 amp=16) 1.0122 1.3133 —
—— 对照:X40 自报 z(amp=4) 1.0648 2.0915 —

⇒ 读法(必须这么读):

  1. 主结论:与纯年龄阈值比,距离比 ∈ [0.98, 1.02] ⇒ 校准没有把价值从 0 变正(H0)。
  2. 副结论(这条是真增量):NMSE 比从自报量的 1.31 → 0.99 —— 校准把"比年龄阈值差"变成了"与年龄阈值持平"。自报 σ 的方向性是坏的(越信它越差), 校准把方向性修掉了,但没有造出方向性。
  3. 不许说的:「共形校准带来了任务价值」——效应量 ≤2%、两臂可分辨性不一致(4/5 vs 5/5)、 且任务距离本身无点真正收敛(承 X35/X41)。C30 自己也写明其短视界档 "empirical conformal horizons match the deployed clock" ⇒ 朴素共形并没有赢。

★★ 跑前先纠正了一处前提(本轮最有价值的一步,不花算力)

X41 §12.5 写的是「C30 用校准壳在等预算下赢过 expected-belief 调度 ⇒ 下一步 = 换 conformal」。 核原文(arXiv:2607.01537)后发现这是过度转述:C30 的正面结果来自 drift-aware 的 certified clock(谱项 + 校准信封),而它自己声明朴素共形在短视界档只打平。 ⇒ 「换成 conformal 就有价值」是没有根据的预期,本轮 H0 是先验上完全可能的结果, 照实预注册(S_c1 硬门 + H1/H0/H2 三条判据跑前写死)。

四道自检(全部通过)

  • S_c1 覆盖性(硬门):独立 episode 的留出集上边缘覆盖率 0.9157(目标 0.90, 3σ 容差 ±0.0035)⇒ 校准兑现;逐年龄覆盖率中位 0.9207 / 最小 0.8853。
  • S_c2 形状:ĝ 随年龄单调,违约 0/31 段;ĝ 中位 0.0014→0.5300(pos)/0.0155→0.7354(nmse)。
  • S_h' 退化:tol=+∞ ⇒ ≡纯年龄阈值(相对差 0.00%);K=1 / tol=−∞ ⇒ ≡T=1。
  • S_c4 接线(R12):0.67(nmse 臂)/ 0.46(pos 臂)的工作点上信封真的比安全网 K 更早触发;其余点等价于纯年龄阈值,对 H1 不构成证据(已在 JSON 里逐点记录)。

★★ 本轮踩掉的三个坑(都有回归测试 / 离线复算)

  1. 标定集为空(真事故):第一版直接 collect(n) 再 // 2 切分 ⇒ amp=16 时 _sample_windows 抛「没有可用窗口」。根因:PD 控制器在 amp=16 阵风下大量跟丢, seed=3000 的 8 条里只有 1 条长度 > 417(中位长度 169)。 ⇒ 改成跨多个种子批次收集、先筛"熬过预热"的 episode、再切分。 ★ 这顺带暴露了一条幸存者偏差:凡是 t0_min=WARMUP 的探针(X38-b/X39/X41 的 P3) 都在"熬过 400 步"的子集上算 —— 已在引用限定里登记。
  2. 跨臂变量复用(真 bug):汇报脚本在逐臂判定循环里误用了上一轮循环残留的 rows ⇒ 两臂的配对符号检验都在用最后一臂的数据,而输出完全正常 (数值合理、结论都印出来)。⇒ 加自洽守卫:这一臂的逐档中位必须等于这一臂的聚合值。
  3. 预写判据太松(自证伪 ㉗):H2 原判「中位差 ≥0.01 且 >2×档间散布」在 n=5 下判出"有增量", 补逐 PER 配对符号检验后 pos 臂 p=0.188 ⇒ 不可分辨。 "2×散布"这种拍系数判据会把倾向性读成结论 —— 已固化为 sign_test。

产物

scripts/26_x42_conformal_report.py(分块合并 + 覆盖守卫 + 符号检验 + 图); wmlab/eval/conformal.py(PAVA / 共形分位数 / 信封 / 覆盖性复核); 自检 ㊷㊸㊹ ⇒ 62/62;图 assets/28_x42_conformal.png、assets/29_x42_conformal_envelope.png。 ★ 分块跑的原因:完整网格单次跑不完(本机后台任务 10 min 硬上限,实测两臂都在 10m01s 被终止、连日志都没写出)⇒ 按 PER 分块(配对逐档独立 ⇒ 分块数值等价), 合并时覆盖守卫强制每个 PER 档都在场(缺档 raise)。

⚠️ 引用必带

  • PER=0.9 不可评估(periodic 族可比点塌缩到 1 点 ⇒ 强衰落区做不了等预算比较, 场景限制不是方法限制,承 X40/X41);n=5 档、零发散(0/306)。
  • 归属:C29(arXiv:2609.15801)已提出"校准单元上的 bounded-loss 增益 + 置信下界"; C30(arXiv:2607.01537)已提出"calibrated rollout-drift envelope 当重采样时钟"。 ⇒ 本号不宣称方法新颖,只贡献:闭环通信调度的等预算实测(校准量 vs 自报量 vs 年龄阈值 的三方对照)+ "校准修方向性、不造方向性"这个机制区分。
  • tol 阶梯 {0.05, 0.1, 0.2, 0.4} 锚在配置既有的 err_threshold=0.05(×2,跑前登记); 它是任务量纲、与环境尺度绑定 ⇒ 跨场景必须重标。
  • "价值 = 0" 只在本 env(正弦阵风场 + PD + 5.6 万参数高斯世界模型)上成立。

㉔ X43「oracle(特权)触发量」:连完美知道当前估计误差都赢不了年龄阈值 —— 瓶颈不在触发量(2026-09-29)

承接 §㉓ 的「下一步」第 1 条(也就是看板「下一步」第 2 项)。X38 → X39 → X40 → X41 → X42 一路在换触发统计量,「边际任务价值 = 0」已经五连。剩下的唯一问题是: 是不是「统计量还不够好」? ⇒ 规则结构逐字沿用 X40/X42 的 age ≥ K 或 触发(安全网 K 不动、触发只准加速)—— 只换信息来源、不换结构(消融封死混淆变量)。 唯一差别:X43 卡 z_or = (e − m(h)) / Ŝ(h) ≥ τ,其中 e = ‖est − 真值‖² / var_g 是仿真器内部的 ground-truth 误差 (control.py 写入 u_state["oracle_err"] / ["oracle_pos"])。

★★ 一句话答案:O0 成立 —— 连「完美知道当前估计误差」都赢不了年龄阈值

臂(--oracle-target) 跨 PER 任务距离比中位 跨 PER NMSE 比中位 口径核对(闭环 ÷ 离线 m(h))
res(全维 6/6,与 X38/X40/X41/X42-nmse 同口径) 0.9921(n=5 档,0 发散) 0.9311 中位 0.874(0.63–1.14)✓ 可迁移
pos(位置维 2/6 = 控制器吃进去的量) 1.0023(n=5 档,0 发散) 1.1675 中位 0.799(0.56–1.18)✓ 可迁移
—— 对照:X42 共形校准(amp=16) 0.9969 / 0.9962 — —
—— 对照:X41-B 自报 z(同档 amp=16) 1.0122 1.3133 —
—— 对照:X40 自报 z(amp=4,不同档,旁证) 1.0648 2.0915 —

⇒ 读法(必须这么读):

  1. 主结论:两臂都落在 [0.98, 1.02] ⇒ 把触发量换成真值误差也没换来任务收益 ⇒ 「价值 = 0」不是「信号不够好」,而是瓶颈在任务侧(或「当前误差」本身不是好目标)。
  2. 这不是「又换了一次统计量」:前五号的统计量互为信息子集(U ⊃ 残差 ⊃ 共形信封), 而 oracle 的信息严格多于它们全部(它直接知道真值)⇒ 它量的是这一族 「误差类触发量」的可达上界;上界都打不破年龄阈值 ⇒ 继续换统计量的路到此为止。
  3. 不许说的:「误差类触发量无用」—— 只能说在本场景 / 本任务指标下,连 oracle 都不可分辨。
  4. O_c 自洽铁门:两臂都不 >1.02(0.9921 / 1.0023)⇒ 与「信息更多不该更差」相容 ⇒ 实现检查通过。

★★ 概念边界(决定本号能说什么)

oracle 用 ground truth ⇒ 不可部署。它上界的是「误差类触发量」这一族 —— 任何「从当前估计误差出发」的调度器,信息量都不超过「直接知道当前误差」。 ⚠️ 它不上界「用别的可观测量做预测性触发」(例如知道真值阵风场 ⇒ 提前知道哪一段误差会长得快) —— 那一类需要另一个 oracle,本号没有测。⇒ 引用时不得把结论外推到「一切预测性调度」。

★★ 跑前先纠正了一处前提(0 算力,本轮最值钱的一步)

看板原文是「用环境真值的逐年龄误差分布当完美触发量」。字面实现是同义反复: Ê^or(h) 只依赖 h ⇒ Ê^or(h) ≥ tol ⟺ h ≥ h* ⇒ 恒等于年龄阈值(比值 ≡ 1.000), 拿到的会是「年龄阈值 = 年龄阈值」——看着像个结论,其实是定义。 ⇒ 改用已实现误差(realized error,即"这一次的估计到底错了多少")的逐年龄 z 分数,即上面的非退化版本。 ★ 与 §㉓ 的「跑前核 C30 原文」是同一类动作:先确认这个实验在语义上不是空的,再花算力。

三道自检(全部通过 ⇒ 自检 62 → 66/66)

  • S_o1 接线(R12,自检 ㊺):显式开启 _oracle 才算(未开启不写 oracle_* 键 ⇒ 默认路径零影响); T=1 时真值误差恒为 0;单步全丢包时 oracle_err 逐位 = est_nmse(量纲恒等式); _otrace 必须是 (age, 6 维量, 位置维量) 三元组(列 2 / 列 3 与 u_state 逐位一致)。
  • S_o2 退化:τ=+∞ ⇒ 逐位 ≡ 纯年龄阈值(相对差 0.00%);K=1 / τ=−∞ ⇒ ≡ T=1。
  • S_o4 生效性(不许靠 K 蹭结论):两臂「oracle 真的比安全网 K 更早触发」的工作点比例都是 1.00(24/24) ⇒ 不是「K 主导、oracle 白挂」。
  • 另两条概念守(自检 ㊻㊼):归一化不可省(Ŝ(h),否则退化成"只在老年龄才发"); O2 非有限必 raise(R14)。

★★ 本轮踩掉的坑:同一条量纲错误犯了两次(自检 ㊽ 已锁)

  • ① _otrace 第一版只有一列(6 维量)⇒ pos 臂拿 6 维量去比位置维基准 m_pos(h) (m_pos(h=1)/m_res(h=1) = 0.088 ⇒ 比值被顶到 ≈10×)。
  • ② 补上第三列之后,列号变量 col 算了却忘了接进取数行(取数仍硬编码 trace[:, 1]) ⇒ 症状与 ① 逐位相同("我改过了,怎么一点没变")。
  • ★ 这次的判据:修完之后症状逐位不变 ⇒ 先怀疑"改动根本没接线",而不是怀疑数据。
  • ⇒ 构件抽成纯函数 wmlab/eval/oracle.py::align_age_medians;自检 ㊽ 用一条 「第 1 列比第 2 列大 10×」的假 trace 锁死:col=2 必须返回 ≈1.0、取错列必须返回 ≈10。
  • 结论不受影响:P4 不读 trace ⇒ 两臂比值在修复前后逐位不变(这本身就是判据)。 受影响的是诊断旗标 —— 它此前把「可迁移」误报成「不可迁移」。

产物

wmlab/eval/oracle.py(fit_age_cond / z_oracle / z_pool / align_age_medians); scripts/27_x43_oracle_report.py(分块合并 + 覆盖守卫 + 逐 PER 配对符号检验 + 图); scripts/24_triggered_scheduling.py 的 --pol oracle、--oracle-target {res,pos}; 自检 ㊺㊻㊼㊽ ⇒ 66/66;图 assets/30_x43_oracle.png(assets 共 32 张)。 ★ 分块跑:同 §㉓(本机后台任务 10 min 硬上限)⇒ 按 PER 分 3 块 × 2 臂 (等预算配对逐档独立 ⇒ 分块数值等价),合并时覆盖守卫强制每档在场(缺档 raise)。

⚠️ 引用必带

  • PER=0.9 不可评估(periodic 族可比点塌缩到 1)⇒ 强衰落区做不了等预算比较, 场景限制不是方法限制(承 X40/X41/X42);n=5 档、零发散。
  • 任务距离本身没有点真正收敛(中位 6–12 m 量级)⇒ 结论强度弱于稳态工况。
  • 归属(不许抢功):「采样率约束下最优采样是阈值策略」已由 Sun–Polyanskiy–Uysal-Biyikoglu (arXiv:1701.06734 / 1707.02531)解决;「预测信息量 ≠ 下游损失」已由 C29(arXiv:2609.15801) 一般化提出。⇒ 本号不宣称方法新颖,贡献是:闭环通信调度上「误差类触发量可达上界」的实测
    • 「连上界都打不破年龄阈值 ⇒ 瓶颈在任务侧」这个定位。
  • ★ 幸存者偏差:凡 t0_min = WARMUP(400) 的探针都在「熬过 400 步」的 episode 子集上算 (X38-b / X39 / X41 / 本号同样适用)。
  • 「价值 = 0」只在本 env(正弦阵风场 + PD + 5.6 万参数高斯世界模型)上成立。
  • ★ 本号没有测「用别的可观测量做预测性触发」那一类 ⇒ 不得外推到「一切预测性调度都没用」。

㉕ X44「发送时机扰动」:固定预算、只动发送时刻 —— 把「瓶颈在任务侧」从定性变成定量(2026-10-04)

入口:用户「帮我继续实验吧,云端 gpu 还没整好」⇒ X37(Sionna)/ X10(云端训练)出局, 只剩纯 CPU 路 ① 本号(X43 §14.7 第 1 条,那条链的终点判据)② 调度基线库(工程)。 选 ①:唯一产生新曲线的一条,且把 X43 的「瓶颈在任务侧」从间接推断变直接测量。 产物:scripts/28_x44_timing.py、新库模块 wmlab/eval/timing.py、assets/31_x44_timing.png。 自检 66 → 68/68(新增 ㊾ ㊿)。正式跑 366 s(含重训 150 epoch / 244 s),CPU 0 元。

★★ 一句话答案:任务指标不是"免疫",而是强衰减耦合

固定传输预算、只扰动发送时刻(周期 → 抖动 → 完全随机):

T 最大 Δest_nmse 对应 Δmean_dist_tail Δ任务/Δ估计 CV 比 ρ(NMSE,dist)
8 +518.5% +44.1% 0.085 0.129 +0.949
16 +182.1% +80.7% 0.443 0.429 +0.961

⇒ 估计误差最多能涨 5.2 倍,任务距离只涨 1.44 倍(衰减 ~12 倍); 两者同向且高相关(ρ≈0.95)—— 所以不是"任务对时机免疫"(我预写的 T2 因此 FAIL), 而是「任务指标把估计质量的变化强衰减了 2.3–12 倍」。

★★ 预算轴(对照,无时机扰动):est_nmse ×1119,任务距离只 ×2.97,而且非单调

T 1 2 4 8 16 32
est_nmse 0 0.000305 0.002309 0.012134 0.066304 0.341809
mean_dist_tail (m) 0.6669 2.1623 3.6341 4.5012 4.2745 6.4328

★ T=16 的距离(4.2745 m)低于 T=8(4.5012 m) ⇒ 更差的估计、更好的任务 ⇒ X35「NMSE 不能当任务代理」的又一次独立复现,且尺度是三个数量级。

设计:把混淆变量封死

  • 载体 = 周期调度(无状态)⇒ 预算可逐位固定 ⇒ 唯一自变量就是「时刻」。
  • ★★ PER=0 是刻意的:有丢包时不同时刻序列会在不同的步消耗随机数 ⇒ 丢包实现与"时机"产生虚假相关。「加丢包更真实」的直觉在这里是错的。
  • 三个旋钮(都保持恰好 N 次发送):相位 Δ / 抖动 j(有界 j ≤ (T−1)//2 ⇒ 不乱序)/ 完全随机。
  • ★ 新增纯净自变量 CV(相邻间隔):周期任意相位 ⇒ 0;抖动 ⇒ 升;随机 ⇒ 最大。 (E[age] 同时被"预算"和"时机"影响,CV(间隔) 只吃时机。)

⚠️ 判据结算:T1 ❌ / T2 ❌ / T2′ ❌ ⇒ 落在未预注册的「同向亚线性」

相位档的任务偏差 6.40% / 6.26%(> 预写的 5% ⇒ T1 FAIL)。 ⇒ ★★ 第 28 次自证伪:判据分区缺了最常见的那一档。 预写分区只有「免疫(≤5%)/近线性(>0.5×)/异号」,没有"同向亚线性" ⇒ 老分区把 +44% 标成"弱/不可判"——那是标注假象,不是结论(+44% 远不是"弱")。 共因:用「符号 + 拍阈值」分区,而不是用「斜率 / CV 比」。⇒ 已补全分区并离线重算(不改仿真)。

⚠️ 引用必带

  1. T1 的"相位"在有限窗口里与"尾部静默长度"耦合(未分离): 时刻表落在 [1, N·T] 而 episode 跑到 300 步 ⇒ 尾静默 = 300 − (281+Δ) ⇒ Δ=0 尾静默 19 步、Δ=7 只有 12 步。⇒ 那 ±6.4% 只能报为「相位 + 边界」的合并效应。
  2. 随机旋钮只有 3 个实现(n=3)⇒「最坏档 +518%」不稳定; 主结论请用 CV 比(0.129/0.429)与斜率(0.085/0.443)(12 档聚合量)。
  3. n_ep=30(X38–X43 用 40);未做逐 episode 配对检验。
  4. PER=0 ⇒ 结论只对无丢包成立。
  5. 任务距离仍在 4–6 m 量级、没有点真正收敛(承 X35)。
  6. 归属(不许抢功):阈值最优已由 Sun–Polyanskiy–Uysal-Biyikoglu 解决; 「预测信息量 ≠ 下游损失」已由 C29(arXiv:2609.15801)一般化提出 ⇒ 本号不宣称新命题,贡献 = 「时机的定量衰减因子」实测 + "任务侧受限"的定量化。

★ 本轮踩掉的坑(都有回归测试)

  • ★★ 调度首次被查询在 t=1,t=0 永不出现(t += 1 在 schedule(t,rng) 之前): 时刻表从 0 起 ⇒ 相位各档差 1 次发送;反算区间写成 t < L ⇒ 基准档反算 101 vs 实测 93 ⇒ 差 1 的预算偏差会被读成时机效应(自检 ㊿ 用反向断言锁死)。
  • 抖动会把首个时刻推到 t = −1 ⇒ 起点抬到 1 + j;j > (T−1)//2 直接 raise(自检 ㊾)。
  • ★★ 「固定预算」在闭环里 ≠ "每集次数相同":episode 会因跟丢提前终止 ⇒ 正确检查是 n_tx 逐位 = Σ_e #{1 ≤ t_k ≤ L_e}(同时验接线 + 次数变化完全由集长解释), 并对实测送达率偏差 > 5% 的档判不可评估、打印原因(铁律 17)。

当前状态

  • 环境接口 + CartPole 适配器
  • 最小世界模型(MLP 版)
  • 多步 rollout 误差曲线 + 可靠视界指标
  • 长视界 H* 测量(Pendulum,视界到 190)+ 误差形态判定脚本(scripts/03_)
  • ★ H* 误差口径修正为逐点(2026-09-20):两个口径同时返回,累积口径发警告
  • ★ 通信接入层(envs/channel.py + eval/tracking.py + eval/aoi.py,X24/X25/X26)
  • ★ 68 项自检测试(不依赖 pytest;每个用例对应一次真实踩过的坑)
  • ★ 时延真的生效(X27):delay 从空参数改为在飞包 FIFO; 「生成年龄 ≠ 传输年龄」首次被实测分开,误差地板 2(1−ρ_o(D)) 由两条独立路径验证
  • ★ 多种子(5)× 阈值敏感性(5)(X3 / X4): H*(开环) = 26.93 ± 11.41(CV 0.42,范围 13.13–42.99); H*(θ) ≈ 62.19·θ^(+0.277)(R² 0.98,符号已更正);★ 单步 val_loss 不能预报 H* (两个 val_loss 差 3.2% 的模型,H* 差 3.3 倍);开环>闭环的序在 5 个阈值下一致
  • ★ NaN/Inf 不再被静默当成"已超阈"(X3 期间发现):reliable_horizon 遇到非有限值即 raise (NaN <= 阈值 恒为 False,旧行为会返回虚假偏小的 H*)
  • ★ X22「与理论界对账」已探明为死路(2026-09-21,见 §⑦):C17 的 δ 是两转移模型的 TV 距离,而本仓库「环境确定 + 模型确定 ⇒ 两个点质量」使 δ ≡ 1 ⇒ H(ε,1) = 1+ε, 对任何有意义的 γ 都不满足其定理条件。故不报任何 gap 数值(强行代入会造出 26 倍的假缺口)。 两条补救路径(注入过程噪声 / 换 Wasserstein 距离自己重推)已记录,留待 X14 与阶段 3–4。 顺带更正了 §⑥ 里 θ^(−0.277) 的指数符号(应为 +0.277)。
  • ★ X28/X29「δ 连续化 + 对账闭合」(2026-09-22,见 §⑧):过程噪声 + 高斯模型使 δ 可测 (条件:latent_dim=4);对账 gap ≈ 8.5–23.8×(定性);C17 的 max 定义被实证为实践过强
  • ★ X11 第三种曲线(2026-09-22):端点恒等式证明;纠错频率 K 对 H* 的影响 = 模型质量的函数
  • ★ X14 UAV 场景首跑(2026-09-22):架构声明实测通过;首个带过程噪声场景的 H*
  • ★ X12-min σ 头校准(2026-09-22):潜空间单步转移 τ=1.058;覆盖率 95%→94.5%(温度缩放后)
  • ★ X30 任务锚定的 H*(2026-09-22,见 §⑨):闭环控制下 H*_task 随任务指标在 1–32 步间漂移(32 倍),而 H*_err 只有一个数(26.1);误差阈值恰好落在"灾难性失败" 一侧(H_escape/H_err = 1.22);闭环控制把估计误差放大 ~1.7×(同口径对账)
  • ★ X31 突发信道(2026-09-22,见 §⑪):Gilbert–Elliott 两状态信道; 平均丢包率相同(50%)时跟踪误差跨 570 倍;闭式恒等式 E[NMSE]=p̄[f(L)+J] 相对偏差中位 −1.5% ⇒ X26 的解析式推广到任意突发信道;★ 无记忆点是 L=1/(1−p̄) 不是 L=1
  • ★ X31-b 多丢包率扫描(2026-09-23,见 §⑫):p̄×L 网格,模型一次训练全网格共享; 5 个 L 中 3 个的跨 p̄ 离散度低于噪声本身 ⇒ 丢包率 × 突发结构基本解耦; G(L) 跨 143 倍而 p̄ 只贡献线性因子
  • ★ X32 物理层(2026-09-23,见 §⑬):M-QAM + 量化的速率—可靠权衡; b* 随 SNR 单调增 2→4→6→8;模型增益从低 PER 的 ×1.03 升到高 PER 的 ×3.10 ⇒ 模型补的是丢包不是量化精度
  • ★ X33 跨层闭式预报(2026-09-24,见 §⑭):E[NMSE]=Σ_h P_age(h)·g_b(h) 只用 离线曲线 + 信道参数 ⇒ |偏差| 中位 5.0%(换实测年龄直方图 3.4%,对照 X31 旧结论 10.0%); ★ 误差不可加:量化贡献随年龄衰减到 −182×(不是被放大)⇒ 「量化误差被 rollout 传播」的 直觉模型被推翻,A_model 中位 0.985、Spearman(A, E[age]) = −0.04(两个预写假设 H1/H2 全错,已照报)
  • ★ X34 联合设计 T × b(2026-09-25,见 §⑮):周期发送的新年龄闭式 E[age] = T·q/s + (T−1)/2;周期本身是信息代价(零丢包时年龄也在 0…T−1 循环); 闭式预报中位 3.1%、闭式选出的 T* 与仿真 54/54 一致、T*_model ≥ T*_persist 100%; ★ 反直觉:PER=0 时 T=1 并不最优(b=4 五档全选 T=2)—— 多推一步会洗掉量化噪声(X33 A2 的后果)
  • ★ X35 任务锚定的联合设计(2026-09-25,见 §⑯):真闭环下同一张 (T,b) 网格同时记 闭式 NMSE / 闭环 NMSE / 任务指标 ⇒ ★ 闭式 argmin T 与任务 argmin T 只一致 12/20(60%); Spearman(NMSE, 距离) = 0.778 < 0.8 ⇒ NMSE 不能当任务代理; ★★ 模型把 NMSE 降到 1/2.3 却没换来跟踪距离(尾段距离比中位 1.000,b=4 时反而 1.446); 闭式搬到闭环后偏差中位 3.1% → 8.1%
  • ★ X36 突发信道下的联合设计(2026-09-25,见 §⑰):把 X31 的突发结构接进 X34 的设计闭式 (新闭式:周期发送 + GE 的年龄分布,2×2 矩阵精确解)⇒ ★★ 不带突发结构做预报会系统性 低估误差(突发档中位 −86.6%,49/49 同向);★ E1 未达标(T* 只 1/12 组移动)—— 机制是设计空间饱和(b=4 的 6/6 组 T* 已顶在 T=1),不是"突发不影响设计"
  • ★ X38 触发式调度(2026-09-27,见 §⑱):等传输预算下 周期 / 年龄阈值 / 模型不确定度触发三方对比。 ✅ 阈值 ≤ 周期(PER=0 恒等,比值最低 0.547)且 U 形成立(解析细网格拐点 @PER 0.88–0.96); ✅ P2:NMSE 上阈值降到 1/2.95,但任务距离中位 0.955–1.000 ⇒ ★★ 「NMSE 不是任务代理」 在 X35 之外的第二个独立场景再次成立; ★★ P3 核心负面:给定 age=h 后 ρ_cond = −0.029、AUC_cond = 0.419,机制是 ρ(U, h) = +0.966、条件 CV 由 0.337 掉到 0.062(残差≈单步 σ 的 CV 0.071) ⇒ 模型自报的累积不确定度 U 只是 age 的替身。⚠️ 边界:本场景 σ 头近乎同方差, 必须先做 X38-b(注入状态依赖噪声)才可谈推广; P4:U 触发 ≈ 年龄阈值(中位 0.945–1.053)⇒ 与 P3 互相印证;S_f 96/96 通过
  • ★ X38-b 阵风场剂量—反应(2026-09-27,见 §⑲):把 X38 的负面结论关进笼子。 amp=0 逐位退化为原环境(自检 ㊳ 钉死)⇒ ★ σ 头一旦有东西可学就能学到 (ρ(σ_pred,σ_true)=0.67–0.88,而 amp=0 档预测 σ 的 CV 只有 0.071) ⇒ X38 的 7.1% 是「环境同方差」不是「头不行」;★ U 的独立信息是涌现的: ρ_cond −0.029 → −0.148 → −0.018 → +0.347(amp=0/1/2/4),只有 amp=4 跨过门槛且 AUC 0.601 压线 ⇒ 不是是/否问题,取决于异方差强度
  • ★ X39 阵风场下的闭环触发式调度(2026-09-29,见 §⑳):P2'/P4' 双双不成立 (U触发/年龄阈值 距离中位 1.018–1.041、NMSE 1.17–1.34)★ 机制 = 闭环 ρ(U,age)=0.9941 ⇒ 全局阈值 U≥thr 数学上 ≡ 年龄阈值 ⇒ 本号只能证「全局阈值不行」⇒ 催生 X40
  • ★ X40 条件化触发(决定性版本)(2026-09-29,见 §㉑):H1 ❌ / H0 ✅
  • ★★ X41 U 边际任务价值的剂量—反应(2026-09-29,见 §㉒):离线信息 +12%(AUC 0.601→0.674), 任务边际价值仍为 0;★ AUC 非单调(0.601→0.600→0.674→0.520),amp=32 崩塌的根因是 σ 头学不动(ρ_calib 0.851→0.448)、不是环境没信息;★★ 结论按 C29/C30/C31 收窄为 「未经校准的自报不确定度 U」——不是「U 无用」
  • ★ X42 共形校准的误差信封触发(2026-09-29,见 §㉓):H0 成立 —— 校准把「更差」变「持平」,没变出正价值; 距离比中位 0.9969(pos)/ 0.9962(nmse)(n=5 档、零发散 0/306); ★ 真增量 = NMSE 比从自报量的 1.31 → 0.99 ⇒ 校准修掉了坏方向性,但没造出好方向性
  • ★★ X43 oracle(特权)触发量(2026-09-29,见 §㉔):O0 成立 —— 连「完美知道当前估计误差」 都赢不了年龄阈值(两臂距离比中位 0.9921 / 1.0023,n=5 档、零发散)⇒ ★★ 「价值为 0」不是「信号不够好」,瓶颈在任务侧;★ 上界对象 = 「误差类触发量」这一族 (oracle 的信息严格多于 U / 残差 / 共形信封)⇒ 继续换统计量的路到此为止
  • ★★ X44 发送时机扰动(2026-10-04,见 §㉕):固定预算、只动发送时刻 ⇒ 把「瓶颈在任务侧」 从间接推断变直接测量。★ 估计误差最多 +518% 而任务距离只 +44%(衰减 ~12 倍); ★★ 预算轴上更极端:est_nmse ×1119 只换来距离 ×2.97,且 T=16 的距离低于 T=8(非单调); ⚠️ T1/T2/T2′ 全 ❌ ⇒ 落在未预注册的「同向亚线性」⇒ 第 28 次自证伪:判据分区缺一档; ★ 新库模块 wmlab/eval/timing.py、自检 ㊾ ㊿ ⇒ 68/68;★ 坑:调度首查在 t=1(t=0 永不出现)
  • X14 续:连续动作策略接入(多种子 H* 与 σ 敏感性已于 47d6dd1 完成; 本仓库 PPO 仅支持离散动作 ⇒ X30 先用解析 PD 控制器顶上;SAC/连续 PPO 待做)
  • 因子化潜空间(确定性 H_t + 随机 Z_t)与不确定性校准(X12;σ 头已就位)
  • 扩散策略动作头(对齐 diffusion policy)

结果图索引(assets/ 共 33 张,全部进了版本库)

判据:不进版本库的图不算对外可验证的产出(outputs/ 已 gitignore)。 下表是「图 ↔ 实验编号 ↔ README 小节」的对照,防止图躺在库里却没人能对上出处。

图 实验 小节
01_random_baseline.png 随机策略 baseline §①
02_world_model.png X1 / X2(CartPole,短视界) §②
02_world_model_pendulum.png X2(Pendulum,视界到 190) §③
04_channel.png X24 / X25 / X26 §④
05_x26_gap_diagnosis.png X26 对账 §④
06_delay_floor.png X27 时延地板 §⑤
07_seeds_threshold.png X3 / X4 种子与阈值 §⑥
08_x22_theory_check.png X22 理论界 §⑦
11_latent_roundtrip.png X11 纠错频率 K §⑧
12_delta_continuity.png X28 σ 扫描 §⑧
12_delta_ldim4_full.png X28(latent_dim=4 = 可分辨区) §⑧
13_x29_reconcile.png X29 C17 对账 §⑧
14_uav_track.png X14 首跑 §⑧
14_uav_sigma_scan.png X14 σ 敏感性 §⑧
15_sigma_calibration.png X12-min σ 头校准 §⑧
16_task_horizon.png X30 任务锚定 H* §⑨
09_ppo_cartpole.png X5 手写 PPO §⑩
10_behavior_ablation.png X6 / X7 行为策略消融 §⑩
17_burst_channel.png X31 突发信道 §⑪
18_burst_sweep.png X31-b 多丢包率扫描(数据塌缩) §⑫
19_physical_layer.png X32 物理层(M-QAM + 量化) §⑬
20_additivity.png X33 跨层闭式预报 + 可分解性 §⑭
21_period_design.png X34 联合设计(周期 T × 精度 b) §⑮
22_task_design.png X35 任务锚定的联合设计(真闭环) §⑯
23_burst_design.png X36 突发信道下的联合设计 §⑰
24_triggered_scheduling.png X38 触发式调度(周期 / 年龄阈值 / U 触发) §⑱
25_x39_triggered_wind4.png X39 阵风场(amp=4)闭环触发式调度 §⑳
26_x40_conditional_wind4.png X40 条件化触发(hybrid = U 的边际价值) §㉑
27_x41_dose_response.png X41 U 边际价值的剂量—反应(7 档离线 + 2 档闭环) §㉒
28_x42_conformal.png X42 共形校准触发 vs 年龄阈值(两臂 + 自报基线) §㉓
29_x42_conformal_envelope.png X42 共形信封诊断(覆盖率 / 信封曲线 / 触发边界) §㉓
30_x43_oracle.png X43 oracle(真值误差)触发 vs 年龄阈值(res / pos 两臂 + 基线) §㉔
31_x44_timing.png X44 发送时机扰动(固定预算;估计增益 vs 任务增益) §㉕

参考

  • 课题地图与选题:见父项目 D:\workbuddy\researchproject
  • 方法来源:Dreamer 系(潜空间想象训练)、JEPA 系(联合嵌入预测)
  • ★ 误差口径说明:wmlab/rollout/imagine.py 的模块 docstring(逐点 vs 累积、 以及"为什么『首次超阈』必须用逐点")。所有 H* 数字都被这张表约束。
  • 通信接入的口径声明(R1/R2/R3 + 第四条):scripts/04_channel_tracking.py 的模块 docstring
  • ★ 时延语义与误差地板解析式:wmlab/eval/tracking.py 的模块 docstring ("时延 delay 的语义"一节 + 2(1 − ρ_o(D)) 的推导与诚实边界)
  • 误差增长形态的判定:scripts/03_analyze_horizon_curve.py (在逐点序列上算 inc = ΔNMSE/Δhorizon;峰值在末段 = 未饱和,峰值后回撤 ≥ 15% = 饱和)
  • ★ 种子方差 / 阈值敏感性的全部口径:scripts/07_seeds_threshold.py 的模块 docstring —— 含 Part A 采样收敛性检验(不先确认它,种子方差里就混着采样噪声)、 删失计数(H* 顶到量表边界时 σ=0 会被误读成"极其稳定")、 稀疏 vs 稠密网格误差、以及 H*(θ) ≈ C·θ^(+α) 的幂律拟合 (★ 指数为正:阈值越松,可靠视界越长。2026-09-21 更正过符号)

About

Minimal reproducible framework for world-model rollout: measures how many steps a learned world model stays trustworthy (reliable horizon) before its own predictions degrade it.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages