coef: two-head sigmoid (λ_soft, λ_hard) — .cvcnav format v2 - #105
Merged
Merged
Conversation
Extend the deployable CoefMLP / coef_export / coef_train path with the paper's TWO learned, sigmoid-bounded reroute strengths (lam_soft AND lam_hard, App A.4 / material_nav.py:175-176: lam = lam_max*sigmoid(head)). Byte-compatible with the libcvc cvc::nav::coef_mlp v2 loader. sdf_nav.CoefMLP: - Add use_lam_hard (requires use_lam) -> out_dim = 3 + use_lam + use_lam_hard, plus lam_soft_max/lam_hard_max (5.0/10.0). A two-head net is lam_sigmoid: the lam columns are lam_max*sigmoid(head) with the head init in the last Linear bias (logit(init/max)); alpha/beta/gamma stay softplus(log(expm1)). full_out_bias() returns the 3 abg biases only in sigmoid mode. coeffs_and_lam returns (a,b,g,lam_soft[,lam_hard]). The v1 single-softplus lam path is unchanged. - add_lam_heads(model, soft_init, hard_init): basin-preserving lifter mirroring add_lam_head — append the lam_soft/lam_hard rows (zero weights, bias=logit(init/ max)), copy the abg rows verbatim so alpha/beta/gamma are bit-identical at init. coef_export.write_coef_mlp: a sigmoid net writes FORMAT_VERSION 2 + FLAG_LAM_SIGMOID, out_bias length 3 (abg only), then the two ceilings (struct '<ff') before meta. A plain / single-softplus-lam net stays v1, byte-unchanged. coef_train: --learned-lam-hard (implies --learned-lam) builds the net via add_lam_heads; --lam-hard-init (>0) seeds the hard head. train_bicycle and eval_risk_exposure use the LEARNED lam_hard for a two-head net; the Swarm drives with both learned lambdas. Deploy note states the 5-out v2 net + the v2 libcvc host floor. tests: add_lam_heads identity + init + flags; two-head sigmoid bounds and out-of-range init rejection; exporter v2 layout + a pure-numpy decode/forward parity (~1e-4) that reproduces the C++ forward from the exported bytes; v1 single-softplus export back-compat; a two-head train_bicycle smoke; the CLI rejecting --lam-hard-init <= 0; and a pycvc-gated in-process C++ round-trip for the two-head net.
…built on v2 libcvc The in-process C++<->torch round-trip loads a v2 .cvcnav through the INSTALLED pycvc, which still links a pre-v2 libcvc and raises 'unsupported .cvcnav format version' in hermetic CI. The comment already said it should skip until pycvc is rebuilt on v2 (deploy step 9); implement that skip. The pure-numpy decoder in test_lam_head already proves the v2 byte layout + forward math, so byte-parity coverage is unaffected.
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.
What
Extend the deployable
CoefMLP/coef_export/coef_trainpath with the paper's two learned, sigmoid-bounded reroute strengths —lam_softandlam_hard(App A.4 /material_nav.py:175-176,lam = lam_max*sigmoid(head)). Previously onlylam_softwas learnable (a single softplus 4th output);lam_hardwas a fixed dial. This makes the tiny deployable net two-head, byte-compatible with the new libcvc.cvcnavformat v2.Companion (required host): transfix/libcvc —
nav: two-head sigmoid (lam_soft, lam_hard) — .cvcnav format v2→ transfix/libcvc#436Changes
sdf_nav.CoefMLP:use_lam_hard(requiresuse_lam) →out_dim = 3 + use_lam + use_lam_hard;lam_soft_max/lam_hard_max= 5.0/10.0. A two-head net islam_sigmoid: lam columns arelam_max*sigmoid(head)with the head init in the last Linear bias (logit(init/max)); α/β/γ staysoftplus(log(expm1)).full_out_bias()returns the 3 abg biases only in sigmoid mode;coeffs_and_lamreturns(a,b,g,lam_soft[,lam_hard]). The v1 single-softplus lam path is unchanged.add_lam_heads(model, soft_init, hard_init): basin-preserving lifter mirroringadd_lam_head— appends the two lam rows (zero weights, bias =logit(init/max)), copies the abg rows verbatim so α/β/γ are bit-identical at init.coef_export.write_coef_mlp: a sigmoid net writesFORMAT_VERSION = 2+FLAG_LAM_SIGMOID,out_biaslength 3 (abg only), then the two ceilings (struct '<ff') before the meta trailer. A plain / single-softplus-lam net stays v1, byte-unchanged.coef_train:--learned-lam-hard(implies--learned-lam) builds the net viaadd_lam_heads;--lam-hard-init(>0) seeds the hard head.train_bicycle/eval_risk_exposureuse the learnedlam_hardfor a two-head net; theSwarmdrives with both learned lambdas. Deploy note states the 5-out v2 net + the v2 libcvc host floor.Byte parity / back-compat
.cvcnavdecoder intests/test_lam_head.pythat reproduces the C++ forward from the exported bytes and asserts parity (~1e-4) + lam bounds — an independent cross-check that runs without a pycvc build.tests/test_coef_mlp_parity.pygains a pycvc-gated in-process C++↔torch round-trip for the two-head net (all 5 columns, ~1e-4) — runs once pycvc is rebuilt on v2 libcvc.test_single_softplus_lam_still_exports_v1); all existing lam tests pass.Test results (
.venv, torch 2.12, numpy 2.4)tests/test_lam_head.py: 14 passed (7 new two-head).test_swarm,test_scenario,test_squad,test_vehicle,test_material_scenario,test_drive_step_parity,test_sim_thread,test_material_parity,test_vehicle_refinements,test_coef_export_checkpoint,test_coef_train_lam_deploy,test_risk_lever,test_swarm_risk_drive,test_scorecard_eval,test_coef_eval,test_coef_mlp_parity): 130 passed, 9 skipped (all skips are pycvc-only).black 24.10.0+ruff 0.6.9: clean.NOT in this PR (human owns)
Retrain / A-B / republish (step 9). Ready-to-retrain command:
The published
libcvc-matext+cvc-dbg-weightsrecipes will need acvc_revisionbump at republish (not touched here).