helen9975 commited on
Commit
c4db2b9
·
verified ·
1 Parent(s): b375dc9

README: correct root cause (dynamics NMSE ~0.85 at aug onset), add three tuning arms

Browse files
Files changed (1) hide show
  1. README.md +58 -11
README.md CHANGED
@@ -39,8 +39,14 @@ in the e2e arm the spread between 1st and 5th place in the top-k heap is ~7%.
39
  | path | arm | best epoch | val action MSE |
40
  |---|---|---|---|
41
  | `baseline/` | BC baseline | 60 | **0.003426** |
42
- | `seq_be/` | sequential CCIL (backward-Euler aug) | 10 | 0.003440 |
43
  | `e2e/` | end-to-end CCIL | 10 | 0.003215 |
 
 
 
 
 
 
44
 
45
  Each directory holds `*_best.pt`, `val_top_k.json` (the full top-k selection
46
  record), and where available the hydra `overrides.yaml`.
@@ -88,16 +94,57 @@ than halved (0.0239 -> 0.0112) — an overfitting signature on 44 training
88
  episodes. `final_epoch300.pt` is included alongside `best.pt` so the gap between
89
  last-epoch and val-selected weights is inspectable.
90
 
91
- Measured causes, from the run's own diagnostics: the internal dynamics head
92
- under-predicts the latent displacement (`delta_pred_norm/delta_norm` peaks at
93
- 0.645), so backward-Euler augmented states sit too close to the expert states;
94
- the relative-quality mask keeps exactly the least-displaced 50% by construction,
95
- which selects *against* novelty; and `loss_normalization=adaptive` rescales the
96
- augmentation loss to ~1.0 regardless of how uninformative it is, giving those
97
- near-duplicates the same gradient weight as real data. Three of the advertised
98
- quality gates are inert in this code path: `aug_cycle_threshold` (its
99
- `cycle_error_mean` is assigned to zero and never computed), `aug_hardness_min`
100
- (`hard_ratio` is hardcoded to 1.0), and the mask's fixed 50% quantile.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
 
102
  ## Reproducing
103
 
 
39
  | path | arm | best epoch | val action MSE |
40
  |---|---|---|---|
41
  | `baseline/` | BC baseline | 60 | **0.003426** |
42
+ | `seq_be/` | sequential CCIL, clean dynamics | 10 | 0.003401 |
43
  | `e2e/` | end-to-end CCIL | 10 | 0.003215 |
44
+ | `e2e_fix_stepscale/` | e2e, `aug_step_scale=1.6` | 10 | 0.003260 |
45
+ | `e2e_fix_lossweight/` | e2e, `loss_normalization=fixed`, `lambda_aug=0.3` | 10 | 0.003258 |
46
+ | `e2e_fix_combined/` | e2e, all of the above + `aug_q_threshold=0.8`, `phase1=120` | 10 | 0.003258 |
47
+
48
+ Every arm carries `*_best.pt` (validation-selected) **and** `final_epoch300.pt`
49
+ (last epoch). They differ: best is typically epoch 10, final is epoch 300.
50
 
51
  Each directory holds `*_best.pt`, `val_top_k.json` (the full top-k selection
52
  record), and where available the hydra `overrides.yaml`.
 
94
  episodes. `final_epoch300.pt` is included alongside `best.pt` so the gap between
95
  last-epoch and val-selected weights is inspectable.
96
 
97
+ ### Why augmentation never helped — the measured cause
98
+
99
+ **The latent dynamics head barely models the dynamics.** `fwd_image_nmse` is the
100
+ normalized one-step prediction error, where **1.0 means no better than predicting
101
+ "no change"**:
102
+
103
+ | epoch | 10 | 50 | 100 | 150 | 200 | 299 |
104
+ |---|---|---|---|---|---|---|
105
+ | e2e | 0.968 | **0.852** | 0.779 | 0.696 | 0.631 | 0.549 |
106
+
107
+ At epoch 50, when augmentation switches on, the head explains roughly **15% of
108
+ the latent displacement variance**; even after 300 epochs it reaches only ~45%.
109
+ Backward-Euler synthesizes `z_g = z_prev - step * fwd_head(z_prev, a_t)` and then
110
+ trains the policy to emit `a_t` at `z_g`. When `fwd_head` is that wrong, `z_g` is
111
+ largely noise and the policy is taught incorrect state-action associations. CCIL
112
+ assumes the dynamics model is good enough to place a corrective label; on 44
113
+ training episodes in a 6921-dim latent space, it is not.
114
+
115
+ **Three tuning arms confirm this and rule out hyperparameters as the cause.**
116
+ Each was run for a full 300 epochs from the same baseline checkpoint:
117
+
118
+ | arm | best | top-5 epochs | post-augmentation checkpoints in top-5 |
119
+ |---|---|---|---|
120
+ | original | 0.003215 | 10, 150, 50, 140, 160 | 150, 140, 160 |
121
+ | stepscale | 0.003260 | 10, 20, 40, 50, 30 | **none** |
122
+ | lossweight | 0.003258 | 10, 20, 40, 50, 30 | **none** |
123
+ | combined | 0.003258 | 10, 20, 40, 50, 70 | **none** |
124
+
125
+ The arm with the *weakest* augmentation — the original — is the only one whose
126
+ post-augmentation checkpoints placed at all. Correcting the displacement
127
+ (`aug_step_scale=1.6`, bringing effective displacement from 0.645 to ~0.98 of
128
+ true), relaxing the mask (`aug_q_threshold=0.8`, verified: `mask_ratio` 0.500 ->
129
+ 0.797), reducing the augmentation weight, and delaying warmup to epoch 120 each
130
+ made post-augmentation checkpoints *less* competitive, not more. Amplifying a
131
+ mostly-wrong displacement amplifies the error.
132
+
133
+ Meanwhile training BC loss more than halved in every arm — the policy is
134
+ overfitting 44 episodes, and augmentation does not counteract it.
135
+
136
+ **Secondary issues, real but downstream.** Three advertised quality gates are
137
+ inert in this code path: `aug_cycle_threshold` (its `cycle_error_mean` is
138
+ assigned to zero and never computed), `aug_hardness_min` (`hard_ratio` is
139
+ hardcoded to 1.0), and the mask's quantile filter, which keeps exactly 50% by
140
+ construction regardless of absolute quality — and since `label_err` *is* the
141
+ novelty metric, it keeps the **least**-displaced half, selecting against novelty.
142
+ Worth fixing, but they are not why the method fails here.
143
+
144
+ **What would actually change the result:** gate augmentation on measured
145
+ `fwd_image_nmse` rather than an epoch count (e.g. require < 0.3), and give the
146
+ dynamics head materially more data. A 100-episode session exists and is being
147
+ evaluated separately.
148
 
149
  ## Reproducing
150