Reinforcement Learning (Actor Critic)
#18
by odunbar - opened
- .cache/known_methods_snapshot.json +63 -13
- .claude/skills/leaderboard-manager/references/add-method.md +1 -1
- .claude/skills/leaderboard-manager/references/populate-metadata.md +1 -1
- CLAUDE.md +25 -14
- data/rl-ddpg/leaderboard_rl-ddpg-long_l63_2026-10-04.nc +3 -0
- data/rl-ddpg/leaderboard_rl-ddpg-long_l96_const-force_2026-10-04.nc +3 -0
- data/rl-ddpg/leaderboard_rl-ddpg-long_l96_flux-force_2026-10-04.nc +3 -0
- data/rl-ddpg/leaderboard_rl-ddpg-long_l96_vec-force_2026-10-04.nc +3 -0
- data/rl-ddpg/leaderboard_rl-ddpg-short_l63_2026-10-04.nc +3 -0
- data/rl-ddpg/leaderboard_rl-ddpg-short_l96_const-force_2026-10-04.nc +3 -0
- data/rl-ddpg/leaderboard_rl-ddpg-short_l96_flux-force_2026-10-04.nc +3 -0
- data/rl-ddpg/leaderboard_rl-ddpg-short_l96_vec-force_2026-10-04.nc +3 -0
- data/rl-td3/leaderboard_rl-td3-long_l63_2026-10-04.nc +3 -0
- data/rl-td3/leaderboard_rl-td3-long_l96_const-force_2026-10-04.nc +3 -0
- data/rl-td3/leaderboard_rl-td3-long_l96_flux-force_2026-10-04.nc +3 -0
- data/rl-td3/leaderboard_rl-td3-long_l96_vec-force_2026-10-04.nc +3 -0
- data/rl-td3/leaderboard_rl-td3-short_l63_2026-10-04.nc +3 -0
- data/rl-td3/leaderboard_rl-td3-short_l96_const-force_2026-10-04.nc +3 -0
- data/rl-td3/leaderboard_rl-td3-short_l96_flux-force_2026-10-04.nc +3 -0
- data/rl-td3/leaderboard_rl-td3-short_l96_vec-force_2026-10-04.nc +3 -0
- src/common/leaderboard.py +12 -5
- src/common/method_registry.py +58 -16
- src/data_store.py +16 -0
- src/pages/MethodDetails.py +172 -0
- src/streamlit_app.py +5 -4
.cache/known_methods_snapshot.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
| 4 |
"abbreviation": "TEKI",
|
| 5 |
"Method": "Tikhonov Regularized Ensemble Kalman Inversion",
|
| 6 |
"parallelism": "parallel-interacting",
|
| 7 |
-
"update_type": "
|
| 8 |
"method_goal": "optimization",
|
| 9 |
"emulator_use": "none",
|
| 10 |
"aliases": [
|
|
@@ -15,7 +15,7 @@
|
|
| 15 |
"abbreviation": "ETKI",
|
| 16 |
"Method": "Ensemble Transform Kalman Inversion",
|
| 17 |
"parallelism": "parallel-interacting",
|
| 18 |
-
"update_type": "
|
| 19 |
"method_goal": "optimization",
|
| 20 |
"emulator_use": "none",
|
| 21 |
"aliases": [
|
|
@@ -26,7 +26,7 @@
|
|
| 26 |
"abbreviation": "IEKF",
|
| 27 |
"Method": "Iterative Ensemble Kalman Filter",
|
| 28 |
"parallelism": "parallel-interacting",
|
| 29 |
-
"update_type": "
|
| 30 |
"method_goal": "uq",
|
| 31 |
"emulator_use": "none",
|
| 32 |
"aliases": [
|
|
@@ -39,7 +39,7 @@
|
|
| 39 |
"abbreviation": "UKI",
|
| 40 |
"Method": "Unscented Kalman Inversion",
|
| 41 |
"parallelism": "parallel-interacting",
|
| 42 |
-
"update_type": "
|
| 43 |
"method_goal": "optimization",
|
| 44 |
"emulator_use": "none",
|
| 45 |
"aliases": [
|
|
@@ -72,7 +72,7 @@
|
|
| 72 |
"abbreviation": "CES-EKI-DMC",
|
| 73 |
"Method": "Calibrate Emulate Sample (EKI-DataMisfitController)",
|
| 74 |
"parallelism": "parallel-interacting",
|
| 75 |
-
"update_type": "
|
| 76 |
"method_goal": "uq",
|
| 77 |
"emulator_use": "after-optimize",
|
| 78 |
"aliases": [
|
|
@@ -83,7 +83,7 @@
|
|
| 83 |
"abbreviation": "CES-EKI-CONST",
|
| 84 |
"Method": "Calibrate Emulate Sample (EKI-Constant Scheduler)",
|
| 85 |
"parallelism": "parallel-interacting",
|
| 86 |
-
"update_type": "
|
| 87 |
"method_goal": "uq",
|
| 88 |
"emulator_use": "after-optimize",
|
| 89 |
"aliases": [
|
|
@@ -94,7 +94,7 @@
|
|
| 94 |
"abbreviation": "CES-IEKF-CONST",
|
| 95 |
"Method": "Calibrate Emulate Sample (IEKF-Constant Scheduler)",
|
| 96 |
"parallelism": "parallel-interacting",
|
| 97 |
-
"update_type": "
|
| 98 |
"method_goal": "uq",
|
| 99 |
"emulator_use": "after-optimize",
|
| 100 |
"aliases": [
|
|
@@ -105,7 +105,7 @@
|
|
| 105 |
"abbreviation": "ADAM",
|
| 106 |
"Method": "Adaptive Moment Estimation",
|
| 107 |
"parallelism": "serial",
|
| 108 |
-
"update_type": "gradient",
|
| 109 |
"method_goal": "optimization",
|
| 110 |
"emulator_use": "none",
|
| 111 |
"aliases": [
|
|
@@ -116,7 +116,7 @@
|
|
| 116 |
"abbreviation": "LM",
|
| 117 |
"Method": "Levenberg-Marquardt",
|
| 118 |
"parallelism": "serial",
|
| 119 |
-
"update_type": "gradient",
|
| 120 |
"method_goal": "optimization",
|
| 121 |
"emulator_use": "none",
|
| 122 |
"aliases": [
|
|
@@ -142,7 +142,7 @@
|
|
| 142 |
"abbreviation": "LM-KGMM",
|
| 143 |
"Method": "Score-based Levenberg-Marquardt (KGMM)",
|
| 144 |
"parallelism": "serial",
|
| 145 |
-
"update_type": "gradient",
|
| 146 |
"method_goal": "optimization",
|
| 147 |
"emulator_use": "none",
|
| 148 |
"aliases": [
|
|
@@ -155,7 +155,7 @@
|
|
| 155 |
"abbreviation": "LM-DSM",
|
| 156 |
"Method": "Score-based Levenberg-Marquardt (DSM)",
|
| 157 |
"parallelism": "serial",
|
| 158 |
-
"update_type": "gradient",
|
| 159 |
"method_goal": "optimization",
|
| 160 |
"emulator_use": "none",
|
| 161 |
"aliases": [
|
|
@@ -168,7 +168,7 @@
|
|
| 168 |
"abbreviation": "ADAM-KGMM",
|
| 169 |
"Method": "Score-based Adam (KGMM)",
|
| 170 |
"parallelism": "serial",
|
| 171 |
-
"update_type": "gradient",
|
| 172 |
"method_goal": "optimization",
|
| 173 |
"emulator_use": "none",
|
| 174 |
"aliases": [
|
|
@@ -181,7 +181,7 @@
|
|
| 181 |
"abbreviation": "ADAM-DSM",
|
| 182 |
"Method": "Score-based Adam (DSM)",
|
| 183 |
"parallelism": "serial",
|
| 184 |
-
"update_type": "gradient",
|
| 185 |
"method_goal": "optimization",
|
| 186 |
"emulator_use": "none",
|
| 187 |
"aliases": [
|
|
@@ -189,6 +189,52 @@
|
|
| 189 |
"score-based adam (gfdt, dsm) (extended window)",
|
| 190 |
"score-based adam (gfdt, dsm) (parallel branches)"
|
| 191 |
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 192 |
}
|
| 193 |
},
|
| 194 |
"observed_methods": [
|
|
@@ -200,6 +246,10 @@
|
|
| 200 |
"lm",
|
| 201 |
"lm-dsm",
|
| 202 |
"lm-kgmm",
|
|
|
|
|
|
|
|
|
|
|
|
|
| 203 |
"teki",
|
| 204 |
"uki"
|
| 205 |
],
|
|
|
|
| 4 |
"abbreviation": "TEKI",
|
| 5 |
"Method": "Tikhonov Regularized Ensemble Kalman Inversion",
|
| 6 |
"parallelism": "parallel-interacting",
|
| 7 |
+
"update_type": "gradient (Kalman)",
|
| 8 |
"method_goal": "optimization",
|
| 9 |
"emulator_use": "none",
|
| 10 |
"aliases": [
|
|
|
|
| 15 |
"abbreviation": "ETKI",
|
| 16 |
"Method": "Ensemble Transform Kalman Inversion",
|
| 17 |
"parallelism": "parallel-interacting",
|
| 18 |
+
"update_type": "gradient (Kalman)",
|
| 19 |
"method_goal": "optimization",
|
| 20 |
"emulator_use": "none",
|
| 21 |
"aliases": [
|
|
|
|
| 26 |
"abbreviation": "IEKF",
|
| 27 |
"Method": "Iterative Ensemble Kalman Filter",
|
| 28 |
"parallelism": "parallel-interacting",
|
| 29 |
+
"update_type": "gradient (Kalman)",
|
| 30 |
"method_goal": "uq",
|
| 31 |
"emulator_use": "none",
|
| 32 |
"aliases": [
|
|
|
|
| 39 |
"abbreviation": "UKI",
|
| 40 |
"Method": "Unscented Kalman Inversion",
|
| 41 |
"parallelism": "parallel-interacting",
|
| 42 |
+
"update_type": "gradient (Kalman)",
|
| 43 |
"method_goal": "optimization",
|
| 44 |
"emulator_use": "none",
|
| 45 |
"aliases": [
|
|
|
|
| 72 |
"abbreviation": "CES-EKI-DMC",
|
| 73 |
"Method": "Calibrate Emulate Sample (EKI-DataMisfitController)",
|
| 74 |
"parallelism": "parallel-interacting",
|
| 75 |
+
"update_type": "gradient (Kalman)",
|
| 76 |
"method_goal": "uq",
|
| 77 |
"emulator_use": "after-optimize",
|
| 78 |
"aliases": [
|
|
|
|
| 83 |
"abbreviation": "CES-EKI-CONST",
|
| 84 |
"Method": "Calibrate Emulate Sample (EKI-Constant Scheduler)",
|
| 85 |
"parallelism": "parallel-interacting",
|
| 86 |
+
"update_type": "gradient (Kalman)",
|
| 87 |
"method_goal": "uq",
|
| 88 |
"emulator_use": "after-optimize",
|
| 89 |
"aliases": [
|
|
|
|
| 94 |
"abbreviation": "CES-IEKF-CONST",
|
| 95 |
"Method": "Calibrate Emulate Sample (IEKF-Constant Scheduler)",
|
| 96 |
"parallelism": "parallel-interacting",
|
| 97 |
+
"update_type": "gradient (Kalman)",
|
| 98 |
"method_goal": "uq",
|
| 99 |
"emulator_use": "after-optimize",
|
| 100 |
"aliases": [
|
|
|
|
| 105 |
"abbreviation": "ADAM",
|
| 106 |
"Method": "Adaptive Moment Estimation",
|
| 107 |
"parallelism": "serial",
|
| 108 |
+
"update_type": "gradient (exact)",
|
| 109 |
"method_goal": "optimization",
|
| 110 |
"emulator_use": "none",
|
| 111 |
"aliases": [
|
|
|
|
| 116 |
"abbreviation": "LM",
|
| 117 |
"Method": "Levenberg-Marquardt",
|
| 118 |
"parallelism": "serial",
|
| 119 |
+
"update_type": "gradient (exact)",
|
| 120 |
"method_goal": "optimization",
|
| 121 |
"emulator_use": "none",
|
| 122 |
"aliases": [
|
|
|
|
| 142 |
"abbreviation": "LM-KGMM",
|
| 143 |
"Method": "Score-based Levenberg-Marquardt (KGMM)",
|
| 144 |
"parallelism": "serial",
|
| 145 |
+
"update_type": "gradient (score)",
|
| 146 |
"method_goal": "optimization",
|
| 147 |
"emulator_use": "none",
|
| 148 |
"aliases": [
|
|
|
|
| 155 |
"abbreviation": "LM-DSM",
|
| 156 |
"Method": "Score-based Levenberg-Marquardt (DSM)",
|
| 157 |
"parallelism": "serial",
|
| 158 |
+
"update_type": "gradient (score)",
|
| 159 |
"method_goal": "optimization",
|
| 160 |
"emulator_use": "none",
|
| 161 |
"aliases": [
|
|
|
|
| 168 |
"abbreviation": "ADAM-KGMM",
|
| 169 |
"Method": "Score-based Adam (KGMM)",
|
| 170 |
"parallelism": "serial",
|
| 171 |
+
"update_type": "gradient (score)",
|
| 172 |
"method_goal": "optimization",
|
| 173 |
"emulator_use": "none",
|
| 174 |
"aliases": [
|
|
|
|
| 181 |
"abbreviation": "ADAM-DSM",
|
| 182 |
"Method": "Score-based Adam (DSM)",
|
| 183 |
"parallelism": "serial",
|
| 184 |
+
"update_type": "gradient (score)",
|
| 185 |
"method_goal": "optimization",
|
| 186 |
"emulator_use": "none",
|
| 187 |
"aliases": [
|
|
|
|
| 189 |
"score-based adam (gfdt, dsm) (extended window)",
|
| 190 |
"score-based adam (gfdt, dsm) (parallel branches)"
|
| 191 |
]
|
| 192 |
+
},
|
| 193 |
+
"rl-ddpg-short": {
|
| 194 |
+
"abbreviation": "RL-DDPG-SHORT",
|
| 195 |
+
"Method": "Reinforcement Learning (DDPG, short RL step)",
|
| 196 |
+
"parallelism": "serial",
|
| 197 |
+
"update_type": "gradient (score)",
|
| 198 |
+
"method_goal": "optimization",
|
| 199 |
+
"emulator_use": "none",
|
| 200 |
+
"aliases": [
|
| 201 |
+
"rl-ddpg-short"
|
| 202 |
+
]
|
| 203 |
+
},
|
| 204 |
+
"rl-ddpg": {
|
| 205 |
+
"abbreviation": "RL-DDPG",
|
| 206 |
+
"Method": "Reinforcement Learning (DDPG)",
|
| 207 |
+
"parallelism": "serial",
|
| 208 |
+
"update_type": "gradient (score)",
|
| 209 |
+
"method_goal": "optimization",
|
| 210 |
+
"emulator_use": "none",
|
| 211 |
+
"aliases": [
|
| 212 |
+
"rl-ddpg",
|
| 213 |
+
"rl-ddpg-long"
|
| 214 |
+
]
|
| 215 |
+
},
|
| 216 |
+
"rl-td3-short": {
|
| 217 |
+
"abbreviation": "RL-TD3-SHORT",
|
| 218 |
+
"Method": "Reinforcement Learning (TD3, short RL step)",
|
| 219 |
+
"parallelism": "serial",
|
| 220 |
+
"update_type": "gradient (score)",
|
| 221 |
+
"method_goal": "optimization",
|
| 222 |
+
"emulator_use": "none",
|
| 223 |
+
"aliases": [
|
| 224 |
+
"rl-td3-short"
|
| 225 |
+
]
|
| 226 |
+
},
|
| 227 |
+
"rl-td3": {
|
| 228 |
+
"abbreviation": "RL-TD3",
|
| 229 |
+
"Method": "Reinforcement Learning (TD3)",
|
| 230 |
+
"parallelism": "serial",
|
| 231 |
+
"update_type": "gradient (score)",
|
| 232 |
+
"method_goal": "optimization",
|
| 233 |
+
"emulator_use": "none",
|
| 234 |
+
"aliases": [
|
| 235 |
+
"rl-td3",
|
| 236 |
+
"rl-td3-long"
|
| 237 |
+
]
|
| 238 |
}
|
| 239 |
},
|
| 240 |
"observed_methods": [
|
|
|
|
| 246 |
"lm",
|
| 247 |
"lm-dsm",
|
| 248 |
"lm-kgmm",
|
| 249 |
+
"rl-ddpg",
|
| 250 |
+
"rl-ddpg-short",
|
| 251 |
+
"rl-td3",
|
| 252 |
+
"rl-td3-short",
|
| 253 |
"teki",
|
| 254 |
"uki"
|
| 255 |
],
|
.claude/skills/leaderboard-manager/references/add-method.md
CHANGED
|
@@ -45,7 +45,7 @@ at line 7). Follow the existing pattern exactly:
|
|
| 45 |
"abbreviation": "NEWABBR", # Short uppercase display name
|
| 46 |
"Method": "Full Method Name", # Human-readable name for tables
|
| 47 |
"parallelism": "parallel-interacting", # serial | parallel-independent | parallel-interacting
|
| 48 |
-
"update_type": "
|
| 49 |
"method_goal": "optimization", # optimization | uq
|
| 50 |
"emulator_use": "none", # none | within-optimize | after-optimize
|
| 51 |
"aliases": ["new-key", "alias2"], # All raw strings that may appear in NetCDF algorithm_type
|
|
|
|
| 45 |
"abbreviation": "NEWABBR", # Short uppercase display name
|
| 46 |
"Method": "Full Method Name", # Human-readable name for tables
|
| 47 |
"parallelism": "parallel-interacting", # serial | parallel-independent | parallel-interacting
|
| 48 |
+
"update_type": "gradient (Kalman)", # gradient (exact) | gradient (Kalman) | gradient (score) | general
|
| 49 |
"method_goal": "optimization", # optimization | uq
|
| 50 |
"emulator_use": "none", # none | within-optimize | after-optimize
|
| 51 |
"aliases": ["new-key", "alias2"], # All raw strings that may appear in NetCDF algorithm_type
|
.claude/skills/leaderboard-manager/references/populate-metadata.md
CHANGED
|
@@ -114,7 +114,7 @@ short label that appears in table columns), edit `KNOWN_METHODS` in
|
|
| 114 |
"abbreviation": "UKI", # Short label in table columns
|
| 115 |
"Method": "Unscented Kalman Inversion", # Full name in Method column
|
| 116 |
"parallelism": "parallel-interacting", # serial | parallel-independent | parallel-interacting
|
| 117 |
-
"update_type": "
|
| 118 |
"method_goal": "optimization", # optimization | uq
|
| 119 |
"emulator_use": "none", # none | within-optimize | after-optimize
|
| 120 |
"aliases": ["uki"], # Raw algorithm_type strings from NetCDF
|
|
|
|
| 114 |
"abbreviation": "UKI", # Short label in table columns
|
| 115 |
"Method": "Unscented Kalman Inversion", # Full name in Method column
|
| 116 |
"parallelism": "parallel-interacting", # serial | parallel-independent | parallel-interacting
|
| 117 |
+
"update_type": "gradient (Kalman)", # gradient (exact) | gradient (Kalman) | gradient (score) | general
|
| 118 |
"method_goal": "optimization", # optimization | uq
|
| 119 |
"emulator_use": "none", # none | within-optimize | after-optimize
|
| 120 |
"aliases": ["uki"], # Raw algorithm_type strings from NetCDF
|
CLAUDE.md
CHANGED
|
@@ -78,6 +78,8 @@ calibration_benchmark/
|
|
| 78 |
│ ├── opt_dsm_score_lm/ Score-based LM (DSM score estimator) results (per-benchmark files)
|
| 79 |
│ ├── opt_kgmm_score_adam/ Score-based ADAM (KGMM score estimator) results (per-benchmark files)
|
| 80 |
│ ├── opt_dsm_score_adam/ Score-based ADAM (DSM score estimator) results (per-benchmark files)
|
|
|
|
|
|
|
| 81 |
│ ├── ces-eki-dmc_results/ CES-EKI-DMC ensemble-results files (UQ source)
|
| 82 |
│ ├── gboed-uq_results/ GBOED ensemble-results files (UQ source)
|
| 83 |
│ ├── gnki-uq_results/ IEKF (a.k.a GNKI) ensemble-results files (UQ source)
|
|
@@ -161,13 +163,18 @@ Four independent tags on every `KNOWN_METHODS` entry, each scoped to its own axi
|
|
| 161 |
|
| 162 |
- **`parallelism`** — how the search explores parameter space:
|
| 163 |
`serial` (single point estimate advanced step by step, e.g. `ADAM`/`LM`) ·
|
|
|
|
|
|
|
| 164 |
`parallel-independent` (population updated with no coupling between members,
|
| 165 |
e.g. `ABC`'s accepted samples / `HM`'s per-wave resampling) ·
|
| 166 |
`parallel-interacting` (ensemble members coupled through a shared update each
|
| 167 |
iteration — any Kalman-based method).
|
| 168 |
- **`update_type`** — the mechanism driving each update step:
|
| 169 |
-
`gradient
|
| 170 |
-
|
|
|
|
|
|
|
|
|
|
| 171 |
`general` (anything else, e.g. `ABC`'s rejection sampling, `HM`'s implausibility cuts).
|
| 172 |
- **`method_goal`** — what the method is built to report:
|
| 173 |
`optimization` (single best-fit parameter estimate) or `uq` (full posterior /
|
|
@@ -179,7 +186,7 @@ Four independent tags on every `KNOWN_METHODS` entry, each scoped to its own axi
|
|
| 179 |
`after-optimize` (fits a surrogate once, after calibration finishes, e.g. `CES-EKI-DMC`).
|
| 180 |
|
| 181 |
`update_type` deliberately avoids a "Bayesian" label — Kalman methods are approximate
|
| 182 |
-
Bayesian updates too, so the split is about mechanism (
|
| 183 |
not philosophy. `_UPDATE_TYPE_ORDER` in `src/common/leaderboard.py` controls
|
| 184 |
table/suitability sort order and must stay in sync with `update_type` values.
|
| 185 |
A quick taxonomy tree is rendered on the home page (`src/streamlit_app.py`).
|
|
@@ -188,20 +195,24 @@ A quick taxonomy tree is rendered on the home page (`src/streamlit_app.py`).
|
|
| 188 |
|
| 189 |
| Canonical | Abbreviation | parallelism | update_type | method_goal | emulator_use | Aliases |
|
| 190 |
|---|---|---|---|---|---|---|
|
| 191 |
-
| `teki` | TEKI | parallel-interacting |
|
| 192 |
-
| `etki` | ETKI | parallel-interacting |
|
| 193 |
-
| `iekf` | IEKF | parallel-interacting |
|
| 194 |
-
| `uki` | UKI | parallel-interacting |
|
| 195 |
| `abc` | ABC | parallel-independent | general | uq | none | — |
|
| 196 |
| `hm` | HM | parallel-independent | general | uq | within-optimize | — |
|
| 197 |
-
| `ces-eki-dmc` | CES-EKI-DMC | parallel-interacting |
|
| 198 |
-
| `adam` | ADAM | serial | gradient | optimization | none | — |
|
| 199 |
-
| `lm` | LM | serial | gradient | optimization | none | gradient_descent |
|
| 200 |
| `gboed` | GBOED | parallel-interacting | general | uq | within-optimize | boed |
|
| 201 |
-
| `lm-kgmm` | LM-KGMM | serial | gradient | optimization | none | — |
|
| 202 |
-
| `lm-dsm` | LM-DSM | serial | gradient | optimization | none | — |
|
| 203 |
-
| `adam-kgmm` | ADAM-KGMM | serial | gradient | optimization | none | — |
|
| 204 |
-
| `adam-dsm` | ADAM-DSM | serial | gradient | optimization | none | — |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 205 |
|
| 206 |
## How to extend
|
| 207 |
|
|
|
|
| 78 |
│ ├── opt_dsm_score_lm/ Score-based LM (DSM score estimator) results (per-benchmark files)
|
| 79 |
│ ├── opt_kgmm_score_adam/ Score-based ADAM (KGMM score estimator) results (per-benchmark files)
|
| 80 |
│ ├── opt_dsm_score_adam/ Score-based ADAM (DSM score estimator) results (per-benchmark files)
|
| 81 |
+
│ ├── rl-td3/ RL-TD3-SHORT / RL-TD3 (TD3 variant of the RL experiments; RL-TD3 files are `rl-td3-long` in the NetCDF) results (per-benchmark files)
|
| 82 |
+
│ ├── rl-ddpg/ RL-DDPG-SHORT / RL-DDPG (DDPG actor-critic; short RL step / standard-window RL step; RL-DDPG files are `rl-ddpg-long` in the NetCDF) results (per-benchmark files)
|
| 83 |
│ ├── ces-eki-dmc_results/ CES-EKI-DMC ensemble-results files (UQ source)
|
| 84 |
│ ├── gboed-uq_results/ GBOED ensemble-results files (UQ source)
|
| 85 |
│ ├── gnki-uq_results/ IEKF (a.k.a GNKI) ensemble-results files (UQ source)
|
|
|
|
| 163 |
|
| 164 |
- **`parallelism`** — how the search explores parameter space:
|
| 165 |
`serial` (single point estimate advanced step by step, e.g. `ADAM`/`LM`) ·
|
| 166 |
+
`serial (short window)` (serial, but each step advances a sliding statistics window by a
|
| 167 |
+
fraction of its length rather than a full window, e.g. `RL-DDPG-SHORT`/`RL-TD3-SHORT`) ·
|
| 168 |
`parallel-independent` (population updated with no coupling between members,
|
| 169 |
e.g. `ABC`'s accepted samples / `HM`'s per-wave resampling) ·
|
| 170 |
`parallel-interacting` (ensemble members coupled through a shared update each
|
| 171 |
iteration — any Kalman-based method).
|
| 172 |
- **`update_type`** — the mechanism driving each update step:
|
| 173 |
+
`gradient (exact)` (loss gradient / Gauss-Newton step differentiated through the forward
|
| 174 |
+
model, e.g. `ADAM`/`LM`) ·
|
| 175 |
+
`gradient (Kalman)` (a possibly linearized/unscented Kalman-style ensemble update) ·
|
| 176 |
+
`gradient (score)` (gradient built from an estimated score or learned critic rather than a
|
| 177 |
+
simulator Jacobian, e.g. `*-KGMM`, `*-DSM`, `RL-*`) ·
|
| 178 |
`general` (anything else, e.g. `ABC`'s rejection sampling, `HM`'s implausibility cuts).
|
| 179 |
- **`method_goal`** — what the method is built to report:
|
| 180 |
`optimization` (single best-fit parameter estimate) or `uq` (full posterior /
|
|
|
|
| 186 |
`after-optimize` (fits a surrogate once, after calibration finishes, e.g. `CES-EKI-DMC`).
|
| 187 |
|
| 188 |
`update_type` deliberately avoids a "Bayesian" label — Kalman methods are approximate
|
| 189 |
+
Bayesian updates too, so the split is about mechanism (exact vs. Kalman vs. score gradient vs. general),
|
| 190 |
not philosophy. `_UPDATE_TYPE_ORDER` in `src/common/leaderboard.py` controls
|
| 191 |
table/suitability sort order and must stay in sync with `update_type` values.
|
| 192 |
A quick taxonomy tree is rendered on the home page (`src/streamlit_app.py`).
|
|
|
|
| 195 |
|
| 196 |
| Canonical | Abbreviation | parallelism | update_type | method_goal | emulator_use | Aliases |
|
| 197 |
|---|---|---|---|---|---|---|
|
| 198 |
+
| `teki` | TEKI | parallel-interacting | gradient (Kalman) | optimization | none | — |
|
| 199 |
+
| `etki` | ETKI | parallel-interacting | gradient (Kalman) | optimization | none | — |
|
| 200 |
+
| `iekf` | IEKF | parallel-interacting | gradient (Kalman) | uq | none | gnsl, gnki |
|
| 201 |
+
| `uki` | UKI | parallel-interacting | gradient (Kalman) | optimization | none | — |
|
| 202 |
| `abc` | ABC | parallel-independent | general | uq | none | — |
|
| 203 |
| `hm` | HM | parallel-independent | general | uq | within-optimize | — |
|
| 204 |
+
| `ces-eki-dmc` | CES-EKI-DMC | parallel-interacting | gradient (Kalman) | uq | after-optimize | — |
|
| 205 |
+
| `adam` | ADAM | serial | gradient (exact) | optimization | none | — |
|
| 206 |
+
| `lm` | LM | serial | gradient (exact) | optimization | none | gradient_descent |
|
| 207 |
| `gboed` | GBOED | parallel-interacting | general | uq | within-optimize | boed |
|
| 208 |
+
| `lm-kgmm` | LM-KGMM | serial | gradient (score) | optimization | none | — |
|
| 209 |
+
| `lm-dsm` | LM-DSM | serial | gradient (score) | optimization | none | — |
|
| 210 |
+
| `adam-kgmm` | ADAM-KGMM | serial | gradient (score) | optimization | none | — |
|
| 211 |
+
| `adam-dsm` | ADAM-DSM | serial | gradient (score) | optimization | none | — |
|
| 212 |
+
| `rl-ddpg-short` | RL-DDPG-SHORT | serial (short window) | gradient (score) | optimization | none | — |
|
| 213 |
+
| `rl-ddpg` | RL-DDPG | serial | gradient (score) | optimization | none | rl-ddpg-long |
|
| 214 |
+
| `rl-td3-short` | RL-TD3-SHORT | serial (short window) | gradient (score) | optimization | none | — |
|
| 215 |
+
| `rl-td3` | RL-TD3 | serial | gradient (score) | optimization | none | rl-td3-long |
|
| 216 |
|
| 217 |
## How to extend
|
| 218 |
|
data/rl-ddpg/leaderboard_rl-ddpg-long_l63_2026-10-04.nc
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:75420eb82ea3b59b30f803fc289a85af15869a782bc1d74ff8ed899d6997abce
|
| 3 |
+
size 9200
|
data/rl-ddpg/leaderboard_rl-ddpg-long_l96_const-force_2026-10-04.nc
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:85660a09db96d4486bdfec01c8310b2fa8e888903e930437334f678c2a24f693
|
| 3 |
+
size 9200
|
data/rl-ddpg/leaderboard_rl-ddpg-long_l96_flux-force_2026-10-04.nc
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d541f2a8bb5ed357bd6a47183546f95f243202afc6a47ac64a4c78d5b1ae1b0b
|
| 3 |
+
size 9200
|
data/rl-ddpg/leaderboard_rl-ddpg-long_l96_vec-force_2026-10-04.nc
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d541f2a8bb5ed357bd6a47183546f95f243202afc6a47ac64a4c78d5b1ae1b0b
|
| 3 |
+
size 9200
|
data/rl-ddpg/leaderboard_rl-ddpg-short_l63_2026-10-04.nc
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:68189692e5ecab696cd87030be1fcd94a4c018f6035c2e361924dfa1b1904859
|
| 3 |
+
size 9200
|
data/rl-ddpg/leaderboard_rl-ddpg-short_l96_const-force_2026-10-04.nc
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:7f461cf02963eccb7fefb4d41c0451dd823232b93ae1b5cfa971df9e2ffbd8d9
|
| 3 |
+
size 9200
|
data/rl-ddpg/leaderboard_rl-ddpg-short_l96_flux-force_2026-10-04.nc
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:7cec229bfc4948a5c2ef382fba6b733221f8ef5ea3143e5b72be9c93f833e512
|
| 3 |
+
size 9200
|
data/rl-ddpg/leaderboard_rl-ddpg-short_l96_vec-force_2026-10-04.nc
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:ce5cff4a54bcff60d862a0f8f29d956cc9d6eba230f3469992a71fd6e44a7efa
|
| 3 |
+
size 9200
|
data/rl-td3/leaderboard_rl-td3-long_l63_2026-10-04.nc
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:f546837f79d3f020fa8e8c6f1f97f4aa9543dda0631d8a5b462687ff49793697
|
| 3 |
+
size 9200
|
data/rl-td3/leaderboard_rl-td3-long_l96_const-force_2026-10-04.nc
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:27956dd2b55fe624f191cd1759701d247f6efc09cd833daa5adc1851c6c0c42d
|
| 3 |
+
size 9200
|
data/rl-td3/leaderboard_rl-td3-long_l96_flux-force_2026-10-04.nc
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:0562fc2dc63bc374389772c9ebba5fa7118edb7217e60a04e02a246b671337b0
|
| 3 |
+
size 9200
|
data/rl-td3/leaderboard_rl-td3-long_l96_vec-force_2026-10-04.nc
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:8c51d0d65cdb3abf2f3f095d790a028132039eb2c7c161c5544fc962ba615196
|
| 3 |
+
size 9200
|
data/rl-td3/leaderboard_rl-td3-short_l63_2026-10-04.nc
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:0c33c3864a00e00e57baa9f8d08521c730da84695c0c1139d6ba60e3e2b48d0e
|
| 3 |
+
size 9200
|
data/rl-td3/leaderboard_rl-td3-short_l96_const-force_2026-10-04.nc
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:abd015cc5749e5a2db779756192a4eb1521c01170a69fb551b52b65dedfb71a2
|
| 3 |
+
size 9200
|
data/rl-td3/leaderboard_rl-td3-short_l96_flux-force_2026-10-04.nc
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:599281064f3f993989a9f93c1eb24bb6a1e30dba7c5b900da86ac90ba0d99a1b
|
| 3 |
+
size 9200
|
data/rl-td3/leaderboard_rl-td3-short_l96_vec-force_2026-10-04.nc
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:80282ab8703b8addb2114fde70b5d30934b0e6f5b04260cf092d69eef515f8b9
|
| 3 |
+
size 9200
|
src/common/leaderboard.py
CHANGED
|
@@ -53,9 +53,10 @@ def _method_color(present_abbrevs: list[str]) -> alt.Color:
|
|
| 53 |
# Unknown/unmapped update types fall back to 99 and appear at the end.
|
| 54 |
# See method_registry.py for the full four-axis taxonomy.
|
| 55 |
_UPDATE_TYPE_ORDER: dict[str, int] = {
|
| 56 |
-
"
|
| 57 |
-
"gradient": 1,
|
| 58 |
-
"
|
|
|
|
| 59 |
}
|
| 60 |
|
| 61 |
# Failure-rate threshold (%) below which a method's runs at a given target are
|
|
@@ -119,7 +120,11 @@ def _render_suitability_table(
|
|
| 119 |
continue
|
| 120 |
qualifying = sub[sub["failure_rate"] < failure_threshold].dropna(subset=["metric"])
|
| 121 |
if qualifying.empty:
|
| 122 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 123 |
cell_color[method][bm] = _UNSUITABLE
|
| 124 |
continue
|
| 125 |
method_best = float(qualifying["metric"].min())
|
|
@@ -157,7 +162,9 @@ def _render_suitability_table(
|
|
| 157 |
f"Evaluated at target = {suitability_target}. "
|
| 158 |
f"**Green**: at some ensemble size, failure rate < {failure_threshold:.0f}% "
|
| 159 |
f"and mean budget ≤ {ratio_threshold:.0f}× the best method (ratio shown). "
|
| 160 |
-
"**Red** (failed): data present but
|
|
|
|
|
|
|
| 161 |
"**Gray (—)**: no data for this benchmark."
|
| 162 |
)
|
| 163 |
st.dataframe(
|
|
|
|
| 53 |
# Unknown/unmapped update types fall back to 99 and appear at the end.
|
| 54 |
# See method_registry.py for the full four-axis taxonomy.
|
| 55 |
_UPDATE_TYPE_ORDER: dict[str, int] = {
|
| 56 |
+
"gradient (Kalman)": 0,
|
| 57 |
+
"gradient (exact)": 1,
|
| 58 |
+
"gradient (score)": 2,
|
| 59 |
+
"general": 3,
|
| 60 |
}
|
| 61 |
|
| 62 |
# Failure-rate threshold (%) below which a method's runs at a given target are
|
|
|
|
| 120 |
continue
|
| 121 |
qualifying = sub[sub["failure_rate"] < failure_threshold].dropna(subset=["metric"])
|
| 122 |
if qualifying.empty:
|
| 123 |
+
# Report the best (lowest) failure rate over ensemble sizes
|
| 124 |
+
best_fail = sub["failure_rate"].min()
|
| 125 |
+
cell_text[method][bm] = (
|
| 126 |
+
f"failed ({best_fail:.0f}%)" if pd.notna(best_fail) else "failed"
|
| 127 |
+
)
|
| 128 |
cell_color[method][bm] = _UNSUITABLE
|
| 129 |
continue
|
| 130 |
method_best = float(qualifying["metric"].min())
|
|
|
|
| 162 |
f"Evaluated at target = {suitability_target}. "
|
| 163 |
f"**Green**: at some ensemble size, failure rate < {failure_threshold:.0f}% "
|
| 164 |
f"and mean budget ≤ {ratio_threshold:.0f}× the best method (ratio shown). "
|
| 165 |
+
"**Red** (failed): data present but no ensemble size met the criteria; "
|
| 166 |
+
"the percentage is the lowest failure rate (share of runs that did not reach the target) "
|
| 167 |
+
"across ensemble sizes. "
|
| 168 |
"**Gray (—)**: no data for this benchmark."
|
| 169 |
)
|
| 170 |
st.dataframe(
|
src/common/method_registry.py
CHANGED
|
@@ -10,6 +10,8 @@ from pathlib import Path
|
|
| 10 |
#
|
| 11 |
# ``parallelism`` — how the search explores parameter space:
|
| 12 |
# "serial" — a single point estimate advanced step by step (ADAM, LM).
|
|
|
|
|
|
|
| 13 |
# "parallel-independent" — a population of candidates updated with no coupling
|
| 14 |
# between members (ABC's accepted samples, HM's per-wave
|
| 15 |
# resampling from the non-implausible region).
|
|
@@ -17,9 +19,13 @@ from pathlib import Path
|
|
| 17 |
# update each iteration (any Kalman-based method).
|
| 18 |
#
|
| 19 |
# ``update_type`` — the mechanism driving each update step:
|
| 20 |
-
# "gradient
|
| 21 |
-
#
|
| 22 |
-
# "
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
#
|
| 24 |
# ``method_goal`` — what the method is built to report:
|
| 25 |
# "optimization" — a single best-fit parameter estimate.
|
|
@@ -39,7 +45,7 @@ KNOWN_METHODS = {
|
|
| 39 |
"abbreviation": "TEKI",
|
| 40 |
"Method": "Tikhonov Regularized Ensemble Kalman Inversion",
|
| 41 |
"parallelism": "parallel-interacting",
|
| 42 |
-
"update_type": "
|
| 43 |
"method_goal": "optimization",
|
| 44 |
"emulator_use": "none",
|
| 45 |
"aliases": ["teki"],
|
|
@@ -48,7 +54,7 @@ KNOWN_METHODS = {
|
|
| 48 |
"abbreviation": "ETKI",
|
| 49 |
"Method": "Ensemble Transform Kalman Inversion",
|
| 50 |
"parallelism": "parallel-interacting",
|
| 51 |
-
"update_type": "
|
| 52 |
"method_goal": "optimization",
|
| 53 |
"emulator_use": "none",
|
| 54 |
"aliases": ["etki"],
|
|
@@ -57,7 +63,7 @@ KNOWN_METHODS = {
|
|
| 57 |
"abbreviation": "IEKF",
|
| 58 |
"Method": "Iterative Ensemble Kalman Filter",
|
| 59 |
"parallelism": "parallel-interacting",
|
| 60 |
-
"update_type": "
|
| 61 |
"method_goal": "uq",
|
| 62 |
"emulator_use": "none",
|
| 63 |
"aliases": ["iekf", "gnsl", "gnki"],
|
|
@@ -66,7 +72,7 @@ KNOWN_METHODS = {
|
|
| 66 |
"abbreviation": "UKI",
|
| 67 |
"Method": "Unscented Kalman Inversion",
|
| 68 |
"parallelism": "parallel-interacting",
|
| 69 |
-
"update_type": "
|
| 70 |
"method_goal": "optimization",
|
| 71 |
"emulator_use": "none",
|
| 72 |
"aliases": ["uki"],
|
|
@@ -93,7 +99,7 @@ KNOWN_METHODS = {
|
|
| 93 |
"abbreviation": "CES-EKI-DMC",
|
| 94 |
"Method": "Calibrate Emulate Sample (EKI-DataMisfitController)",
|
| 95 |
"parallelism": "parallel-interacting",
|
| 96 |
-
"update_type": "
|
| 97 |
"method_goal": "uq",
|
| 98 |
"emulator_use": "after-optimize",
|
| 99 |
"aliases": ["ces-eki-dmc"]
|
|
@@ -102,7 +108,7 @@ KNOWN_METHODS = {
|
|
| 102 |
"abbreviation": "CES-EKI-CONST",
|
| 103 |
"Method": "Calibrate Emulate Sample (EKI-Constant Scheduler)",
|
| 104 |
"parallelism": "parallel-interacting",
|
| 105 |
-
"update_type": "
|
| 106 |
"method_goal": "uq",
|
| 107 |
"emulator_use": "after-optimize",
|
| 108 |
"aliases": ["ces-eki-const"]
|
|
@@ -111,7 +117,7 @@ KNOWN_METHODS = {
|
|
| 111 |
"abbreviation": "CES-IEKF-CONST",
|
| 112 |
"Method": "Calibrate Emulate Sample (IEKF-Constant Scheduler)",
|
| 113 |
"parallelism": "parallel-interacting",
|
| 114 |
-
"update_type": "
|
| 115 |
"method_goal": "uq",
|
| 116 |
"emulator_use": "after-optimize",
|
| 117 |
"aliases": ["ces-iekf-const"]
|
|
@@ -120,7 +126,7 @@ KNOWN_METHODS = {
|
|
| 120 |
"abbreviation": "ADAM",
|
| 121 |
"Method": "Adaptive Moment Estimation",
|
| 122 |
"parallelism": "serial",
|
| 123 |
-
"update_type": "gradient",
|
| 124 |
"method_goal": "optimization",
|
| 125 |
"emulator_use": "none",
|
| 126 |
"aliases": ["adam"],
|
|
@@ -129,7 +135,7 @@ KNOWN_METHODS = {
|
|
| 129 |
"abbreviation": "LM",
|
| 130 |
"Method": "Levenberg-Marquardt",
|
| 131 |
"parallelism": "serial",
|
| 132 |
-
"update_type": "gradient",
|
| 133 |
"method_goal": "optimization",
|
| 134 |
"emulator_use": "none",
|
| 135 |
"aliases": ["lm", "levenberg_marquardt", "levenberg-marquardt", "gradient_descent"],
|
|
@@ -147,7 +153,7 @@ KNOWN_METHODS = {
|
|
| 147 |
"abbreviation": "LM-KGMM",
|
| 148 |
"Method": "Score-based Levenberg-Marquardt (KGMM)",
|
| 149 |
"parallelism": "serial",
|
| 150 |
-
"update_type": "gradient",
|
| 151 |
"method_goal": "optimization",
|
| 152 |
"emulator_use": "none",
|
| 153 |
"aliases": [
|
|
@@ -160,7 +166,7 @@ KNOWN_METHODS = {
|
|
| 160 |
"abbreviation": "LM-DSM",
|
| 161 |
"Method": "Score-based Levenberg-Marquardt (DSM)",
|
| 162 |
"parallelism": "serial",
|
| 163 |
-
"update_type": "gradient",
|
| 164 |
"method_goal": "optimization",
|
| 165 |
"emulator_use": "none",
|
| 166 |
"aliases": [
|
|
@@ -173,7 +179,7 @@ KNOWN_METHODS = {
|
|
| 173 |
"abbreviation": "ADAM-KGMM",
|
| 174 |
"Method": "Score-based Adam (KGMM)",
|
| 175 |
"parallelism": "serial",
|
| 176 |
-
"update_type": "gradient",
|
| 177 |
"method_goal": "optimization",
|
| 178 |
"emulator_use": "none",
|
| 179 |
"aliases": [
|
|
@@ -186,7 +192,7 @@ KNOWN_METHODS = {
|
|
| 186 |
"abbreviation": "ADAM-DSM",
|
| 187 |
"Method": "Score-based Adam (DSM)",
|
| 188 |
"parallelism": "serial",
|
| 189 |
-
"update_type": "gradient",
|
| 190 |
"method_goal": "optimization",
|
| 191 |
"emulator_use": "none",
|
| 192 |
"aliases": [
|
|
@@ -195,6 +201,42 @@ KNOWN_METHODS = {
|
|
| 195 |
"score-based adam (gfdt, dsm) (parallel branches)",
|
| 196 |
],
|
| 197 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 198 |
}
|
| 199 |
|
| 200 |
|
|
|
|
| 10 |
#
|
| 11 |
# ``parallelism`` — how the search explores parameter space:
|
| 12 |
# "serial" — a single point estimate advanced step by step (ADAM, LM).
|
| 13 |
+
# "serial (short window)" — serial, but each step advances a sliding statistics window by
|
| 14 |
+
# a fraction of its length (RL-*-SHORT) rather than a full window.
|
| 15 |
# "parallel-independent" — a population of candidates updated with no coupling
|
| 16 |
# between members (ABC's accepted samples, HM's per-wave
|
| 17 |
# resampling from the non-implausible region).
|
|
|
|
| 19 |
# update each iteration (any Kalman-based method).
|
| 20 |
#
|
| 21 |
# ``update_type`` — the mechanism driving each update step:
|
| 22 |
+
# "gradient (exact)" — follows the loss gradient or a Gauss-Newton approximation of it,
|
| 23 |
+
# differentiated through the forward model (ADAM, LM).
|
| 24 |
+
# "gradient (Kalman)" — a (possibly linearized/unscented) Kalman-style ensemble update,
|
| 25 |
+
# i.e. an ensemble-estimated gradient/Gauss-Newton step.
|
| 26 |
+
# "gradient (score)" — a gradient built from a learned/estimated score or critic rather
|
| 27 |
+
# than a simulator Jacobian (*-KGMM, *-DSM, RL-*).
|
| 28 |
+
# "general" — anything else (e.g. ABC's rejection sampling, HM's implausibility cuts).
|
| 29 |
#
|
| 30 |
# ``method_goal`` — what the method is built to report:
|
| 31 |
# "optimization" — a single best-fit parameter estimate.
|
|
|
|
| 45 |
"abbreviation": "TEKI",
|
| 46 |
"Method": "Tikhonov Regularized Ensemble Kalman Inversion",
|
| 47 |
"parallelism": "parallel-interacting",
|
| 48 |
+
"update_type": "gradient (Kalman)",
|
| 49 |
"method_goal": "optimization",
|
| 50 |
"emulator_use": "none",
|
| 51 |
"aliases": ["teki"],
|
|
|
|
| 54 |
"abbreviation": "ETKI",
|
| 55 |
"Method": "Ensemble Transform Kalman Inversion",
|
| 56 |
"parallelism": "parallel-interacting",
|
| 57 |
+
"update_type": "gradient (Kalman)",
|
| 58 |
"method_goal": "optimization",
|
| 59 |
"emulator_use": "none",
|
| 60 |
"aliases": ["etki"],
|
|
|
|
| 63 |
"abbreviation": "IEKF",
|
| 64 |
"Method": "Iterative Ensemble Kalman Filter",
|
| 65 |
"parallelism": "parallel-interacting",
|
| 66 |
+
"update_type": "gradient (Kalman)",
|
| 67 |
"method_goal": "uq",
|
| 68 |
"emulator_use": "none",
|
| 69 |
"aliases": ["iekf", "gnsl", "gnki"],
|
|
|
|
| 72 |
"abbreviation": "UKI",
|
| 73 |
"Method": "Unscented Kalman Inversion",
|
| 74 |
"parallelism": "parallel-interacting",
|
| 75 |
+
"update_type": "gradient (Kalman)",
|
| 76 |
"method_goal": "optimization",
|
| 77 |
"emulator_use": "none",
|
| 78 |
"aliases": ["uki"],
|
|
|
|
| 99 |
"abbreviation": "CES-EKI-DMC",
|
| 100 |
"Method": "Calibrate Emulate Sample (EKI-DataMisfitController)",
|
| 101 |
"parallelism": "parallel-interacting",
|
| 102 |
+
"update_type": "gradient (Kalman)",
|
| 103 |
"method_goal": "uq",
|
| 104 |
"emulator_use": "after-optimize",
|
| 105 |
"aliases": ["ces-eki-dmc"]
|
|
|
|
| 108 |
"abbreviation": "CES-EKI-CONST",
|
| 109 |
"Method": "Calibrate Emulate Sample (EKI-Constant Scheduler)",
|
| 110 |
"parallelism": "parallel-interacting",
|
| 111 |
+
"update_type": "gradient (Kalman)",
|
| 112 |
"method_goal": "uq",
|
| 113 |
"emulator_use": "after-optimize",
|
| 114 |
"aliases": ["ces-eki-const"]
|
|
|
|
| 117 |
"abbreviation": "CES-IEKF-CONST",
|
| 118 |
"Method": "Calibrate Emulate Sample (IEKF-Constant Scheduler)",
|
| 119 |
"parallelism": "parallel-interacting",
|
| 120 |
+
"update_type": "gradient (Kalman)",
|
| 121 |
"method_goal": "uq",
|
| 122 |
"emulator_use": "after-optimize",
|
| 123 |
"aliases": ["ces-iekf-const"]
|
|
|
|
| 126 |
"abbreviation": "ADAM",
|
| 127 |
"Method": "Adaptive Moment Estimation",
|
| 128 |
"parallelism": "serial",
|
| 129 |
+
"update_type": "gradient (exact)",
|
| 130 |
"method_goal": "optimization",
|
| 131 |
"emulator_use": "none",
|
| 132 |
"aliases": ["adam"],
|
|
|
|
| 135 |
"abbreviation": "LM",
|
| 136 |
"Method": "Levenberg-Marquardt",
|
| 137 |
"parallelism": "serial",
|
| 138 |
+
"update_type": "gradient (exact)",
|
| 139 |
"method_goal": "optimization",
|
| 140 |
"emulator_use": "none",
|
| 141 |
"aliases": ["lm", "levenberg_marquardt", "levenberg-marquardt", "gradient_descent"],
|
|
|
|
| 153 |
"abbreviation": "LM-KGMM",
|
| 154 |
"Method": "Score-based Levenberg-Marquardt (KGMM)",
|
| 155 |
"parallelism": "serial",
|
| 156 |
+
"update_type": "gradient (score)",
|
| 157 |
"method_goal": "optimization",
|
| 158 |
"emulator_use": "none",
|
| 159 |
"aliases": [
|
|
|
|
| 166 |
"abbreviation": "LM-DSM",
|
| 167 |
"Method": "Score-based Levenberg-Marquardt (DSM)",
|
| 168 |
"parallelism": "serial",
|
| 169 |
+
"update_type": "gradient (score)",
|
| 170 |
"method_goal": "optimization",
|
| 171 |
"emulator_use": "none",
|
| 172 |
"aliases": [
|
|
|
|
| 179 |
"abbreviation": "ADAM-KGMM",
|
| 180 |
"Method": "Score-based Adam (KGMM)",
|
| 181 |
"parallelism": "serial",
|
| 182 |
+
"update_type": "gradient (score)",
|
| 183 |
"method_goal": "optimization",
|
| 184 |
"emulator_use": "none",
|
| 185 |
"aliases": [
|
|
|
|
| 192 |
"abbreviation": "ADAM-DSM",
|
| 193 |
"Method": "Score-based Adam (DSM)",
|
| 194 |
"parallelism": "serial",
|
| 195 |
+
"update_type": "gradient (score)",
|
| 196 |
"method_goal": "optimization",
|
| 197 |
"emulator_use": "none",
|
| 198 |
"aliases": [
|
|
|
|
| 201 |
"score-based adam (gfdt, dsm) (parallel branches)",
|
| 202 |
],
|
| 203 |
},
|
| 204 |
+
"rl-ddpg-short": {
|
| 205 |
+
"abbreviation": "RL-DDPG-SHORT",
|
| 206 |
+
"Method": "Reinforcement Learning (DDPG, short RL step)",
|
| 207 |
+
"parallelism": "serial (short window)",
|
| 208 |
+
"update_type": "gradient (score)",
|
| 209 |
+
"method_goal": "optimization",
|
| 210 |
+
"emulator_use": "none",
|
| 211 |
+
"aliases": ["rl-ddpg-short"],
|
| 212 |
+
},
|
| 213 |
+
"rl-ddpg": {
|
| 214 |
+
"abbreviation": "RL-DDPG",
|
| 215 |
+
"Method": "Reinforcement Learning (DDPG)",
|
| 216 |
+
"parallelism": "serial",
|
| 217 |
+
"update_type": "gradient (score)",
|
| 218 |
+
"method_goal": "optimization",
|
| 219 |
+
"emulator_use": "none",
|
| 220 |
+
"aliases": ["rl-ddpg", "rl-ddpg-long"],
|
| 221 |
+
},
|
| 222 |
+
"rl-td3-short": {
|
| 223 |
+
"abbreviation": "RL-TD3-SHORT",
|
| 224 |
+
"Method": "Reinforcement Learning (TD3, short RL step)",
|
| 225 |
+
"parallelism": "serial (short window)",
|
| 226 |
+
"update_type": "gradient (score)",
|
| 227 |
+
"method_goal": "optimization",
|
| 228 |
+
"emulator_use": "none",
|
| 229 |
+
"aliases": ["rl-td3-short"],
|
| 230 |
+
},
|
| 231 |
+
"rl-td3": {
|
| 232 |
+
"abbreviation": "RL-TD3",
|
| 233 |
+
"Method": "Reinforcement Learning (TD3)",
|
| 234 |
+
"parallelism": "serial",
|
| 235 |
+
"update_type": "gradient (score)",
|
| 236 |
+
"method_goal": "optimization",
|
| 237 |
+
"emulator_use": "none",
|
| 238 |
+
"aliases": ["rl-td3", "rl-td3-long"],
|
| 239 |
+
},
|
| 240 |
}
|
| 241 |
|
| 242 |
|
src/data_store.py
CHANGED
|
@@ -39,6 +39,10 @@ DATASET_FILES = {
|
|
| 39 |
"opt_dsm_score_lm/leaderboard_sblm_dsm_parallel_l63_2026-08-12.nc",
|
| 40 |
"opt_kgmm_score_adam/leaderboard_sbadam_kgmm_parallel_l63_2026-09-11.nc",
|
| 41 |
"opt_dsm_score_adam/leaderboard_sbadam_dsm_parallel_l63_2026-09-14.nc",
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
],
|
| 43 |
"L96": [
|
| 44 |
"teki_results/leaderboard_teki_l96_const-force_2026-09-10.nc",
|
|
@@ -51,6 +55,10 @@ DATASET_FILES = {
|
|
| 51 |
"opt_dsm_score_lm/leaderboard_sblm_dsm_parallel_l96_const-force_2026-08-12.nc",
|
| 52 |
"opt_kgmm_score_adam/leaderboard_sbadam_kgmm_parallel_l96_const-force_2026-09-11.nc",
|
| 53 |
"opt_dsm_score_adam/leaderboard_sbadam_dsm_parallel_l96_const-force_2026-09-14.nc",
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
],
|
| 55 |
"L96_NN_FORCING": [
|
| 56 |
"teki_results/leaderboard_teki_l96_flux-force_2026-09-10.nc",
|
|
@@ -61,6 +69,10 @@ DATASET_FILES = {
|
|
| 61 |
"opt_dsm_score_lm/leaderboard_sblm_dsm_parallel_l96_flux-force_2026-08-12.nc",
|
| 62 |
"opt_kgmm_score_adam/leaderboard_sbadam_kgmm_parallel_l96_flux-force_2026-09-11.nc",
|
| 63 |
"opt_dsm_score_adam/leaderboard_sbadam_dsm_parallel_l96_flux-force_2026-09-14.nc",
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
],
|
| 65 |
"L96_SPATIAL_FORCING": [
|
| 66 |
"teki_results/leaderboard_teki_l96_vec-force_2026-09-10.nc",
|
|
@@ -73,6 +85,10 @@ DATASET_FILES = {
|
|
| 73 |
"opt_dsm_score_lm/leaderboard_sblm_dsm_parallel_l96_vec-force_2026-08-12.nc",
|
| 74 |
"opt_kgmm_score_adam/leaderboard_sbadam_kgmm_parallel_l96_vec-force_2026-09-11.nc",
|
| 75 |
"opt_dsm_score_adam/leaderboard_sbadam_dsm_parallel_l96_vec-force_2026-09-14.nc",
|
|
|
|
|
|
|
|
|
|
|
|
|
| 76 |
],
|
| 77 |
}
|
| 78 |
|
|
|
|
| 39 |
"opt_dsm_score_lm/leaderboard_sblm_dsm_parallel_l63_2026-08-12.nc",
|
| 40 |
"opt_kgmm_score_adam/leaderboard_sbadam_kgmm_parallel_l63_2026-09-11.nc",
|
| 41 |
"opt_dsm_score_adam/leaderboard_sbadam_dsm_parallel_l63_2026-09-14.nc",
|
| 42 |
+
"rl-ddpg/leaderboard_rl-ddpg-short_l63_2026-10-04.nc",
|
| 43 |
+
"rl-ddpg/leaderboard_rl-ddpg-long_l63_2026-10-04.nc",
|
| 44 |
+
"rl-td3/leaderboard_rl-td3-short_l63_2026-10-04.nc",
|
| 45 |
+
"rl-td3/leaderboard_rl-td3-long_l63_2026-10-04.nc",
|
| 46 |
],
|
| 47 |
"L96": [
|
| 48 |
"teki_results/leaderboard_teki_l96_const-force_2026-09-10.nc",
|
|
|
|
| 55 |
"opt_dsm_score_lm/leaderboard_sblm_dsm_parallel_l96_const-force_2026-08-12.nc",
|
| 56 |
"opt_kgmm_score_adam/leaderboard_sbadam_kgmm_parallel_l96_const-force_2026-09-11.nc",
|
| 57 |
"opt_dsm_score_adam/leaderboard_sbadam_dsm_parallel_l96_const-force_2026-09-14.nc",
|
| 58 |
+
"rl-ddpg/leaderboard_rl-ddpg-short_l96_const-force_2026-10-04.nc",
|
| 59 |
+
"rl-ddpg/leaderboard_rl-ddpg-long_l96_const-force_2026-10-04.nc",
|
| 60 |
+
"rl-td3/leaderboard_rl-td3-short_l96_const-force_2026-10-04.nc",
|
| 61 |
+
"rl-td3/leaderboard_rl-td3-long_l96_const-force_2026-10-04.nc",
|
| 62 |
],
|
| 63 |
"L96_NN_FORCING": [
|
| 64 |
"teki_results/leaderboard_teki_l96_flux-force_2026-09-10.nc",
|
|
|
|
| 69 |
"opt_dsm_score_lm/leaderboard_sblm_dsm_parallel_l96_flux-force_2026-08-12.nc",
|
| 70 |
"opt_kgmm_score_adam/leaderboard_sbadam_kgmm_parallel_l96_flux-force_2026-09-11.nc",
|
| 71 |
"opt_dsm_score_adam/leaderboard_sbadam_dsm_parallel_l96_flux-force_2026-09-14.nc",
|
| 72 |
+
"rl-ddpg/leaderboard_rl-ddpg-short_l96_flux-force_2026-10-04.nc",
|
| 73 |
+
"rl-ddpg/leaderboard_rl-ddpg-long_l96_flux-force_2026-10-04.nc",
|
| 74 |
+
"rl-td3/leaderboard_rl-td3-short_l96_flux-force_2026-10-04.nc",
|
| 75 |
+
"rl-td3/leaderboard_rl-td3-long_l96_flux-force_2026-10-04.nc",
|
| 76 |
],
|
| 77 |
"L96_SPATIAL_FORCING": [
|
| 78 |
"teki_results/leaderboard_teki_l96_vec-force_2026-09-10.nc",
|
|
|
|
| 85 |
"opt_dsm_score_lm/leaderboard_sblm_dsm_parallel_l96_vec-force_2026-08-12.nc",
|
| 86 |
"opt_kgmm_score_adam/leaderboard_sbadam_kgmm_parallel_l96_vec-force_2026-09-11.nc",
|
| 87 |
"opt_dsm_score_adam/leaderboard_sbadam_dsm_parallel_l96_vec-force_2026-09-14.nc",
|
| 88 |
+
"rl-ddpg/leaderboard_rl-ddpg-short_l96_vec-force_2026-10-04.nc",
|
| 89 |
+
"rl-ddpg/leaderboard_rl-ddpg-long_l96_vec-force_2026-10-04.nc",
|
| 90 |
+
"rl-td3/leaderboard_rl-td3-short_l96_vec-force_2026-10-04.nc",
|
| 91 |
+
"rl-td3/leaderboard_rl-td3-long_l96_vec-force_2026-10-04.nc",
|
| 92 |
],
|
| 93 |
}
|
| 94 |
|
src/pages/MethodDetails.py
CHANGED
|
@@ -450,6 +450,178 @@ method_meta = {
|
|
| 450 |
],
|
| 451 |
"notes": "**Inherits both LM-DSM's slow DSM-training cost and Adam's local-minimum susceptibility** — training the DSM score network is the binding wall-clock cost (as with LM-DSM), and Adam's lack of a trust region or ensemble diversity leaves it as prone to getting stuck in a bad basin as ADAM-KGMM.",
|
| 452 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 453 |
}
|
| 454 |
|
| 455 |
# KNOWN_METHODS is the source of truth for the abbreviation/full-name list,
|
|
|
|
| 450 |
],
|
| 451 |
"notes": "**Inherits both LM-DSM's slow DSM-training cost and Adam's local-minimum susceptibility** — training the DSM score network is the binding wall-clock cost (as with LM-DSM), and Adam's lack of a trust region or ensemble diversity leaves it as prone to getting stuck in a bad basin as ADAM-KGMM.",
|
| 452 |
},
|
| 453 |
+
"RL-DDPG-SHORT": {
|
| 454 |
+
"citation": "Lillicrap et al., ICLR, 2016",
|
| 455 |
+
"url": "https://arxiv.org/abs/1509.02971",
|
| 456 |
+
"source": "`opt_experiments/ReinforcementLearning` — DDPG actor-critic (`ddpg_core.jl`, `rl_env.jl`, `rl_run.jl`), `UPDATE_FREQUENCY=short`.",
|
| 457 |
+
"math": (
|
| 458 |
+
"The unknown forcing parameterization is the **policy** and the whitened statistics misfit "
|
| 459 |
+
"`Φ_k=‖y-G(x_{T_k})‖²_Γ` defines the **reward** `r_k=Φ_{k-1}-Φ_k`. A small critic MLP `q(x,F)` is "
|
| 460 |
+
"trained on replay-buffer Bellman targets `-(1-γ)Φ_k+γ·q(x_{k+1},π(x_{k+1}))` (the `Φ_{k-1}` "
|
| 461 |
+
"offset cancels exactly), and the policy parameters are ascended along `∇_F q` averaged over "
|
| 462 |
+
"buffer states with Adam. No Jacobian of the simulator is ever formed — the gradient comes "
|
| 463 |
+
"from differentiating the learned critic. **The prior enters in three ways, but not as a "
|
| 464 |
+
"penalty:** the initial policy is a random draw from the prior, the policy is stored in "
|
| 465 |
+
"prior-whitened coordinates `F=μ+Lθ̃` (`L` = Cholesky factor of the prior covariance) so the "
|
| 466 |
+
"Adam step and the Gaussian exploration noise are measured in prior standard deviations "
|
| 467 |
+
"(following the prior's correlations), and the critic sees the whitened action. The reward "
|
| 468 |
+
"is the misfit only. In the *short* variant one RL step advances a "
|
| 469 |
+
"sliding statistics window by 1/10 of its length, so there are ~10 RL updates per window of "
|
| 470 |
+
"simulated time, each costing a fraction of a forward evaluation."
|
| 471 |
+
),
|
| 472 |
+
"math_eq": r"\theta \leftarrow \theta + \mathrm{Adam}\!\left(\mathbb{E}_{x}\left[\nabla_F\, q_\vartheta(x,F)\right]_{F=F_\theta}\right)",
|
| 473 |
+
"guardrails": (
|
| 474 |
+
"`γ=0.5<1` is essential: for a state-independent policy at `γ=1` the reward telescopes and "
|
| 475 |
+
"`∇_F Q` vanishes, so `γ=1` reproduces the no-learning control. A Polyak-averaged target critic "
|
| 476 |
+
"(`τ=0.05`) stabilizes the bootstrap; critic inputs/targets are standardized from warm-up data "
|
| 477 |
+
"and frozen; Gaussian exploration noise (0.1 prior std) is added to the applied action, with a "
|
| 478 |
+
"warm-up phase before the first update. The statistic is computed over a trailing window of "
|
| 479 |
+
"the full length `W` (not the short step) so it is not biased by a shortened estimation "
|
| 480 |
+
"window. Cost is counted as simulation only (1 initial full evaluation + stride/T per step); "
|
| 481 |
+
"per-cell budget is capped at 10000 units."
|
| 482 |
+
),
|
| 483 |
+
"params": [
|
| 484 |
+
{"Parameter": "γ (discount)", "Value": "0.5"},
|
| 485 |
+
{"Parameter": "Polyak rate", "Value": "0.05"},
|
| 486 |
+
{"Parameter": "critic_lr / actor_lr", "Value": "1e-3 / 0.02 (prior-std units)"},
|
| 487 |
+
{"Parameter": "batch size / updates per step", "Value": "64 / 1"},
|
| 488 |
+
{"Parameter": "steps per window / warm-up steps / buffer size", "Value": "10 / 50 / 5000"},
|
| 489 |
+
{"Parameter": "exploration noise / warm-up fraction", "Value": "0.1 / 0.5"},
|
| 490 |
+
{"Parameter": "critic hidden width", "Value": "64 (L63, L96 const) / 128 (vec, flux)"},
|
| 491 |
+
],
|
| 492 |
+
"notes": (
|
| 493 |
+
"**Cost advantage is partly structural** — the continuing RL trajectory pays spin-up once rather "
|
| 494 |
+
"than every step (for L63 `T_start/T=0.75`), and the convergence test runs at every stride on "
|
| 495 |
+
"overlapping windows, so scores are not directly comparable to methods that re-pay spin-up each "
|
| 496 |
+
"evaluation. **Not tuned per case.** Converges on every seed on "
|
| 497 |
+
"L63 and L96-const, but the higher-dimensional forcings are the hard case for a learned "
|
| 498 |
+
"critic: on L96 flux-force and vec-force it reaches the targets on only a few of 30 seeds "
|
| 499 |
+
"(flux: 1 at target 1.1, 5 at 1.2; vec: 2 at 1.1, 4 at 1.2) and on none at 1.0 within the budget."
|
| 500 |
+
),
|
| 501 |
+
},
|
| 502 |
+
"RL-DDPG": {
|
| 503 |
+
"citation": "Lillicrap et al., ICLR, 2016",
|
| 504 |
+
"url": "https://arxiv.org/abs/1509.02971",
|
| 505 |
+
"source": "`opt_experiments/ReinforcementLearning` — DDPG actor-critic (`ddpg_core.jl`, `rl_env.jl`, `rl_run.jl`), `UPDATE_FREQUENCY=long` (leaderboard name `rl-ddpg-long`).",
|
| 506 |
+
"math": (
|
| 507 |
+
"Same DDPG actor-critic scheme as RL-DDPG-SHORT (see that entry's update equation): the unknown "
|
| 508 |
+
"forcing parameterization is the **policy**, the decrease in the whitened statistics misfit "
|
| 509 |
+
"`Φ_k` is the **reward**, and the policy parameters are ascended along `∇_F q` of a small learned "
|
| 510 |
+
"critic. The prior enters as in RL-DDPG-SHORT: a random prior draw as the initial policy, "
|
| 511 |
+
"prior-whitened policy coordinates (step and exploration noise in prior standard deviations), "
|
| 512 |
+
"and no prior penalty in the reward. Here one RL step is the whole statistics window — exactly one standard forward "
|
| 513 |
+
"evaluation (spin-up + window), the same statistical window as every other method on the "
|
| 514 |
+
"leaderboard — so there is one RL update per forward evaluation and each step costs 1 unit."
|
| 515 |
+
),
|
| 516 |
+
"math_eq": r"\theta \leftarrow \theta + \mathrm{Adam}\!\left(\mathbb{E}_{x}\left[\nabla_F\, q_\vartheta(x,F)\right]_{F=F_\theta}\right)",
|
| 517 |
+
"guardrails": (
|
| 518 |
+
"Same `γ=0.5<1` (at `γ=1` the critic has no `F`-dependence for a state-independent policy), "
|
| 519 |
+
"Polyak target critic (`τ=0.05`), frozen input/target standardization, and Gaussian exploration "
|
| 520 |
+
"noise (0.1 prior std) as RL-DDPG-SHORT. The statistic `G_k` is exactly the standard forward map "
|
| 521 |
+
"used by every other method, and the spin-up is paid on every step; per-cell budget is capped "
|
| 522 |
+
"at 10000 units."
|
| 523 |
+
),
|
| 524 |
+
"params": [
|
| 525 |
+
{"Parameter": "γ (discount)", "Value": "0.5"},
|
| 526 |
+
{"Parameter": "Polyak rate", "Value": "0.05"},
|
| 527 |
+
{"Parameter": "critic_lr / actor_lr", "Value": "1e-3 / 0.02 (prior-std units)"},
|
| 528 |
+
{"Parameter": "batch size / updates per step", "Value": "64 / 1"},
|
| 529 |
+
{"Parameter": "steps per window / warm-up steps / buffer size", "Value": "1 / 20 / 2000"},
|
| 530 |
+
{"Parameter": "exploration noise / warm-up fraction", "Value": "0.1 / 0.5"},
|
| 531 |
+
{"Parameter": "critic hidden width", "Value": "64 (L63, L96 const) / 128 (vec, flux)"},
|
| 532 |
+
],
|
| 533 |
+
"notes": (
|
| 534 |
+
"**One RL update per forward evaluation, so far more expensive than RL-DDPG-SHORT** — the short "
|
| 535 |
+
"variant makes ~10× more updates per unit of cost and pays spin-up only once. **Not tuned per "
|
| 536 |
+
"case.** Converges reliably on L63 and L96-const, but never "
|
| 537 |
+
"reached the targets on L96 flux-force or vec-force within the budget."
|
| 538 |
+
),
|
| 539 |
+
},
|
| 540 |
+
"RL-TD3-SHORT": {
|
| 541 |
+
"citation": "Fujimoto, van Hoof & Meger, ICML, 2018",
|
| 542 |
+
"url": "https://arxiv.org/abs/1802.09477",
|
| 543 |
+
"source": "`opt_experiments/ReinforcementLearning` — TD3 actor-critic (`ddpg_core.jl`, `rl_env.jl`, `rl_run.jl`), `ALGORITHM=td3`, `UPDATE_FREQUENCY=short`.",
|
| 544 |
+
"math": (
|
| 545 |
+
"Same actor-critic formulation as RL-DDPG-SHORT (see that entry): the unknown forcing "
|
| 546 |
+
"parameterization is the **policy**, the decrease in the whitened statistics misfit is the "
|
| 547 |
+
"**reward**, and the policy parameters are ascended along `∇_F q` of a learned critic. TD3 "
|
| 548 |
+
"replaces the single critic with **twin critics** whose minimum forms the Bellman target "
|
| 549 |
+
"`-(1-γ)Φ_k+γ·min_i q_i(x_{k+1},π(x_{k+1}))`, and the actor ascends critic 1 only. The prior "
|
| 550 |
+
"enters as in RL-DDPG-SHORT (random prior draw as the initial policy; prior-whitened policy "
|
| 551 |
+
"coordinates for the Adam step, exploration and target-smoothing noise; no prior penalty in "
|
| 552 |
+
"the reward). In the *short* variant one RL step advances a sliding statistics window by 1/10 of its length, so "
|
| 553 |
+
"there are ~10 RL updates per window of simulated time, each costing a fraction of a forward "
|
| 554 |
+
"evaluation."
|
| 555 |
+
),
|
| 556 |
+
"math_eq": r"\theta \leftarrow \theta + \mathrm{Adam}\!\left(\mathbb{E}_{x}\left[\nabla_F\, q^{(1)}_\vartheta(x,F)\right]_{F=F_\theta}\right)",
|
| 557 |
+
"guardrails": (
|
| 558 |
+
"The three TD3 robustness heuristics are switched on relative to RL-DDPG: **twin critics** with a "
|
| 559 |
+
"min-target (reduces critic overestimation), **delayed policy updates** (the actor and the "
|
| 560 |
+
"Polyak target critics update once per 2 critic updates), and **target-policy smoothing** "
|
| 561 |
+
"(clipped Gaussian noise added to the target action, in prior-std units, since the actor is a "
|
| 562 |
+
"single vector). As for RL-DDPG there is no target actor. Same `γ=0.5<1`, Polyak rate, frozen "
|
| 563 |
+
"input/target standardization, 0.1 prior-std Gaussian exploration noise and trailing window of "
|
| 564 |
+
"full length `W` as RL-DDPG-SHORT; cost counts simulation only (1 initial evaluation + stride/T "
|
| 565 |
+
"per step), capped at 10000 units per cell."
|
| 566 |
+
),
|
| 567 |
+
"params": [
|
| 568 |
+
{"Parameter": "γ (discount)", "Value": "0.5"},
|
| 569 |
+
{"Parameter": "Polyak rate", "Value": "0.05"},
|
| 570 |
+
{"Parameter": "critics / policy delay", "Value": "2 / 2"},
|
| 571 |
+
{"Parameter": "target smoothing noise (clip)", "Value": "0.2 (0.5), prior-std units"},
|
| 572 |
+
{"Parameter": "critic_lr / actor_lr", "Value": "1e-3 / 0.02 (prior-std units)"},
|
| 573 |
+
{"Parameter": "batch size / updates per step", "Value": "64 / 1"},
|
| 574 |
+
{"Parameter": "steps per window / warm-up steps / buffer size", "Value": "10 / 50 / 5000"},
|
| 575 |
+
{"Parameter": "exploration noise / warm-up fraction", "Value": "0.1 / 0.5"},
|
| 576 |
+
{"Parameter": "critic hidden width", "Value": "64 (L63, L96 const) / 128 (vec, flux)"},
|
| 577 |
+
],
|
| 578 |
+
"notes": (
|
| 579 |
+
"**Same structural cost advantage as RL-DDPG-SHORT** — the continuing trajectory pays spin-up "
|
| 580 |
+
"once and the convergence test runs on overlapping windows, so scores are not directly "
|
| 581 |
+
"comparable to methods that re-pay spin-up every evaluation. **Not tuned per case.** "
|
| 582 |
+
"Converges on every seed on L63 and L96-const (slower than RL-DDPG-SHORT on L63 at targets "
|
| 583 |
+
"1.0–1.1, similar at 1.2); on the higher-dimensional forcings it is weaker than RL-DDPG-SHORT: "
|
| 584 |
+
"it never reaches the targets on L96 flux-force, and on vec-force only 1 of 30 seeds does "
|
| 585 |
+
"(target 1.2) within the budget."
|
| 586 |
+
),
|
| 587 |
+
},
|
| 588 |
+
"RL-TD3": {
|
| 589 |
+
"citation": "Fujimoto, van Hoof & Meger, ICML, 2018",
|
| 590 |
+
"url": "https://arxiv.org/abs/1802.09477",
|
| 591 |
+
"source": "`opt_experiments/ReinforcementLearning` — TD3 actor-critic (`ddpg_core.jl`, `rl_env.jl`, `rl_run.jl`), `ALGORITHM=td3`, `UPDATE_FREQUENCY=long` (leaderboard name `rl-td3-long`).",
|
| 592 |
+
"math": (
|
| 593 |
+
"Same TD3 actor-critic scheme as RL-TD3-SHORT (twin critics with a min-target; the actor "
|
| 594 |
+
"ascends critic 1 only; see that entry and RL-DDPG-SHORT for the formulation, including how "
|
| 595 |
+
"the prior sets the initial policy and the whitened coordinates). Here one RL step "
|
| 596 |
+
"is the whole statistics window — exactly one standard forward evaluation, the same statistical "
|
| 597 |
+
"window as every other method on the leaderboard — so there is one RL update per forward "
|
| 598 |
+
"evaluation and each step costs 1 unit."
|
| 599 |
+
),
|
| 600 |
+
"math_eq": r"\theta \leftarrow \theta + \mathrm{Adam}\!\left(\mathbb{E}_{x}\left[\nabla_F\, q^{(1)}_\vartheta(x,F)\right]_{F=F_\theta}\right)",
|
| 601 |
+
"guardrails": (
|
| 602 |
+
"Same TD3 heuristics as RL-TD3-SHORT: twin critics with a min-target, delayed policy/target "
|
| 603 |
+
"updates (every 2 critic updates), and clipped target-policy smoothing noise. Same `γ=0.5<1`, "
|
| 604 |
+
"Polyak rate, frozen standardization and 0.1 prior-std exploration noise; the spin-up is paid "
|
| 605 |
+
"on every step; per-cell budget is capped at 10000 units."
|
| 606 |
+
),
|
| 607 |
+
"params": [
|
| 608 |
+
{"Parameter": "γ (discount)", "Value": "0.5"},
|
| 609 |
+
{"Parameter": "Polyak rate", "Value": "0.05"},
|
| 610 |
+
{"Parameter": "critics / policy delay", "Value": "2 / 2"},
|
| 611 |
+
{"Parameter": "target smoothing noise (clip)", "Value": "0.2 (0.5), prior-std units"},
|
| 612 |
+
{"Parameter": "critic_lr / actor_lr", "Value": "1e-3 / 0.02 (prior-std units)"},
|
| 613 |
+
{"Parameter": "batch size / updates per step", "Value": "64 / 1"},
|
| 614 |
+
{"Parameter": "steps per window / warm-up steps / buffer size", "Value": "1 / 20 / 2000"},
|
| 615 |
+
{"Parameter": "exploration noise / warm-up fraction", "Value": "0.1 / 0.5"},
|
| 616 |
+
{"Parameter": "critic hidden width", "Value": "64 (L63, L96 const) / 128 (vec, flux)"},
|
| 617 |
+
],
|
| 618 |
+
"notes": (
|
| 619 |
+
"**One RL update per forward evaluation, so far more expensive than RL-TD3-SHORT.** **Not tuned "
|
| 620 |
+
"per case.** Converges on every seed on L63 and L96-const (slower than RL-DDPG "
|
| 621 |
+
"on L96-const, and on L63 faster at targets 1.0–1.1 but slower at 1.2), but never reached the "
|
| 622 |
+
"targets on L96 flux-force or vec-force within the budget."
|
| 623 |
+
),
|
| 624 |
+
},
|
| 625 |
}
|
| 626 |
|
| 627 |
# KNOWN_METHODS is the source of truth for the abbreviation/full-name list,
|
src/streamlit_app.py
CHANGED
|
@@ -121,9 +121,10 @@ _taxonomy_df = (
|
|
| 121 |
)
|
| 122 |
|
| 123 |
_UPDATE_TYPE_ROW_COLOR = {
|
| 124 |
-
"
|
| 125 |
-
"gradient": "#dbe9fa",
|
| 126 |
-
"
|
|
|
|
| 127 |
}
|
| 128 |
|
| 129 |
|
|
@@ -151,7 +152,7 @@ st.dataframe(
|
|
| 151 |
)
|
| 152 |
st.caption(
|
| 153 |
"Note: Kalman methods are Bayesian in spirit too (they're approximate Gaussian "
|
| 154 |
-
"posterior updates) — update type is about mechanism (gradient
|
| 155 |
"general), not whether a method is 'Bayesian'."
|
| 156 |
)
|
| 157 |
|
|
|
|
| 121 |
)
|
| 122 |
|
| 123 |
_UPDATE_TYPE_ROW_COLOR = {
|
| 124 |
+
"gradient (Kalman)": "#d9f2e6", # pastel green
|
| 125 |
+
"gradient (exact)": "#dbe9fa", # pastel blue
|
| 126 |
+
"gradient (score)": "#e6dcf5", # pastel purple
|
| 127 |
+
"general": "#fde2c8", # pastel orange
|
| 128 |
}
|
| 129 |
|
| 130 |
|
|
|
|
| 152 |
)
|
| 153 |
st.caption(
|
| 154 |
"Note: Kalman methods are Bayesian in spirit too (they're approximate Gaussian "
|
| 155 |
+
"posterior updates) — update type is about mechanism (which kind of gradient — exact, Kalman or score — vs. "
|
| 156 |
"general), not whether a method is 'Bayesian'."
|
| 157 |
)
|
| 158 |
|