Repository navigation
feat(eval): the pre-registered tuning run of the Gauss-Markov visual error model (ADR-0034) - #179
Merged
Merged
Conversation
…error model (ADR-0034) The run of ADR-0034 "How the parameters are chosen", once, on development seeds only: twelve grid points, the candidate gate in S1 and S2 on seeds 0 to 24, the smallest margin as the score. No point qualified, so the candidate is recorded as failed on development seeds. Nothing is chosen, confirmed or frozen, and no default changes. gm_tuning.py imports the margin functions, the seed refusal and the confirmation blocks from scale_tuning and does not change that module. The command takes no seed and refuses any seed from 100 up before a case runs. The DIAGNOSTIC (the highest-score point at five visual-error correlation times, seeds 25 to 49) is outside the decision and in its own file. The CSVs, the generated section of calibration.md and the tests that check them are added. Part of #44. Part of #113. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Keep both test files in the ci.yml pytest list. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01L6ro5x4WRA4P7sQHLyPPGa
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #44. Part of #113.
Outcome: the candidate is recorded as FAILED ON DEVELOPMENT SEEDS. No point of the grid passed the gate in both scenarios on seeds 0 to 24, so none was chosen, none was confirmed, nothing is frozen, no held-out block is used, and no default changed. Per ADR-0034 the candidate is not repaired and no grid point is added. Base:
origin/mainat7d078ed(PR #173), whose CI run was green before the grid was started. Seeds used: 0 to 99 only.Context
ADR-0034 fixes how
tauandrhoof the Gauss-Markov visual error model are chosen: a grid of twelve points, the candidate gate of ADR-0030 in S1 and S2 on seeds 0 to 24, a score that is the smallest margin, confirmation on three more blocks. This PR is that run, once, with the code and tests that make it checkable.Change
src/navkit/gm_tuning.pyandnavkit gate tune-gm --csv PATH [--page PATH] [--robustness-csv PATH]. The grid constant is named after the ADR (GRID_TAU_S,GRID_RHO,GRID). The command takes no seed option, and any seed from 100 up is refused before a case runs, in every stage, the diagnostic included.navkit.scale_tuning, not copied; a test asserts identity. That module is not touched, so the adaptive-scale CSV and page are unchanged (git diffonscale_tuning.py, its CSV and the golden file is empty). The point, the tie rule (smaller tau, then smaller rho) and the CSV columns differ, so those are new.docs/data/gm_tuning.csv(stage, tau, rho, scenario, seeds, condition, relation, value, threshold, margin, holds, score, qualifies, chosen), deterministic, 144 rows.docs/data/gm_tuning_robustness.csv, the diagnostic, 30 rows.docs/calibration.md: the grid table, the outcome sentence, the diagnostic table. No claim about B1;CONSTRAINTS.mdB1 andCLAUDE.mdare not touched.tests/test_gm_tuning_page.pyis added to the CI documentation step (the guard test requires it).tune-gm. Metric markers are regenerated for the new test count.The grid (seeds 0 to 24)
Score is the smallest margin over six conditions in both scenarios. Negative means a condition fails.
The highest score is (tau 2 s, rho 0.9), and it fails S2 on three conditions:
worst_ratio2.205 against 1.5 (margin -0.470, the score),upper4.985 against 4.738 (-0.052) andcoverage0.9316 against 0.95 (-0.019). It passes S1. Scores rise with tau and rho towards the matching correlation time, but none reaches zero. This is a statement about this grid on these seeds; it does not say whyworst_ratiois large.Confirmation: none. No point was chosen, so no confirmation block was run.
Diagnostic (outside the decision, not a selection input, not a pass or fail)
Point: (tau 2 s, rho 0.9), the point with the highest score because none qualified. The S2-like scenario at five visual-error correlation times, gate of ADR-0030 evaluated for that scenario alone, seeds 25 to 49. Each cell is the margin; "no" marks a condition that does not hold.
Two things stand out, as observations on development seeds. With little correlation the model is conservative: the
lowerbound on the per-run NEES fails at 0, 0.25 and 0.5 s. With the correlation time it was set for (2 s) the NEES conditions hold, and the failures are the ATE conditions: the worst ATE ratio against the no-vision control is 2.79 against 1.5, and the candidate beats the control in 19 runs of 25 where 20 are needed. So on seeds 25 to 49 this point would also not have confirmed. That is a diagnostic, not a confirmation, and it was not used to choose anything.Runtime
One run of the full procedure: 801.8 s (13.4 min) on one laptop, one process. The estimate made first, from timing 5 seeds, was 26 min (18 + 4.5 + 3.7). It was an overestimate because no point qualified, so the 4.5 min of confirmation was not spent.
The grid was run once. My first launch used
python -m navkit.cli, which has no main guard and so did nothing: exit 0, no output, no CSV, no case run (checked: no file written, page unchanged). It was a launch error, not a run, and the logic and grid were not touched. The second launch, through the installednavkitcommand, is the only run.How tested
ruff check,ruff format --check,mypy src --ignore-missing-imports,check_doc_tables.py(benchmark in a scratch path),metrics.py --check(after--write),check_links.py,mkdocs build --strict(scratch directory),tests/test_framing.pyandtests/test_quoted_numbers.pyaftergit add, the golden test without--update(nothing frozen, so it must not change and does not), and the full suite once: 2371 passed, 32 skipped, 2 xfailed, 1 failed (18 min 40 s). The failure wastests/test_b1_gate_page.py::test_the_prose_gives_no_verdict_on_b1: that guard reads the whole page from the B1 section to "Worked example", which includes this new section, and forbids the phrase "gate passes", which my diagnostic table header used. I renamed the column to "All six hold" in the generator and regenerated the page from the unchanged CSVs (no case was rerun). I did not rerun the whole suite. I reran the 35 test files of the CI documentation step plustest_gm_tuning.py, the golden test andtest_scale_tuning.py: 803 passed, 6 skipped.Tests, written first (
tests/test_gm_tuning.py, 68 tests,tests/test_gm_tuning_page.py, 18): both files failed at collection before the module existed. They check: the grid constant equals ADR-0034's twelve points (the page test also reads the ADR sentence); the estimator of every point (clone, model on, no preset, no adaptive scale); the score is the minimum margin and not the maximum; ties go to the smaller tau and then the smaller rho, in that order, and a one-in-1e12 difference is not a tie; a non-qualifying point is never chosen; no qualifying point gives "failed"; a chosen point that fails any one confirmation block gives "failed", for each block; a missing or foreign confirmation is an error; the loop runs each point once, confirms only the chosen point on three blocks, and tries no second candidate; seeds 100 and up are refused at every stage before any case, and the command has no seed or held-out option; the CSV columns, byte determinism and round trip; the diagnostic runs at five correlation times on seeds 25 to 49, uses the highest-score point when none qualified, is labelled DIAGNOSTIC, and cannot change the outcome or the grid rows; the page sections equal the CSVs; the margins, scores and choice are recomputed from the rows without the selection function; the config defaults still read as placeholders. Two tests run real cases on seeds 0 and 1 to check determinism and the wiring to the gate, including the correlation time reaching the scenario.Mutation checks (each reverted, file compared back byte for byte):
My first attempt at the last mutation broke collection instead of the tests, so I redid it; the table is the redo.
Risks
vision_enabled, and any attempt to repair the candidate. The next step is a decision for the maintainer; per ADR-0034 it is not a new grid point.ci.ymlis edited (one test name added to the documentation step).Checklist
# noqa, no new suppression, no skipped or weakened test (one test skips by design when nothing is frozen)🤖 Generated with Claude Code