Add new regression and ensemble experiment configurations for V2-M and OrthoBridge

- Introduced multiple regression experiment configurations targeting vf_md, including:
  - cd_solo_reg_set.json: CD tower only regression setup.
  - img_solo_reg_set.json: Image tower only regression setup.
  - reg_head_epoch_sweep.json: Baseline regression sweeps at different epochs (50, 75, 100).
  - reg_head_set.json: Various regression setups including baseline and OrthoBridge configurations.
  - single_eye_reg.json: Single-eye regression setup for worst-eye aggregation analysis.

- Added ensemble configurations for OrthoBridge with different inner bridges:
  - ortho_alts_ensemble.json: Ensemble tests with ConcatBridge, PairwiseAdditiveBridge, and GatedAdditiveBridge.
  - ortho_alts_tritower.json: Tritower tests with the same inner bridges.

- Created V2-M specific configurations:
  - baseline_reg_nt50.json: Regression baseline with V2-M backbone.
  - geom_vec_gt.json and geom_vec_unet.json: Geometry vector injection experiments with V2-M.
  - single_l1_bridges.json: Single-eye ensemble experiments with various bridge types.
  - tritower_geom_gt.json: Tritower setup with GT contour-rasterized masks.

- Promoted existing experiments to higher repetitions for robustness.
This commit is contained in:
rpotter6298
2026-06-11 15:08:20 +02:00
parent 32a801a572
commit 280060db82
343 changed files with 8558 additions and 57747 deletions
+23
View File
@@ -30,6 +30,9 @@ batch.json format:
"stage_overrides": { // optional — patched by stage name
"nt": { "epochs": 40 }
},
"tower_overrides": { // optional — patched by tower name
"img": { "args": { "backbone": "convnextv2_tiny" } }
},
"reps": 10, // optional — overrides --reps
"priority": 0 // optional
}
@@ -83,6 +86,22 @@ def apply_stage_overrides(stages: list[dict], stage_overrides: dict) -> list[dic
return stages
def apply_tower_overrides(towers: list[dict], tower_overrides: dict) -> list[dict]:
"""Patch individual towers by name without replacing the entire list.
Useful for backbone swaps and other per-tower arg tweaks:
"tower_overrides": { "img": { "args": { "backbone": "convnextv2_tiny" } } }
"""
towers = copy.deepcopy(towers)
for tower in towers:
name = tower.get("name")
if name in tower_overrides:
merged = deep_merge(tower, tower_overrides[name])
tower.clear()
tower.update(merged)
return towers
def build_config(base_cfg: dict, entry: dict, rep: int, seed: int, fold_seed: int,
output_root: str) -> dict:
"""Produce the final merged config for one rep of one batch entry."""
@@ -95,6 +114,10 @@ def build_config(base_cfg: dict, entry: dict, rep: int, seed: int, fold_seed: in
if "stage_overrides" in entry and "stages" in cfg:
cfg["stages"] = apply_stage_overrides(cfg["stages"], entry["stage_overrides"])
# Patch individual towers by name (backbone swaps, arg tweaks)
if "tower_overrides" in entry and "towers" in cfg:
cfg["towers"] = apply_tower_overrides(cfg["towers"], entry["tower_overrides"])
# Stamp run_name, model seed, split seed, output_root.
base_run_name = entry["run_name"]
cfg["run_name"] = f"{base_run_name}/rep{rep:02d}"
+9 -1
View File
@@ -292,9 +292,17 @@ def _run_job(job: JobSpec, server: _Server,
proc.wait()
tailer.join(timeout=5)
heartbeat.join(timeout=5)
log_file.unlink(missing_ok=True)
success = proc.returncode == 0
if success:
log_file.unlink(missing_ok=True)
else:
failed_path = log_file.with_suffix(".failed.log")
try:
log_file.replace(failed_path)
print(f"[client] preserved failure log at {failed_path}", flush=True)
except Exception:
pass
if not success:
try:
Binary file not shown.