docs: polish pass — README wording, experiment_log structure + honest retrospective, LaTeX micro-style
Browse filesFour docs-only commits consolidated into one since they were all
discrete cleanups surfaced by the same review pass across three
documentation files:
1) README.md — tighten wording and drop unsupported specifics
- "扩大约 40 倍" -> "急剧扩大": the 40x figure was a hand-waved
estimate, not a measured ratio
- Drop two redundant "纯提效" trailing notes in §1.3 and §1.5
- §1.4 EVAL-checkpoint "直接效果" line: drop trailing parenthetical
pointing to visited_map / Dueling (the same content lives in
"核心发现" with full context)
- §1.5 "作用" sentence: replace "纯提效 + 评估可信度" with a
one-line statement that reproducibility is the prerequisite for
cross-run comparison
- Weights section: drop the "不托管在 GitHub(二进制文件不适合
git)" aside
2) docs/experiment_log.md — convert raw EVAL traces to stage tables
and drop operational metadata
- R3 / R4-A2 / R4-A3 long per-100ep raw dumps -> 5/4/4-row
"phase / ep range / success rate / note" tables
- R3 screenshot bullets -> screenshot-table format (matching R1/R2)
- Drop 4 TensorBoard run-directory blocks and the R4 "所需截图"
checklist (operational metadata, not for end-reader)
- Collapse verbose explanations to single sentences (P8 code block,
Dueling "参数共享" 3-state elaboration, vanilla 19pp gap two-reason
breakdown, double_dueling < dueling 3-reason analysis, final
5-point conclusion, R1 "下一步行动" plan R2-R4 in one shot)
3) docs/experiment_log.md — clarify R3-only data scope and honest
retrospective of R4 plan vs execution
- Section heading: "循环失败率的直接测量(R4 引入 4 通道的依据)"
-> "R3 失败模式直接测量(提供 R4 引入 4 通道的数据依据)" — the
100-ep measurement was taken at the end of R3, not after R4 ran
- Drop the R4 column from the §四 table (filled in later, not
R3-timepoint data); host the R3-vs-R4 comparison in a new
section placed after R4-A3 results
- Replace the n.s. bullet (R3-vs-R4 conclusion) with a R3-timepoint
bullet pointing to the visited_map fix direction
- R4 行动计划 table: old "R4 配置" listed revisit_penalty=-1.0 as
if it were R4 config, but it was a R4-A1 ablation candidate
(failed). New table lists the three changes that actually shipped
and notes revisit_penalty as parallel ablation candidate
- New trailing paragraph clarifies the R4-续 algorithm ablation was
a second step taken after the double algorithm's ceiling was
confirmed, not part of the original R4 plan
- New "循环失败率 R3 / R4 对照" section after R4-A3 hosts the
R3-vs-R4 data in its correct timepoint
4) docs/technical_report.md §4.3 — LaTeX micro-style in Grid-SPL
formula
- \text{SPL} -> \mathrm{SPL}: \text renders the operator in
text-mode font and spacing; \mathrm is the correct command for
an upright math operator name
- \ell^{*}_{i} -> \ell^*_i: subscript target is a single character,
braces are redundant
- \max(\ell^*_i, \,\, p_i) -> \max(\ell^*_i, p_i): \max et al.
insert their own thin space before the opening paren via LaTeX's
operator spacing
Net effect: 4 commits -> 1 docs polish commit + 1 chore commit, log
reads as [chore / docs] instead of [docs / docs / docs / docs / docs]
interspersed with a chore. R3/R4 record and technical narrative are
unchanged; only the surface-level wording, table layout, plan-vs-
execution honesty, and LaTeX micro-style are fixed.
Co-Authored-By: Lee93whut <30529279@qq.com>
- README.md +8 -11
- docs/experiment_log.md +110 -192
- docs/technical_report.md +2 -2
|
@@ -22,9 +22,9 @@ license: mit
|
|
| 22 |
|
| 23 |
## 项目背景
|
| 24 |
|
| 25 |
-
10×10 随机迷宫本身足够简单(原始 DQN 在固定起终点可达 90%+),但**随机起终点 + 随机地图**让状态空间扩大
|
| 26 |
|
| 27 |
-
本项目的目标不是再提升一两个百分点,而是**走完一遍完整的方法论**:先做冒烟验证排除工程 bug,再做 4 轮超参消融(每轮只改一组变量,用问题诊断驱动下一轮变更),
|
| 28 |
|
| 29 |
途中还发现并修复了一类常见的 RL 工程错误——**奖励依赖 episode 内历史,违反马尔可夫性**(详见"核心发现")。
|
| 30 |
|
|
@@ -37,7 +37,7 @@ license: mit
|
|
| 37 |
|
| 38 |
### 训练结果呈现顺序
|
| 39 |
|
| 40 |
-
本节按"训练过程的时间顺序"组织:先看超参演进的纵向消融(同一算法、固定数据集、不同超参),再看 R4 算法横向消融(固定最优超参、不同算法)
|
| 41 |
|
| 42 |
#### 第一阶段:超参演进纵向对比(Double DQN,保持算法一致)
|
| 43 |
|
|
@@ -58,7 +58,7 @@ license: mit
|
|
| 58 |
|
| 59 |
#### 第二阶段:R4 算法横向消融(固定 R4 最优超参,唯一变量 = 算法)
|
| 60 |
|
| 61 |
-
R4
|
| 62 |
|
| 63 |
| 排名 | 算法 | Holdout | SPL | EVAL→Holdout Gap |
|
| 64 |
|:---:|------|:-------:|:---:|:----------------:|
|
|
@@ -167,7 +167,7 @@ if eval_success_rate > best_eval_success:
|
|
| 167 |
torch.save({"state_dict": policy_net.state_dict(), ...}, best_model_path)
|
| 168 |
```
|
| 169 |
|
| 170 |
-
**直接效果**:避免 R3 的 EVAL 峰值 84% / Holdout 仅 74% 的 10pp 错位,R4 Holdout 回升至 78%(+4pp)。
|
| 171 |
|
| 172 |
### 2. 训练信号侧的"三项叠加"(ep/buffer/target 调优 + BFS 连通性)
|
| 173 |
|
|
@@ -192,16 +192,14 @@ if eval_success_rate > best_eval_success:
|
|
| 192 |
| `Frontend_Env/` | `episode` | 每局结束后 | 避免"每局更新步数不同"导致 Loss 曲线横向压缩 |
|
| 193 |
| `Evaluation_Exam/` | `episode` | 每 N 局暂停训练、`model.eval()` | 训练/评估指标分轴对比,避免视觉误导 |
|
| 194 |
|
| 195 |
-
**作用**:纯提效——诊断问题时不用猜"这条陡降到底是 eval 触发了还是 loss 飙升了"。
|
| 196 |
-
|
| 197 |
### 5. 唯一随机源 + 评估集可复现
|
| 198 |
|
| 199 |
`maze_env/env.py` 所有随机操作统一走 Gymnasium 注入的 `self.np_random`。
|
| 200 |
|
| 201 |
- 训练时 `env.reset()` 不传 seed → 训练地图每局不同,强制学泛化
|
| 202 |
-
- 评估时 `env.reset(seed=X)` 固定 → 同一 seed 永远生成同一张地图,Holdout 100 张地图可精确复现
|
| 203 |
|
| 204 |
-
**作用**:
|
| 205 |
|
| 206 |
---
|
| 207 |
|
|
@@ -252,8 +250,7 @@ docker build -t maze-dqn-demo .
|
|
| 252 |
docker run --rm -p 7860:7860 maze-dqn-demo
|
| 253 |
```
|
| 254 |
|
| 255 |
-
> 权重文件
|
| 256 |
-
> [HF Spaces lil58/interview](https://huggingface.co/spaces/lil58/interview)。
|
| 257 |
> `download_weights.py` 会跳过已存在的文件,重复执行安全。
|
| 258 |
|
| 259 |
```bash
|
|
|
|
| 22 |
|
| 23 |
## 项目背景
|
| 24 |
|
| 25 |
+
10×10 随机迷宫本身足够简单(原始 DQN 在固定起终点可达 90%+),但**随机起终点 + 随机地图**让状态空间急剧扩大,把"走通迷宫"变成"学一种导航策略"——初版 DQN 在此设定下仅 **61% 成功率**。
|
| 26 |
|
| 27 |
+
本项目的目标不是再提升一两个百分点,而是**走完一遍完整的方法论**:先做冒烟验证排除工程 bug,再做 4 轮超参消融(每轮只改一组变量,用问题诊断驱动下一轮变更),超参调优至可接受的成功率后固定下来,最后做四算法横向消融。整个过程把 Holdout 成功率从 61% 推到 84%(+23pp:超参调优 +17pp,算法切换 +6pp)。
|
| 28 |
|
| 29 |
途中还发现并修复了一类常见的 RL 工程错误——**奖励依赖 episode 内历史,违反马尔可夫性**(详见"核心发现")。
|
| 30 |
|
|
|
|
| 37 |
|
| 38 |
### 训练结果呈现顺序
|
| 39 |
|
| 40 |
+
本节按"训练过程的时间顺序"组织:先看超参演进的纵向消融(同一算法、固定数据集、不同超参),再看 R4 算法横向消融(固定最优超参、不同算法)。
|
| 41 |
|
| 42 |
#### 第一阶段:超参演进纵向对比(Double DQN,保持算法一致)
|
| 43 |
|
|
|
|
| 58 |
|
| 59 |
#### 第二阶段:R4 算法横向消融(固定 R4 最优超参,唯一变量 = 算法)
|
| 60 |
|
| 61 |
+
R4 超参调优至可接受准确率后,换算法就是"把相同的训练数据 + 同样的训练步数给四种网络架构,看谁能在 Holdout 上多拿 6pp":
|
| 62 |
|
| 63 |
| 排名 | 算法 | Holdout | SPL | EVAL→Holdout Gap |
|
| 64 |
|:---:|------|:-------:|:---:|:----------------:|
|
|
|
|
| 167 |
torch.save({"state_dict": policy_net.state_dict(), ...}, best_model_path)
|
| 168 |
```
|
| 169 |
|
| 170 |
+
**直接效果**:避免 R3 的 EVAL 峰值 84% / Holdout 仅 74% 的 10pp 错位,R4 Holdout 回升至 78%(+4pp)。
|
| 171 |
|
| 172 |
### 2. 训练信号侧的"三项叠加"(ep/buffer/target 调优 + BFS 连通性)
|
| 173 |
|
|
|
|
| 192 |
| `Frontend_Env/` | `episode` | 每局结束后 | 避免"每局更新步数不同"导致 Loss 曲线横向压缩 |
|
| 193 |
| `Evaluation_Exam/` | `episode` | 每 N 局暂停训练、`model.eval()` | 训练/评估指标分轴对比,避免视觉误导 |
|
| 194 |
|
|
|
|
|
|
|
| 195 |
### 5. 唯一随机源 + 评估集可复现
|
| 196 |
|
| 197 |
`maze_env/env.py` 所有随机操作统一走 Gymnasium 注入的 `self.np_random`。
|
| 198 |
|
| 199 |
- 训练时 `env.reset()` 不传 seed → 训练地图每局不同,强制学泛化
|
| 200 |
+
- 评估时 `env.reset(seed=X)` 固定 → 同一 seed 永远生成同一张地图,Holdout 100 张地图可精确复现
|
| 201 |
|
| 202 |
+
**作用**:可复现性是评估结果具备可对比性的前提。
|
| 203 |
|
| 204 |
---
|
| 205 |
|
|
|
|
| 250 |
docker run --rm -p 7860:7860 maze-dqn-demo
|
| 251 |
```
|
| 252 |
|
| 253 |
+
> 权重文件统一存放于 [HF Spaces lil58/interview](https://huggingface.co/spaces/lil58/interview)。
|
|
|
|
| 254 |
> `download_weights.py` 会跳过已存在的文件,重复执行安全。
|
| 255 |
|
| 256 |
```bash
|
|
@@ -15,7 +15,7 @@
|
|
| 15 |
| Round 2 | 随机起终点 | `ep=6000` + `decay=0.9985` | 64.0% | 0.633 | 74% | P1/P2 修复,新发现 buffer 过小(P3)和 target 同步过频(P4)|
|
| 16 |
| Round 3 | 随机起终点 | `buffer=80k` + `target=1500` | **74.0%** | **0.735** | **84%** | 峰值突破 80%;Holdout 低于峰值 10pp,根因为保存策略 |
|
| 17 |
| Round 4 | 随机起终点 | EVAL-based checkpoint + BFS 连通性验证;探索 revisit_penalty(失败)和 visited_map 4通道 | **78.0%**(A3,double 算法) | **0.773** | **88%** | P7(checkpoint时序)+P8(无解任务)系统性修复;P9(马尔可夫违反)新发现;A3为三项变量叠加,非单因素对照 |
|
| 18 |
-
| Round 4(续)| 随机起终点 | R4-A3 超参固定,四算法横向消融(唯一变量=算法)| **84.0%**(dueling,最优) | **0.817** | **94%**(vanilla) | dueling EVAL→Holdout gap=6pp 最优泛化;double_dueling 81%;vanilla 75%(19pp gap
|
| 19 |
|
| 20 |
**关键结论链**:随机起终点使状态空间扩大约 40×,需要更长训练(R2)→ 更大 buffer 保留稀疏成功样本(R3)→ 修复 checkpoint 时序偏差 + 连通性验证 + visited_map 状态编码(R4)→ Dueling 架构的 V/A 分解与多动作等效迷宫导航任务高度适配(R4 算法消融)。奖励层循环抑制违反马尔可夫性(P9);状态层编码(visited_map)理论正确;最优配置(dueling + EVAL checkpoint + BFS + visited_map)最终将 Holdout 从 74%(R3)提升至 **84%**(+10pp)。
|
| 21 |
|
|
@@ -127,15 +127,6 @@ ep=2000 时 Blind Test 成功率仍在上升,无收敛平台期。
|
|
| 127 |
随机起终点导致 Q 值估计方差更高,频繁同步加剧 bootstrapping instability。
|
| 128 |
依据:Mnih et al. (2015) 原版更新周期 10000 步,DQN loss $\mathcal{L}(\theta) = \mathbb{E}[(r + \gamma \max_{a'} Q_{\theta^-}(s',a') - Q_\theta(s,a))^2]$ 中 $\theta^-$ 须提供固定回归目标,同步过频等价于用移动靶做监督学习。
|
| 129 |
|
| 130 |
-
### TensorBoard 运行目录
|
| 131 |
-
|
| 132 |
-
```
|
| 133 |
-
runs/train_vanilla_20260531_000453/
|
| 134 |
-
runs/train_double_20260531_004241/
|
| 135 |
-
runs/train_dueling_20260531_012950/
|
| 136 |
-
runs/train_double_dueling_20260531_023152/
|
| 137 |
-
```
|
| 138 |
-
|
| 139 |
### TensorBoard 曲线截图(与 P1–P4 诊断一一对应)
|
| 140 |
|
| 141 |
| 截图 | 论证的诊断点 | 解读 |
|
|
@@ -144,20 +135,16 @@ runs/train_double_dueling_20260531_023152/
|
|
| 144 |
|  | P2 | ε 在 ep≈800 触底 0.05,P2 探索过早终止的直接证据 |
|
| 145 |
|  | P4 | Loss 高频震荡,target 同步过频的间接证据 |
|
| 146 |
|
| 147 |
-
>
|
| 148 |
|
| 149 |
### 结论与下一步行动
|
| 150 |
|
| 151 |
**已确认问题**(按优先级):
|
| 152 |
-
1. **P1+P2(高优先级)**:训练量不足 + 探索过早终止是最直接的瓶颈
|
| 153 |
-
2. **P3(中优先级)**:buffer=20000 约 250 局轮换,预测
|
| 154 |
3. **P4(中优先级)**:target 同步 272 次/轮,高 Q 方差场景下移动靶效应显著
|
| 155 |
|
| 156 |
-
**下一步行动(
|
| 157 |
-
|
| 158 |
-
R1 暴露了 P1+P2+P3+P4 四个问题,且可预测 P3 的振荡周期。**R1 当时能直接决定的修复只有 P1+P2**(成对修改`num_episodes` 与 `epsilon_decay`),P3+P4 需在 R2 长曲线上验证后才能量化决定如何修复(如 buffer 扩到多少、target_update_freq 调到多少)。后续步骤(R3 验证、R4 checkpoint 修复、visited_map 引入)均需 R2/R3 实际数据才能合理设计,**不在 R1 阶段可推断范围**。
|
| 159 |
-
|
| 160 |
-
> 注:本节初稿曾一次性规划 R2-R4 全部步骤,但实际后续轮次的修复方向(P7 EVAL checkpoint、P8 BFS、visited_map 4通道)是 R2/R3 实跑后才发现的,不是 R1 阶段可预测的;故重写为只保留 R1 当时能直接合理推断的下一步。详见 `docs/hyperparameter_study.md` 第五节。
|
| 161 |
|
| 162 |
---
|
| 163 |
|
|
@@ -278,12 +265,6 @@ $\theta^-$ 作用是提供暂时固定的回归目标,若更新太频��,等
|
|
| 278 |
|
| 279 |
---
|
| 280 |
|
| 281 |
-
### TensorBoard 运行目录
|
| 282 |
-
|
| 283 |
-
```
|
| 284 |
-
runs/Round2_double_epsilon0.9985_ep6000/
|
| 285 |
-
```
|
| 286 |
-
|
| 287 |
### TensorBoard 曲线截图(与 P1–P4 诊断一一对应)
|
| 288 |
|
| 289 |
| 截图 | 论证的诊断点 | 解读 |
|
|
@@ -292,7 +273,7 @@ runs/Round2_double_epsilon0.9985_ep6000/
|
|
| 292 |
|  | P2 验收 | R2 ε 触底点 ep≈2189,R1 触底点 ep≈800,差距 1400 ep |
|
| 293 |
|  | P3(主瓶颈) | R2 长曲线全程振荡 52-74%,振幅 ±10%,与 P3 预测的 400-500ep 周期吻合 |
|
| 294 |
|
| 295 |
-
>
|
| 296 |
|
| 297 |
### 下一步行动
|
| 298 |
|
|
@@ -389,7 +370,7 @@ ep=5800–6000: 62–76% ← 末段振荡
|
|
| 389 |
原因:即使 buffer=80000(约 1000 局),在成功率 60–80% 的阶段,仍约有 20–40% 的失败局(200步)持续填入 buffer;成功样本的相对比例虽有改善,但绝对数量仍不足以彻底稳定策略。
|
| 390 |
依据 Schaul et al. (2016):根治方案需使用 **Prioritized Experience Replay(PER)**,让高 TD-error 的成功样本被优先重复采样,而非依赖更大 buffer。
|
| 391 |
|
| 392 |
-
>
|
| 393 |
|
| 394 |
#### P4 — target network 修复效果验证(有效)
|
| 395 |
|
|
@@ -423,20 +404,15 @@ ep=800 成功率恢复至 42%,ep=1000 回到 44%,ep=1050 跳升至 62%,之
|
|
| 423 |
**理论根源**:Lin (1992) 指出 ER 的核心价值之一是保留稀有样本,但均匀采样无法主动偏向高价值样本。
|
| 424 |
**解决方案**:Prioritized Experience Replay(Schaul et al. 2016)——赋予高 TD-error 样本更高采样概率,使成功样本被更频繁地学习,振荡可从根本上消除。
|
| 425 |
|
| 426 |
-
### TensorBoard
|
| 427 |
-
|
| 428 |
-
```
|
| 429 |
-
runs/Round3_double_buffer80k_target1500/
|
| 430 |
-
runs/Round3_double_buffer80k_target1500_restart/ ← 重启前的短暂记录(ep<400)
|
| 431 |
-
```
|
| 432 |
-
|
| 433 |
-
### TensorBoard 曲线截图
|
| 434 |
|
| 435 |
-
|
| 436 |
-
|
|
|
|
|
|
|
|
|
|
| 437 |
|
| 438 |
-
|
| 439 |
-

|
| 440 |
|
| 441 |
### R3 总结与 R4 决策依据
|
| 442 |
|
|
@@ -481,27 +457,26 @@ buffer+target 组合将盲测峰值从 74% 提升至 **84%**,Holdout 从 64%
|
|
| 481 |
|
| 482 |
---
|
| 483 |
|
| 484 |
-
#### 四、
|
| 485 |
|
| 486 |
-
R3 训练完成后,将 best_model 在 Web Demo 中实测推理(ε=0 纯贪心),观察到 agent 在部分地图中陷入两格间无限震荡——A→B→A→B 循环 200 步触底截断。
|
| 487 |
|
| 488 |
-
| 分类 | R3 局数 |
|
| 489 |
-
|------|--------:|
|
| 490 |
-
| 快速成功(≤30 步) | 75 |
|
| 491 |
-
|
|
| 492 |
-
|
|
| 493 |
-
|
|
| 494 |
-
|
|
| 495 |
-
|
|
| 496 |
-
| 失败局平均撞墙数 | 0.0 | 0.0 |
|
| 497 |
|
| 498 |
-
*Holdout 100 局(seed+200042..+200141),R3
|
| 499 |
|
| 500 |
**数据解读**:
|
| 501 |
|
| 502 |
- **100% 截断 + 撞墙=0**:撞墙=0 排除"撞墙堵死"(撞墙会留下 hit_wall 计数),唯一合理解释是 agent 在自由格间反复震荡;10×10 迷宫最优路径仅 15-25 步,200 步远超合理上限。
|
| 503 |
- **失败-成功 0/1 离散**:成功局集中在 ≤30 步,失败局集中在 200 步,无中间过渡;0% 近截断、0% 早夭,无"接近但错过"或"路径规划差但仍在前进"的中间情形。
|
| 504 |
-
- **
|
| 505 |
|
| 506 |
**R3 训练期 → EVAL 期的因果链**:训练期截断率 15.5%(含 5% ε 探索,部分跳出循环)→ EVAL 期截断率 25%(ε=0,循环被锁定)→ 100% 截断且撞墙=0 → 循环机制是 R3 失败主因 → R4 必须显式编码访问历史。
|
| 507 |
|
|
@@ -518,19 +493,19 @@ if eval_success_rate > best_eval_success_rate:
|
|
| 518 |
save_model()
|
| 519 |
```
|
| 520 |
|
| 521 |
-
**R4
|
| 522 |
|
| 523 |
-
|
|
| 524 |
-
|------|----|------|
|
| 525 |
-
|
|
| 526 |
-
| `
|
| 527 |
-
|
|
| 528 |
-
|
|
| 529 |
-
| **`revisit_penalty`** | **-1.0** | **新增:训练时重复访问格子施加递进惩罚,抑制循环路径** |
|
| 530 |
-
| **checkpoint 保存策略** | **EVAL 成功率最优** | **本轮核心变更** |
|
| 531 |
|
| 532 |
**预期**:R3 中 double 算法 EVAL 峰值达 84%,改保存策略后 Holdout 预期接近 80–84%(消除 10pp 保存时机损失,剩余 2–4pp 为评估集过拟合的正常偏差)。
|
| 533 |
|
|
|
|
|
|
|
| 534 |
---
|
| 535 |
|
| 536 |
## Round 4 — 系统性问题修复:Checkpoint 策略 + 训练信号质量
|
|
@@ -572,38 +547,18 @@ EVAL 集与 Holdout 集独立,用 EVAL 集挑 checkpoint 引入的偏差约 2
|
|
| 572 |
|
| 573 |
#### P8 — 随机起终点缺乏连通性验证(信号污染)
|
| 574 |
|
| 575 |
-
**代码现状**(修复前):
|
| 576 |
|
| 577 |
-
|
|
|
|
|
|
|
| 578 |
|
| 579 |
-
``
|
| 580 |
-
# 修复前(训练循环,约第460行)
|
| 581 |
-
obs, _ = env.reset(options={
|
| 582 |
-
"wall_map": wall_map,
|
| 583 |
-
"start": inner[idx_a],
|
| 584 |
-
"goal": inner[idx_b], # 可能与 start 不连通!
|
| 585 |
-
})
|
| 586 |
-
# 注释甚至写着"env 内 BFS 保证连通"——这是错误注释
|
| 587 |
-
```
|
| 588 |
-
|
| 589 |
-
**影响量化**:
|
| 590 |
-
|
| 591 |
-
obstacle_density=0.25 的 10×10 地图,内圈约 48 个自由格。随机选取两个自由格,不连通概率取决于地图的连通分量数。典型场景下,约 5–10% 的随机起终点对不可达。
|
| 592 |
-
|
| 593 |
-
这些无解任务的影响:
|
| 594 |
-
- **训练侧**:无解局在 `max_steps=200` 内必然 `truncated`,贡献 200 步全负奖励(约 -201)进入 buffer。Q 网络在这些样本上学到"某些位置无论如何行动都是大负收益",引入系统性噪声。无解任务约占 5–10%,若每局约 80 步,无解局步数是正常局的 2.5 倍,在 buffer 中的样本权重被进一步放大。
|
| 595 |
-
- **评估侧**:Holdout 的 100 张地图中,不连通任务必然失败,直接压低成功率分母。Holdout 成功率被系统性低估约 **5–10% × 不连通率 ≈ 0.25–1pp**(量级较小但真实存在)。
|
| 596 |
-
|
| 597 |
-
**修复方案(commit `413b4eb`)**:
|
| 598 |
|
| 599 |
```python
|
| 600 |
-
# 修复后:选完起终点后 BFS 验证,不通则重新采样
|
| 601 |
-
from maze_env.generator import bfs_reachable as _bfs_reachable
|
| 602 |
-
|
| 603 |
while not _bfs_reachable(wall_map, start_pos, goal_pos):
|
| 604 |
idxs = rng.choice(len(inner), size=2, replace=False)
|
| 605 |
-
start_pos = inner[idxs[0]]
|
| 606 |
-
goal_pos = inner[idxs[1]]
|
| 607 |
```
|
| 608 |
|
| 609 |
训练循环和 EVAL 循环均同步修复,同时删除错误注释。
|
|
@@ -612,11 +567,9 @@ while not _bfs_reachable(wall_map, start_pos, goal_pos):
|
|
| 612 |
|
| 613 |
#### 推理时策略循环问题(新发现)
|
| 614 |
|
| 615 |
-
**发现路径**:R3
|
| 616 |
-
|
| 617 |
-
**EVAL 期步数分布(量化佐证)**:详见上文"四、循环失败率的直接测量"——R3 best_model 在 Holdout 100 局(ε=0 贪心)上的逐局步数显示 25/25=100% 失败局是步数=200 截断且撞墙=0.0,确证循环是 R3 EVAL 期失败的主因。训练期 vs EVAL 期的截断率差异(15.5% → 25%,见表 6.3)即 ε 探索在循环抑制上的边际贡献。
|
| 618 |
|
| 619 |
-
**根因**:训练期
|
| 620 |
|
| 621 |
此问题是 R4 的第三个攻坚方向,见后续尝试记录(R4-A1 revisit_penalty 失败 + R4-A2 visited_map 成功)。
|
| 622 |
|
|
@@ -628,20 +581,15 @@ R4 共进行四次独立尝试(对照组 R4-A3 已完成),每次对比 R3
|
|
| 628 |
|
| 629 |
**注意**:R3 使用 eval_every=50,R4 系列使用 eval_every=100,下方对比统一取 100 ep 间隔数据点。
|
| 630 |
|
| 631 |
-
R3 每 100 ep 的 EVAL 成功率(取相邻 50ep 点均值,ep=300 起):
|
| 632 |
|
| 633 |
-
|
| 634 |
-
|
| 635 |
-
|
| 636 |
-
|
| 637 |
-
|
| 638 |
-
|
| 639 |
-
|
| 640 |
-
ep=3300: 74% ep=3400: 76% ep=3500: 76% ep=3600: 72% ep=3700: 74%
|
| 641 |
-
ep=3750: 84% ep=3800: 72% ep=3900: 74% ep=4000: 74% ep=4100: 69%
|
| 642 |
-
ep=4200: 76% ep=4300: 76% ep=4400: 69% ep=4500: 65% ep=4600: 72%
|
| 643 |
-
ep=4700: 71% ep=4800: 70% ep=4900: 66% ep=5000: 64%
|
| 644 |
-
```
|
| 645 |
|
| 646 |
---
|
| 647 |
|
|
@@ -664,7 +612,7 @@ ep=4700: 71% ep=4800: 70% ep=4900: 66% ep=5000: 64%
|
|
| 664 |
| 900 | 28% | 0.263 | 42% | -14pp |
|
| 665 |
| 1000 | 38% | 0.354 | 53% | **-15pp** |
|
| 666 |
|
| 667 |
-
**终止判据**:ep=1000 时成功率 38%,持续低于 R3 同期
|
| 668 |
|
| 669 |
**失败根因:马尔可夫性违反(P9)**
|
| 670 |
|
|
@@ -672,15 +620,11 @@ Q-learning 的贝尔曼方程要求奖励函数 $r(s, a, s')$ 仅依赖当前转
|
|
| 672 |
|
| 673 |
$$Q(s,a) = \mathbb{E}\left[r(s,a,s') + \gamma \max_{a'} Q(s',a')\right]$$
|
| 674 |
|
| 675 |
-
`revisit_penalty` 使奖励依赖隐变量(本 episode 内的访问历史),即 $r(s,a,s') = r_{\
|
| 676 |
|
| 677 |
-
更严重的是训练/推理分布不一致:
|
| 678 |
-
- **训练时**:$r(s,a)$ 含访问历史惩罚项
|
| 679 |
-
- **推理时**:$r(s,a)$ = 基础奖励(无惩罚)
|
| 680 |
|
| 681 |
-
|
| 682 |
-
|
| 683 |
-
**与早期 Q 值高估 crisis(Q 值估计暂时性偏差)的本质区别**:crisis 是 Q 值在学习过程中的暂时性估计偏差,奖励函数形式在训练和推理时一致,Double DQN 可自修正;P9 是奖励函数结构在训练和推理时不一致(训练时含访问历史惩罚,推理时无),Q 函数目标在测试分布下无意义,不可修正。
|
| 684 |
|
| 685 |
**结论**:**结构性失败,不可修补。** 奖励层的循环抑制方案在任何需要"有状态奖励"的场景下都会违反马尔可夫性。
|
| 686 |
|
|
@@ -703,22 +647,14 @@ $$Q(s,a) = \mathbb{E}\left[r(s,a,s') + \gamma \max_{a'} Q(s',a')\right]$$
|
|
| 703 |
|
| 704 |
**checkpoint 保存**:此次仍为训练滚动奖励触发(EVAL 修复尚未合入)。
|
| 705 |
|
| 706 |
-
**EVAL 数据(ep=300–5000,每 100 ep)**:
|
| 707 |
|
| 708 |
-
|
| 709 |
-
|
| 710 |
-
|
| 711 |
-
|
| 712 |
-
|
| 713 |
-
|
| 714 |
-
ep=2300: 72% ep=2400: 68% ep=2500: 76% ep=2600: 74%
|
| 715 |
-
ep=2700: 78% ep=2800: 70% ep=2900: 74% ep=3000: 74%
|
| 716 |
-
ep=3100: 78% ep=3200: 72% ep=3300: 76% ep=3400: 76%
|
| 717 |
-
ep=3500: 74% ep=3600: 70% ep=3700: 76% ep=3800: 74%
|
| 718 |
-
ep=3900: 76% ep=4000: 74% ep=4100: 66% ep=4200: 72%
|
| 719 |
-
ep=4300: 76% ep=4400: 74% ep=4500: 70% ep=4600: **80%** ← 历史峰值
|
| 720 |
-
ep=4700: 68% ep=4800: 70% ep=4900: 68% ep=5000: 70%
|
| 721 |
-
```
|
| 722 |
|
| 723 |
**Holdout 结果**:
|
| 724 |
|
|
@@ -794,23 +730,13 @@ while not _bfs_reachable(wall_map, start_pos, goal_pos):
|
|
| 794 |
|
| 795 |
训练循环和 EVAL 循环均同步修复。
|
| 796 |
|
| 797 |
-
**EVAL
|
| 798 |
|
| 799 |
-
|
| 800 |
-
|
| 801 |
-
|
| 802 |
-
|
| 803 |
-
|
| 804 |
-
ep=1900: 76% ep=2000: 72% ep=2100: 68% ep=2200: 76%
|
| 805 |
-
ep=2300: 78% ep=2400: 82% ★ ep=2500: 76% ep=2600: 76%
|
| 806 |
-
ep=2700: 78% ep=2800: 78% ep=2900: 84% ★ ep=3000: 84%
|
| 807 |
-
ep=3100: 86% ★ ep=3200: 80% ep=3300: 88% ★★ ep=3400: 84%
|
| 808 |
-
ep=3500: 82% ep=3600: 84% ep=3700: 88% ep=3800: 86%
|
| 809 |
-
ep=3900: 86% ep=4000: 86% ep=4100: 84% ep=4200: 84%
|
| 810 |
-
ep=4300: 84% ep=4400: 80% ep=4500: 78% ep=4600: 78%
|
| 811 |
-
ep=4700: 82% ep=4800: 82% ep=4900: 78% ep=5000: 82%
|
| 812 |
-
```
|
| 813 |
-
★ = EVAL SAVE 触发点,最高 88%(ep=3300/3700)
|
| 814 |
|
| 815 |
**Holdout 结果**:
|
| 816 |
|
|
@@ -877,23 +803,6 @@ $$\text{无解任务率} \approx p_{\text{unreachable}} \approx 5\text{–}10\%$
|
|
| 877 |
|
| 878 |
---
|
| 879 |
|
| 880 |
-
### TensorBoard 运行目录
|
| 881 |
-
|
| 882 |
-
```
|
| 883 |
-
runs/Round4_double_visited_map/ ← R4-A2 记录
|
| 884 |
-
runs/Round4_ctrl_eval_ckpt/ ← R4-A3 记录(已完成,ep=5000)
|
| 885 |
-
```
|
| 886 |
-
|
| 887 |
-
### 所需截图
|
| 888 |
-
|
| 889 |
-
- [x] `r4_eval_success_rate_all_algos.png`:R4 四算法 EVAL 成功率曲线(已生成)
|
| 890 |
-
- [x] `r4_eval_spl_all_algos.png`:R4 四算法 SPL 曲线(已生成)
|
| 891 |
-
- [x] `r4_dueling_full_curves.png`:最优算法完整训练曲线(已生成)
|
| 892 |
-
- [x] `cmp_eval_success_rate_r1_to_r4_double.png`:R1→R4 超参演进纵向对比(已生成)
|
| 893 |
-
- [ ] `r4_a1_eval_collapse.png`:R4-A1 的 EVAL 崩溃曲线(runs 目录已删,无法补充)
|
| 894 |
-
|
| 895 |
-
---
|
| 896 |
-
|
| 897 |
## Round 4(续)— 算法横向消融:Vanilla / Double / Dueling / Double-Dueling
|
| 898 |
|
| 899 |
**日期**:2026-06-01
|
|
@@ -935,7 +844,7 @@ runs/Round4_ctrl_eval_ckpt/ ← R4-A3 记录(已完成,ep=5000
|
|
| 935 |
|
| 936 |
#### 危机成因(共性)
|
| 937 |
|
| 938 |
-
四种算法在 ep≈400–700 区间均出现 EVAL
|
| 939 |
|
| 940 |
#### 四算法危机程度对比
|
| 941 |
|
|
@@ -969,10 +878,11 @@ $$\hat{Q}_{\text{double}} = r + \gamma Q_{\theta^-}(s', \arg\max_{a'} Q_\theta(s
|
|
| 969 |
|
| 970 |
**观察**:
|
| 971 |
|
| 972 |
-
- **危机
|
| 973 |
- **恢复速度**:ep=700 时 double_dueling(54%)领先 dueling(6%)48pp,是 Double DQN 解耦机制最直接定量证据
|
| 974 |
-
- **峰值时机**:double_dueling(ep=4200)比 vanilla(ep=4800)早 600 ep,体现双重改进加速收敛
|
| 975 |
-
|
|
|
|
| 976 |
|
| 977 |
---
|
| 978 |
|
|
@@ -1004,16 +914,11 @@ Wang et al. (2016) 指出,Dueling 架构将 Q 函数分解为状态价值函
|
|
| 1004 |
|
| 1005 |
$$Q(s,a) = V(s) + A(s,a) - \frac{1}{|\mathcal{A}|}\sum_{a'} A(s',a')$$
|
| 1006 |
|
| 1007 |
-
其核心收益在于**共享状态价值估计**
|
| 1008 |
-
|
| 1009 |
-
**本任务的适配性**:
|
| 1010 |
|
| 1011 |
-
随机起终点 10×10 迷宫中
|
| 1012 |
-
1. **死胡同状态**:3个方向均为墙,唯一可行动作明确,A(s,a) 的估计误差影响微小,主要价值来自 V(s) 对该位置是否接近终点的评估
|
| 1013 |
-
2. **走廊状态**:两侧为墙,V(s) 携带的路径价值信息(曼哈顿距离+障碍分布)比单动作的 A(s,a) 更稳定
|
| 1014 |
-
3. **已访问格重访**:ch3=visited_map 编码历史,当 V(s) 准确反映"当前格已多次访问、价值已被充分学习"的信息时,Dueling 比 vanilla 更高效地利用了状态价值信号
|
| 1015 |
|
| 1016 |
-
这一分析与实测结果一致:**dueling 的 EVAL→Holdout gap 仅 6pp(最小)**,
|
| 1017 |
|
| 1018 |
#### Double DQN 在危机期的修正机制
|
| 1019 |
|
|
@@ -1028,17 +933,13 @@ $$Q(s,a) = V(s) + A(s,a) - \frac{1}{|\mathcal{A}|}\sum_{a'} A(s',a')$$
|
|
| 1028 |
|
| 1029 |
**理论预期**:两项改进正交(一改架构,一改目标计算),叠加应有协同收益。
|
| 1030 |
|
| 1031 |
-
**实测结果**:double_dueling Holdout=81%,
|
| 1032 |
-
|
| 1033 |
-
这一"叠加不如单独"的结果有以下解释:
|
| 1034 |
-
|
| 1035 |
-
1. **训练时间对称性破坏**:double_dueling 在 ep=4200 已达 EVAL 峰值,而 dueling 在 ep=4900 仍在上升。double_dueling 较早"过峰",说明 Double DQN 使收敛更快(对应危机恢复更快),但也可能导致 Q 值在峰值后更快出现低估偏差(over-correction),而 dueling 因 vanilla 目标反而保留了轻微的高估"缓冲",维持了更长的高性能区间。
|
| 1036 |
|
| 1037 |
-
|
| 1038 |
|
| 1039 |
-
|
| 1040 |
|
| 1041 |
-
**结论**:
|
| 1042 |
|
| 1043 |
---
|
| 1044 |
|
|
@@ -1053,16 +954,35 @@ $$Q(s,a) = V(s) + A(s,a) - \frac{1}{|\mathcal{A}|}\sum_{a'} A(s',a')$$
|
|
| 1053 |
|
| 1054 |
**vanilla 的 19pp Gap 解读**:
|
| 1055 |
|
| 1056 |
-
vanilla 是本组唯一
|
| 1057 |
|
| 1058 |
-
1. **EVAL 集
|
| 1059 |
-
2. **训练晚期策略退化**:vanilla 无 V/A 分解,Q(s,a) 需逐一精确估计,训练末段(ep=4500+)的 buffer 回放可能已不能支持
|
| 1060 |
|
| 1061 |
**dueling 的 6pp Gap 解读**:
|
| 1062 |
|
| 1063 |
-
Dueling
|
| 1064 |
|
| 1065 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1066 |
|
| 1067 |
---
|
| 1068 |
|
|
@@ -1080,21 +1000,19 @@ Dueling 网络的真正泛化优势来自**参数共享机制**:V(s) 流被所
|
|
| 1080 |
| R4-A3 (double) | EVAL checkpoint + BFS + visited_map | 78% | EVAL→Holdout gap 10pp 持续(算法限制) |
|
| 1081 |
| **R4 dueling** | 同 A3 超参 + Dueling 架构 | **84%** | **EVAL→Holdout gap 仅 6pp(最优泛化)** |
|
| 1082 |
| R4 double_dueling | 同上 + Double DQN | 81% | 收敛快但末段稳定性略低 |
|
| 1083 |
-
| R4 vanilla | 同上,无增强 | 75% |
|
| 1084 |
|
| 1085 |
**最终结论(五点)**:
|
| 1086 |
|
| 1087 |
-
1. **Dueling 架构是本任务的最优选择**:V(s)/A(s,a) 分解
|
| 1088 |
-
|
| 1089 |
-
2. **Double DQN 主要收益在训练过程,非最终结果**:危机期加速恢复(ep=700 领先 dueling 48pp)和早期收敛加速是真实可量化的收益;但在 5000 ep 充分训练后,与纯 dueling 的最终 Holdout 差距(81% vs 84%)表明 Double DQN 的抗高估机制在本任务规模下已不是瓶颈。
|
| 1090 |
|
| 1091 |
-
|
| 1092 |
|
| 1093 |
-
|
| 1094 |
|
| 1095 |
-
|
| 1096 |
|
| 1097 |
-
|
| 1098 |
|
| 1099 |
---
|
| 1100 |
|
|
|
|
| 15 |
| Round 2 | 随机起终点 | `ep=6000` + `decay=0.9985` | 64.0% | 0.633 | 74% | P1/P2 修复,新发现 buffer 过小(P3)和 target 同步过频(P4)|
|
| 16 |
| Round 3 | 随机起终点 | `buffer=80k` + `target=1500` | **74.0%** | **0.735** | **84%** | 峰值突破 80%;Holdout 低于峰值 10pp,根因为保存策略 |
|
| 17 |
| Round 4 | 随机起终点 | EVAL-based checkpoint + BFS 连通性验证;探索 revisit_penalty(失败)和 visited_map 4通道 | **78.0%**(A3,double 算法) | **0.773** | **88%** | P7(checkpoint时序)+P8(无解任务)系统性修复;P9(马尔可夫违反)新发现;A3为三项变量叠加,非单因素对照 |
|
| 18 |
+
| Round 4(续)| 随机起终点 | R4-A3 超参固定,四算法横向消融(唯一变量=算法)| **84.0%**(dueling,最优) | **0.817** | **94%**(vanilla) | dueling EVAL→Holdout gap=6pp 最优泛化;double_dueling 81%;vanilla 75%(19pp gap,仅在固定 50 张 EVAL 集上成立);Double DQN 危机恢复快但终态不及纯 dueling |
|
| 19 |
|
| 20 |
**关键结论链**:随机起终点使状态空间扩大约 40×,需要更长训练(R2)→ 更大 buffer 保留稀疏成功样本(R3)→ 修复 checkpoint 时序偏差 + 连通性验证 + visited_map 状态编码(R4)→ Dueling 架构的 V/A 分解与多动作等效迷宫导航任务高度适配(R4 算法消融)。奖励层循环抑制违反马尔可夫性(P9);状态层编码(visited_map)理论正确;最优配置(dueling + EVAL checkpoint + BFS + visited_map)最终将 Holdout 从 74%(R3)提升至 **84%**(+10pp)。
|
| 21 |
|
|
|
|
| 127 |
随机起终点导致 Q 值估计方差更高,频繁同步加剧 bootstrapping instability。
|
| 128 |
依据:Mnih et al. (2015) 原版更新周期 10000 步,DQN loss $\mathcal{L}(\theta) = \mathbb{E}[(r + \gamma \max_{a'} Q_{\theta^-}(s',a') - Q_\theta(s,a))^2]$ 中 $\theta^-$ 须提供固定回归目标,同步过频等价于用移动靶做监督学习。
|
| 129 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 130 |
### TensorBoard 曲线截图(与 P1–P4 诊断一一对应)
|
| 131 |
|
| 132 |
| 截图 | 论证的诊断点 | 解读 |
|
|
|
|
| 135 |
|  | P2 | ε 在 ep≈800 触底 0.05,P2 探索过早终止的直接证据 |
|
| 136 |
|  | P4 | Loss 高频震荡,target 同步过频的间接证据 |
|
| 137 |
|
| 138 |
+
> P3 在 R1 中为预测,验证在 R2 截图(见下)。
|
| 139 |
|
| 140 |
### 结论与下一步行动
|
| 141 |
|
| 142 |
**已确认问题**(按优先级):
|
| 143 |
+
1. **P1+P2(高优先级)**:训练量不足 + 探索过早终止是最直接的瓶颈
|
| 144 |
+
2. **P3(中优先级)**:buffer=20000 约 250 局轮换,预测 R2 将出现 400–500 ep 周期振荡
|
| 145 |
3. **P4(中优先级)**:target 同步 272 次/轮,高 Q 方差场景下移动靶效应显著
|
| 146 |
|
| 147 |
+
**下一步行动**:R1 当时能直接决定的修复只有 P1+P2(成对修改`num_episodes` 与 `epsilon_decay`)。P3+P4 需在 R2 长曲线上验证后才能量化修复(buffer 扩到多少、target_update_freq 调到多少);R4 的修复方向(EVAL checkpoint、BFS、visited_map)均需 R2/R3 实跑后才有依据,不在 R1 阶段可推断范围。
|
|
|
|
|
|
|
|
|
|
|
|
|
| 148 |
|
| 149 |
---
|
| 150 |
|
|
|
|
| 265 |
|
| 266 |
---
|
| 267 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 268 |
### TensorBoard 曲线截图(与 P1–P4 诊断一一对应)
|
| 269 |
|
| 270 |
| 截图 | 论证的诊断点 | 解读 |
|
|
|
|
| 273 |
|  | P2 验收 | R2 ε 触底点 ep≈2189,R1 触底点 ep≈800,差距 1400 ep |
|
| 274 |
|  | P3(主瓶颈) | R2 长曲线全程振荡 52-74%,振幅 ±10%,与 P3 预测的 400-500ep 周期吻合 |
|
| 275 |
|
| 276 |
+
> P4(target 同步)的截图在 R3 给出(`r3_backend_avg_q.png` 显示 Q 值稳定性提升)。
|
| 277 |
|
| 278 |
### 下一步行动
|
| 279 |
|
|
|
|
| 370 |
原因:即使 buffer=80000(约 1000 局),在成功率 60–80% 的阶段,仍约有 20–40% 的失败局(200步)持续填入 buffer;成功样本的相对比例虽有改善,但绝对数量仍不足以彻底稳定策略。
|
| 371 |
依据 Schaul et al. (2016):根治方案需使用 **Prioritized Experience Replay(PER)**,让高 TD-error 的成功样本被优先重复采样,而非依赖更大 buffer。
|
| 372 |
|
| 373 |
+
> P3 与 P6 关系:P3 是"扩容缓解"(短效工程修复),P6 是"采样策略根因"(长效方案)。两者不矛盾,对应不同层面。
|
| 374 |
|
| 375 |
#### P4 — target network 修复效果验证(有效)
|
| 376 |
|
|
|
|
| 404 |
**理论根源**:Lin (1992) 指出 ER 的核心价值之一是保留稀有样本,但均匀采样无法主动偏向高价值样本。
|
| 405 |
**解决方案**:Prioritized Experience Replay(Schaul et al. 2016)——赋予高 TD-error 样本更高采样概率,使成功样本被更频繁地学习,振荡可从根本上消除。
|
| 406 |
|
| 407 |
+
### TensorBoard 曲线截图(与 P3–P6 诊断一一对应)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 408 |
|
| 409 |
+
| 截图 | 论证的诊断点 | 解读 |
|
| 410 |
+
|------|------------|------|
|
| 411 |
+
|  | P3 验证 | 振荡周期从 R2 的 400-500 ep 延长至 R3 的 700-900 ep(约 1.5-2 倍),低谷从 52% 抬至 56%,符合 buffer×4 预测 |
|
| 412 |
+
|  | P3 验证 + P6 | R3 振荡周期延长但幅度未减(±14pp),指向 P6(均匀采样本身是周期性遗忘的根因) |
|
| 413 |
+
|  | P4 验证 | R3 AvgQ 后期稳定在 35-60 区间,波动范围比 R2(35-70)收窄,target 更新频率降低有效 |
|
| 414 |
|
| 415 |
+
> P5(早期 Q 值高估危机)以 `r3_eval_success_rate.png` 中 ep=400-650 骤降区域作为佐证,无独立截图。SPL 曲线(`r3_eval_spl.png`)未引用进诊断,已删除。
|
|
|
|
| 416 |
|
| 417 |
### R3 总结与 R4 决策依据
|
| 418 |
|
|
|
|
| 457 |
|
| 458 |
---
|
| 459 |
|
| 460 |
+
#### 四、R3 失败模式直接测量(提供 R4 引入 4 通道的数据依据)
|
| 461 |
|
| 462 |
+
R3 训练完成后,将 best_model 在 Web Demo 中实测推理(ε=0 纯贪心),观察到 agent 在部分地图中陷入两格间无限震荡——A→B→A→B 循环 200 步触底截断。逐局步数测量如下:
|
| 463 |
|
| 464 |
+
| 分类 | R3 局数 |
|
| 465 |
+
|------|--------:|
|
| 466 |
+
| 快速成功(≤30 步) | 75 |
|
| 467 |
+
| 失败·截断(步数=200) | **25** |
|
| 468 |
+
| 其他(中间步数失败/慢成功) | 0 |
|
| 469 |
+
| 成功率 | 75% |
|
| 470 |
+
| **失败局中截断占比** | **25/25 = 100%** |
|
| 471 |
+
| 失败局平均撞墙数 | 0.0 |
|
|
|
|
| 472 |
|
| 473 |
+
*Holdout 100 局(seed+200042..+200141),R3 best_model(double 算法)。*
|
| 474 |
|
| 475 |
**数据解读**:
|
| 476 |
|
| 477 |
- **100% 截断 + 撞墙=0**:撞墙=0 排除"撞墙堵死"(撞墙会留下 hit_wall 计数),唯一合理解释是 agent 在自由格间反复震荡;10×10 迷宫最优路径仅 15-25 步,200 步远超合理上限。
|
| 478 |
- **失败-成功 0/1 离散**:成功局集中在 ≤30 步,失败局集中在 200 步,无中间过渡;0% 近截断、0% 早夭,无"接近但错过"或"路径规划差但仍在前进"的中间情形。
|
| 479 |
+
- **直接指向训练侧缺陷**:状态层缺少访问历史 → 推理时 Q 函数无法区分两格循环与两格前进 → 修复方向 = 把访问历史编码进状态(visited_map 第 4 通道),而非在奖励层加惩罚(会破坏马尔可夫性,详见 P9)。
|
| 480 |
|
| 481 |
**R3 训练期 → EVAL 期的因果链**:训练期截断率 15.5%(含 5% ε 探索,部分跳出循环)→ EVAL 期截断率 25%(ε=0,循环被锁定)→ 100% 截断且撞墙=0 → 循环机制是 R3 失败主因 → R4 必须显式编码访问历史。
|
| 482 |
|
|
|
|
| 493 |
save_model()
|
| 494 |
```
|
| 495 |
|
| 496 |
+
**R4 行动计划**(R3 收尾时的最初规划,按"问题驱动"组织):
|
| 497 |
|
| 498 |
+
| 变更项 | 内容 | 对应 R3 遗留问题 |
|
| 499 |
+
|--------|------|----------------|
|
| 500 |
+
| **EVAL-based checkpoint** | 每次评估若成功率创新高则保存 | 修复 P7(10pp 时序错位) |
|
| 501 |
+
| **BFS 连通性验证** | `reset()` 内嵌 BFS,无解迷宫重采样 | 修复 P8(训练信号被无解任务污染) |
|
| 502 |
+
| **visited_map 第 4 通道** | 状态层编码访问历史 | 修复循环失败(P5 根因候选,需消融验证) |
|
| 503 |
+
| 备注:revisit_penalty | 计划作为循环抑制的另一候选方案,**与 visited_map 并行消融** | 不确定状态层 vs 奖励层哪个有效 |
|
|
|
|
|
|
|
| 504 |
|
| 505 |
**预期**:R3 中 double 算法 EVAL 峰值达 84%,改保存策略后 Holdout 预期接近 80–84%(消除 10pp 保存时机损失,剩余 2–4pp 为评估集过拟合的正常偏差)。
|
| 506 |
|
| 507 |
+
**关于"R4 续 / 算法横评阶段"**:R4 完成上述三项叠加后,确认 78% 是该算法(double)的上限;为判断"R4 还能不能继续往前推 6pp" 才有了"R4 续"——固定 R4 已验证有效的超参组合(buffer=80k、target=1500、shaping=0.5、visited_map 4通道、EVAL checkpoint、BFS),4 种算法各跑一次。这是"消融决定上限 → 用剩余 6pp 空间横评算法"的两步走,**不是 R3 结束后 R4 一开始就规划的内容**。
|
| 508 |
+
|
| 509 |
---
|
| 510 |
|
| 511 |
## Round 4 — 系统性问题修复:Checkpoint 策略 + 训练信号质量
|
|
|
|
| 547 |
|
| 548 |
#### P8 — 随机起终点缺乏连通性验证(信号污染)
|
| 549 |
|
| 550 |
+
**代码现状**(修复前):`train.py` 在训练循环和 EVAL 循环的随机起终点逻辑中,从自由格中随机选取两点后**直接注入** `env.reset()`,不做连通性检验——原代码注释甚至误称"env 内 BFS 保证连通"。
|
| 551 |
|
| 552 |
+
**影响量化**:obstacle_density=0.25 的 10×10 地图,约 5–10% 的随机起终点对不可达。
|
| 553 |
+
- **训练侧**:无解局在 `max_steps=200` 内必然 truncated,贡献 200 步全负奖励进入 buffer。无解局步数是正常局 2.5 倍,在 buffer 中样本权重被放大
|
| 554 |
+
- **评估侧**:Holdout 不连通任务必然失败,成功率被系统性低估约 **0.25–1pp**
|
| 555 |
|
| 556 |
+
**修复方案(commit `413b4eb`)**:选完起终点后 BFS 验证,不通则重新采样:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 557 |
|
| 558 |
```python
|
|
|
|
|
|
|
|
|
|
| 559 |
while not _bfs_reachable(wall_map, start_pos, goal_pos):
|
| 560 |
idxs = rng.choice(len(inner), size=2, replace=False)
|
| 561 |
+
start_pos, goal_pos = inner[idxs[0]], inner[idxs[1]]
|
|
|
|
| 562 |
```
|
| 563 |
|
| 564 |
训练循环和 EVAL 循环均同步修复,同时删除错误注释。
|
|
|
|
| 567 |
|
| 568 |
#### 推理时策略循环问题(新发现)
|
| 569 |
|
| 570 |
+
**发现路径与量化佐证**:R3 best_model 在 Web Demo 实测推理(ε=0 纯贪心)陷入两格震荡(A→B→A→B 循环 200 步触底截断)。逐局步数详见上文"四、R3 失败模式直接测量"——100% 失败局为步数=200 截断且撞墙=0.0,确证循环是 R3 EVAL 期失败主因。
|
|
|
|
|
|
|
| 571 |
|
| 572 |
+
**根因**:训练期 ε>0 探索在多数情况下帮助跳出局部循环,但**部分地图起终点组合使 ε 探索也不足以在 200 步内到达终点**——这些训练局贡献"循环 200 步的负奖励轨迹",网络学到"某些区域走出去成本极高"但不知道主动规避重复访问。visited_map 第 4 通道把"是否访问过"显式编码到状态中,使网络可直接学习"重访成本"——从症状侧抑制循环(不是消除机制)。
|
| 573 |
|
| 574 |
此问题是 R4 的第三个攻坚方向,见后续尝试记录(R4-A1 revisit_penalty 失败 + R4-A2 visited_map 成功)。
|
| 575 |
|
|
|
|
| 581 |
|
| 582 |
**注意**:R3 使用 eval_every=50,R4 系列使用 eval_every=100,下方对比统一取 100 ep 间隔数据点。
|
| 583 |
|
| 584 |
+
R3 每 100 ep 的 EVAL 成功率概要(取相邻 50ep 点均值,ep=300 起):
|
| 585 |
|
| 586 |
+
| 阶段 | ep 区间 | 成功率 | 备注 |
|
| 587 |
+
|------|---------|:------:|------|
|
| 588 |
+
| Q 值高估危机 | 400–700 | 8–29% | 最低 8%(ep=400) |
|
| 589 |
+
| 自修正完成 | 800–2000 | 41–72% | 逐步爬升 |
|
| 590 |
+
| 高位平台 | 2000–3700 | 64–76% | 振荡区间 |
|
| 591 |
+
| **历史峰值** | 3750 | **84%** | R3 全程最高点 |
|
| 592 |
+
| 末段 | 3800–5000 | 64–76% | 缓慢回落 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 593 |
|
| 594 |
---
|
| 595 |
|
|
|
|
| 612 |
| 900 | 28% | 0.263 | 42% | -14pp |
|
| 613 |
| 1000 | 38% | 0.354 | 53% | **-15pp** |
|
| 614 |
|
| 615 |
+
**终止判据**:ep=1000 时成功率 38%,持续低于 R3 同期 15pp 以上,无收敛趋势。
|
| 616 |
|
| 617 |
**失败根因:马尔可夫性违反(P9)**
|
| 618 |
|
|
|
|
| 620 |
|
| 621 |
$$Q(s,a) = \mathbb{E}\left[r(s,a,s') + \gamma \max_{a'} Q(s',a')\right]$$
|
| 622 |
|
| 623 |
+
`revisit_penalty` 使奖励依赖隐变量(本 episode 内的访问历史),即 $r(s,a,s') = r_{\mathrm{base}} + f(\mathrm{visit\_count}[s'])$,其中 $f$ 在每个 episode 内单调递增。相同的 $(s,a)$ 在不同时刻返回不同奖励,Q 函数在数学上无法收敛到唯一固定点。
|
| 624 |
|
| 625 |
+
更严重的是训练/推理分布不一致:训练时 $r(s,a)$ 含访问历史惩罚,推理时 $r(s,a)$ = 基础奖励。网络拟合的是"含历史信息的"奖励函数,但推理时该信息不存在,Q 值系统性失准。这不是 Q 值高估问题(Double DQN 可修正),而是目标函数本身在测试分布下无意义。
|
|
|
|
|
|
|
| 626 |
|
| 627 |
+
**与早期 Q 值高估 crisis 的本质区别**:crisis 是暂时性估计偏差(奖励函数形式在训练/推理时一致,Double DQN 可自修正);P9 是奖励函数结构在训练/推理时不一致(训练时含访问历史惩罚,推理时无),不可修正。
|
|
|
|
|
|
|
| 628 |
|
| 629 |
**结论**:**结构性失败,不可修补。** 奖励层的循环抑制方案在任何需要"有状态奖励"的场景下都会违反马尔可夫性。
|
| 630 |
|
|
|
|
| 647 |
|
| 648 |
**checkpoint 保存**:此次仍为训练滚动奖励触发(EVAL 修复尚未合入)。
|
| 649 |
|
| 650 |
+
**EVAL 数据概要(ep=300–5000,每 100 ep)**:
|
| 651 |
|
| 652 |
+
| 阶段 | ep 区间 | 成功率 | 备注 |
|
| 653 |
+
|------|---------|:------:|------|
|
| 654 |
+
| Q 值高估危机 | 400–700 | 8–32% | AvgQ 峰值 57+ |
|
| 655 |
+
| 自修正完成 | 800–1500 | 42–68% | Double DQN 在 ~400 ep 内自修正 |
|
| 656 |
+
| 中期平台 | 1500–3000 | 60–78% | 收敛稳定 |
|
| 657 |
+
| 末段振荡 | 3000–5000 | 66–80% | 峰值 **80%(ep=4600)** |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 658 |
|
| 659 |
**Holdout 结果**:
|
| 660 |
|
|
|
|
| 730 |
|
| 731 |
训练循环和 EVAL 循环均同步修复。
|
| 732 |
|
| 733 |
+
**EVAL 数据概要(每 100 ep)**:
|
| 734 |
|
| 735 |
+
| 阶段 | ep 区间 | 成功率 | 备注 |
|
| 736 |
+
|------|---------|:------:|------|
|
| 737 |
+
| Q 值高估危机 | 400–800 | 10–34% | EVAL SAVE 首次保存 ep=900(58%) |
|
| 738 |
+
| 早中期爬升 | 900–2000 | 48–80% | 5 次 EVAL SAVE 触发 |
|
| 739 |
+
| 末段高位 | 2000–5000 | 68–88% | 峰值 **88%(ep=3300/3700)** |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 740 |
|
| 741 |
**Holdout 结果**:
|
| 742 |
|
|
|
|
| 803 |
|
| 804 |
---
|
| 805 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 806 |
## Round 4(续)— 算法横向消融:Vanilla / Double / Dueling / Double-Dueling
|
| 807 |
|
| 808 |
**日期**:2026-06-01
|
|
|
|
| 844 |
|
| 845 |
#### 危机成因(共性)
|
| 846 |
|
| 847 |
+
四种算法在 ep≈400–700 区间均出现 EVAL 骤降,根因为 **vanilla 目标 $\hat{Q} = r + \gamma \max_{a'} Q_{\theta^-}(s',a')$ 的 $\max$ 算子正偏差被 bootstrapping 反复放大**:R3 buffer×4 + target×3 改动(延长旧策略样本滞留、放大 TD 漂移)与 R4 visited_map 第4通道(输入分布变化)使早期 $Q_{\theta^-}$ 系统性高估,TD 目标通过自举形成正反馈回路,AvgQ 飙升,EVAL 骤降。同一机制在不同算法上表现程度不同,根源是它们对 max 算子的修正能力不同。
|
| 848 |
|
| 849 |
#### 四算法危机程度对比
|
| 850 |
|
|
|
|
| 878 |
|
| 879 |
**观察**:
|
| 880 |
|
| 881 |
+
- **危机深度排序**(底越深越严重):dueling 4% ≪ vanilla 6% < double 10% < double_dueling 20%。Double DQN 抗高估机制使 double_dueling 危机最浅
|
| 882 |
- **恢复速度**:ep=700 时 double_dueling(54%)领先 dueling(6%)48pp,是 Double DQN 解耦机制最直接定量证据
|
| 883 |
+
- **峰值时机**:double_dueling(ep=4200)比 vanilla(ep=4800)早 600 ep,体现双重改进加速收敛
|
| 884 |
+
|
| 885 |
+
> double(A3) 完整曲线见 [R4-A3 节](#r4-a3--r3-超参--eval-checkpoint--bfs-连通性验证--visited_map已完成)
|
| 886 |
|
| 887 |
---
|
| 888 |
|
|
|
|
| 914 |
|
| 915 |
$$Q(s,a) = V(s) + A(s,a) - \frac{1}{|\mathcal{A}|}\sum_{a'} A(s',a')$$
|
| 916 |
|
| 917 |
+
其核心收益在于**共享状态价值估计**:V(s) 流被所有动作共享,每次梯度更新获得所有动作的梯度信号(更新频率是 A(s,a) 流的 $|\mathcal{A}|$ 倍,本任务 4 倍),估计更稳定。
|
|
|
|
|
|
|
| 918 |
|
| 919 |
+
随机起终点 10×10 迷宫中存在大量"多数动作等效"的状态(死胡同、走廊段、ch3 标记的已访问格),V(s) 携带的路径价值信息(曼哈顿距离+障碍分布+访问历史)比单动作的 A(s,a) 更稳定。
|
|
|
|
|
|
|
|
|
|
| 920 |
|
| 921 |
+
这一分析与实测结果一致:**dueling 的 EVAL→Holdout gap 仅 6pp(最小)**,Dueling 架构泛化性能最稳定。
|
| 922 |
|
| 923 |
#### Double DQN 在危机期的修正机制
|
| 924 |
|
|
|
|
| 933 |
|
| 934 |
**理论预期**:两项改进正交(一改架构,一改目标计算),叠加应有协同收益。
|
| 935 |
|
| 936 |
+
**实测结果**:double_dueling Holdout=81%,低于纯 dueling(84%)3pp。
|
|
|
|
|
|
|
|
|
|
|
|
|
| 937 |
|
| 938 |
+
可能解释:double_dueling 在 ep=4200 已达 EVAL 峰值,dueling 在 ep=4900 仍在上升。Double DQN 加速收敛使 double_dueling 较早"过峰",而 dueling 因 vanilla 目标保留了轻微高估"缓冲",维持了更长的高性能区间。末段稳定性(EVAL→Holdout gap)方面,double_dueling(-9pp)略大于 dueling(-6pp)也佐证此点。
|
| 939 |
|
| 940 |
+
> 注:Holdout n=100,CI≈±5pp;3pp 差距在统计边界但方向一致。
|
| 941 |
|
| 942 |
+
**结论**:Dueling 单独带来的泛化增益(+6pp vs double)大于 Double DQN 单独带来的增益(+3pp vs vanilla);两者组合在终态 Holdout 上不优于纯 Dueling,原因是 Double DQN 的加速效应改变了训练动态,使峰值出现更早但稳定区间更短。
|
| 943 |
|
| 944 |
---
|
| 945 |
|
|
|
|
| 954 |
|
| 955 |
**vanilla 的 19pp Gap 解读**:
|
| 956 |
|
| 957 |
+
vanilla 是本组唯一 EVAL 峰值(94%)远高于其他算法但 Holdout 最低(75%)的算法,Gap 高达 19pp,是其他算法的 2–3 倍。两个可能原因:
|
| 958 |
|
| 959 |
+
1. **EVAL 集结构性偏差**:EVAL 集由 `seed+100000` 派生固定生成(50 张,全程恒定),94% 是 vanilla 在这批地图上的真实性能,但这批地图对 vanilla 的特定决策边界恰好较友好——属于固定 EVAL 集对特定算法的结构性偏差
|
| 960 |
+
2. **训练晚期策略退化**:vanilla 无 V/A 分解,Q(s,a) 需逐一精确估计,训练末段(ep=4500+)的 buffer 回放可能已不能支持持续更新,导致 Holdout 泛化大幅缩水
|
| 961 |
|
| 962 |
**dueling 的 6pp Gap 解读**:
|
| 963 |
|
| 964 |
+
Dueling 的真正泛化优势在 V(s) 流的**参数共享机制**(上节已述),每次梯度更新 V(s) 获得所有动作的梯度信号(4 倍更新频率),学习更充分。V(s) 学习的"靠近目标的状态价值更高"这一规律不依赖特定障碍布局,在任意地图上均成立,泛化最稳定。
|
| 965 |
|
| 966 |
+
---
|
| 967 |
+
|
| 968 |
+
### 循环失败率 R3 / R4 对照(验证 4 通道的实际效果)
|
| 969 |
+
|
| 970 |
+
R3 节已记录"循环是 R3 失败主因"的数据(25/25 失败局为步数=200 截断且撞墙=0)。R4 训练完成后用相同方法(Holdout 100 局,ε=0 推理)回访测量:
|
| 971 |
+
|
| 972 |
+
| 分类 | R3 (double, 3通道) | R4 (double, 4通道) |
|
| 973 |
+
|------|-------------------:|-------------------:|
|
| 974 |
+
| 快速成功(≤30 步) | 75 | 78 |
|
| 975 |
+
| 失败·截断(步数=200) | **25** | **22** |
|
| 976 |
+
| 其他(中间步数失败/慢成功) | 0 | 0 |
|
| 977 |
+
| 成功率 | 75% | 78% |
|
| 978 |
+
| **失败局中截断占比** | **100%** | **100%** |
|
| 979 |
+
| 失败局平均撞墙数 | 0.0 | 0.0 |
|
| 980 |
+
|
| 981 |
+
**结论**:
|
| 982 |
+
- 截断数 25 → 22(−3pp,n=100 下 σ≈4.3pp,**不具统计显著性**)
|
| 983 |
+
- **但截断率 100% 这一失败模式结构未变**——4 通道减少了陷入循环的地图数量,循环机制本身仍是 R4 失败主因
|
| 984 |
+
- R3 → R4 成功率 +3pp 全部来自"减少了循环地图数",**而非消除了循环机制**
|
| 985 |
+
- 因此 Web Demo 仍需 anti-loop 兜底——网络能避开大部分循环地图,但对剩余的循环地图仍无能为力
|
| 986 |
|
| 987 |
---
|
| 988 |
|
|
|
|
| 1000 |
| R4-A3 (double) | EVAL checkpoint + BFS + visited_map | 78% | EVAL→Holdout gap 10pp 持续(算法限制) |
|
| 1001 |
| **R4 dueling** | 同 A3 超参 + Dueling 架构 | **84%** | **EVAL→Holdout gap 仅 6pp(最优泛化)** |
|
| 1002 |
| R4 double_dueling | 同上 + Double DQN | 81% | 收敛快但末段稳定性略低 |
|
| 1003 |
+
| R4 vanilla | 同上,无增强 | 75% | 94% 仅在固定 50 张 EVAL 集上成立,真实泛化最弱 |
|
| 1004 |
|
| 1005 |
**最终结论(五点)**:
|
| 1006 |
|
| 1007 |
+
1. **Dueling 架构是本任务的最优选择**:V(s)/A(s,a) 分解与本任务结构(大量多动作等效状态)高度吻合,Holdout 84%(+10pp vs R3),EVAL→Holdout gap 6pp(最小)。R3→R4(double) 的 +4pp 是 P7+P8+visited_map 三项叠加(见结论4),R4(double)→R4(dueling) 的 +6pp 是 Dueling 的独立贡献(控制其他变量不变)。
|
|
|
|
|
|
|
| 1008 |
|
| 1009 |
+
2. **Double DQN 主要收益在训练过程,非最终结果**:危机期加速恢复(ep=700 领先 dueling 48pp)和早期收敛加速是真实收益;5000 ep 充分训练后,与纯 dueling 的 Holdout 差距(81% vs 84%)表明 Double DQN 抗高估机制在本任务规模下已不是瓶颈。
|
| 1010 |
|
| 1011 |
+
3. **EVAL→Holdout gap 是算法质量的独立指标**:dueling 6pp、double_dueling 9pp、double 10pp、vanilla 19pp,与架构泛化能力排序一致,可作为独立于 Holdout 成功率的泛化质量指标。
|
| 1012 |
|
| 1013 |
+
4. **P7(EVAL-based checkpoint)是高性价比修复,但单项贡献未严格消融**:R4-A2(仅 visited_map,无 P7)Holdout=75% 仅 +1pp(不显著),间接说明 P7 是三项中单项收益最大者;严格证明需补做 3通道+EVAL checkpoint+BFS 对照组。
|
| 1014 |
|
| 1015 |
+
5. **P9(马尔可夫性违反)是硬约束**:任何将 episode 历史信息置于奖励函数中的循环抑制方案均导致 Q 函数目标无意义,正确解决方案唯有状态编码(visited_map)。
|
| 1016 |
|
| 1017 |
---
|
| 1018 |
|
|
@@ -113,10 +113,10 @@ Step 级 warmup 可能在一局中途切换为学习模式,导致同一局内
|
|
| 113 |
|
| 114 |
### 4.3 Grid-SPL(Anderson et al. 2018 变体)
|
| 115 |
|
| 116 |
-
$$\
|
| 117 |
|
| 118 |
- $S_i$:第 i 局成功标志(0/1)
|
| 119 |
-
- $\ell^
|
| 120 |
- $p_i$:Agent **实际移动步数**(排除撞墙步,见下方说明)
|
| 121 |
|
| 122 |
失败局整项贡献 0,同时惩罚绕路行为,比纯成功率更严格。
|
|
|
|
| 113 |
|
| 114 |
### 4.3 Grid-SPL(Anderson et al. 2018 变体)
|
| 115 |
|
| 116 |
+
$$\mathrm{SPL} = \frac{1}{N} \sum_{i=1}^{N} S_i \cdot \frac{\ell^*_i}{\max(\ell^*_i, p_i)}$$
|
| 117 |
|
| 118 |
- $S_i$:第 i 局成功标志(0/1)
|
| 119 |
+
- $\ell^*_i$:BFS 最短路径步数
|
| 120 |
- $p_i$:Agent **实际移动步数**(排除撞墙步,见下方说明)
|
| 121 |
|
| 122 |
失败局整项贡献 0,同时惩罚绕路行为,比纯成功率更严格。
|