Ais train optim DO NOT MERGE - #1371
Draft
constantinpape wants to merge 61 commits into
Draft
constantinpape wants to merge 61 commits into
constantinpape wants to merge 61 commits into
Conversation
Snapshot of the APG 2D/3D optimization experiments on this branch: library changes to the v2 automatic prompt generator and UniSAM2 decoder width, the campaign screening/training/benchmark scripts and their JSON configs, campaign notes and reviews, development check scripts, and the accompanying tests. Committed as-is so the full experimental state stays on this branch; the clean-up happens on a separate branch. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Every optimization tested in the 2026-09 APG campaigns was refuted under the generalization rule and is removed from the library, together with the learned prompt-selection machinery that PR #1340 had merged earlier: - micro_sam/v2/automatic_prompt_generation.py drops the learned multimask selector, filter and refinement gate (multimask_scorer, multimask_selection, score_filter, set_multimask_models, gate kwargs), the structural hooks (prompt_type, arbitration, fusion, recover_residual and their helpers), the label-free refinement gating rules (protect_neighbours, negative_scope, gate="isolated", isolated_fallback, touch_radius), the 3D learned candidate filter (return_metadata, VOLUME_CANDIDATE_FEATURE_NAMES, candidate_* options) and every experiment-only hook (prompts=, keep_trace, return_multimask_features). The plain second-round refinement (points / boxes / masks, 2D and the 3D anchor-slice variant) stays, as does the tiled generator. - micro_sam/v2/multimask_selection.py is deleted; the annotator no longer passes score_filter. - finetuning/v2/evaluation keeps the generic harness core (2D/3D manifests and runners, comparator, SLURM submitter, task registry, 3D case tools, pre-existing library benchmarks) stripped of the learned/structural plumbing; the 17 feature-specific screens/trainers/readers and 39 of 44 configs are removed. The 3D runner loses its trace-based recall attribution and anchor export. The stray test_apg_3d_tiling.py becomes check_apg_3d_tiling.py so bare pytest no longer collects it. - Tests for the removed features are deleted or trimmed; the two comparator test files are merged into test_apg_optimization.py. The full campaign state stays preserved on branch apg-optim-fable (356b76d). This commit starts a new implementation checksum epoch (f76ee7170ca77da882c0078dfaa5b301, seven files). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Every campaign note gets a banner stating that the mechanisms it describes were tested, refuted and removed on this branch, that the full state is preserved on apg-optim-fable (356b76d), and which sections describe kept functionality (the second-round refinement). A "Status on this branch" section at the end of each note maps the removed scripts, configs and library hooks. EXPERIMENTAL_SETUP.md records the reproducible set-up of the campaigns for future instance-segmentation (AIS) optimization: environment and SLURM presets, datasets and splits, checkpoints and the v4 staging recipe, the 2D subset manifests and the leak-free 3D crop manifests with their checksums, metrics and aggregation, parameter defaults and controls, acceptance and generalization gates, the timing-trial protocol, implementation checksum epochs (now f76ee7170ca77da882c0078dfaa5b301), the output-root layout and the steps to run an AIS campaign on the same set-up. The two tiled-3D-APG design notes move from the repository root into the notes directory unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…al_features torch_em 0.10.4 takes 'initial_features' as an argument of UNETR3D and sizes the decoder from it, so the joint/v4 checkpoints (32-wide decoders) load strictly through the plain kwargs forwarding UniSAM2 already had on dev. Verified against joint/v4 hvit_t geodesic best.pt: all 325 decoder keys match with no rebuild. micro_sam/v2/models/util.py returns to its dev version; the UniSAM2 width test stays. torch_em 0.10.1 built a 64-wide decoder regardless, so v4 checkpoints now require the newer torch_em (dependency floor to follow). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
submit_all_evaluations.py defaulted to the 'super' environment, which does not exist on grete, and to 3g.40gb slices for 3D jobs, which are scarce; it now activates 'new-stack' and puts 3D jobs on 1g.20gb (the (8, 512, 512) production crops peak around 6 GiB). The parameter_search.py array template activated 'super' as well and now uses the same environment; as a checksum file this starts implementation epoch e1903b1b3c1e4e3610c71e1d0bd81f1d (harness-only, results unaffected). EXPERIMENTAL_SETUP.md gains section 14 with the 2026-09-06 baseline reruns of the cleaned harness on joint/v4 geodesic defaults: the 2D subset benchmark (bit-identical to the recorded v4 controls), the 3D deep crops (holdout identical, primary identical on 56/57 crops) and the AIS/APG production defaults on nine test splits, each with its run directories, result files and reference numbers. The campaign notes point to it from their status sections. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Predict every manifest sample once, cache the (4, *spatial) decoder prediction with its labels, and run configurations, parameter sweeps, seed diagnostics and ground-truth oracles on the cache. Run directories follow the APG layout so the comparator reads them; the report applies the generalization gate. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…cessing The geodesic decoder predicts a distance magnitude that falls to zero along the boundary of every object it recognised, while a false foreground region carries no such dip. drop_instances_without_boundary_dip removes instances whose median boundary magnitude exceeds a threshold; flow_instance_segmentation exposes it as boundary_magnitude_max (off by default). The AIS benchmark mirrors it, the cached sweep scorer applies it, and the campaign notes record the diagnostics and prototypes that led to it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…the A1 screens report_ais_sweep.py joins the per-dataset sweep tables of a grid over several manifests and scores every combination as a shared default: balanced mSA, change per dataset against the library defaults, the gate verdict and the ratio to each dataset's optimum. The notes record the Phase 1 diagnostics, the three prototypes and the epoch A1 filter screens. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
evaluate_automatic_segmentation.py --ais_params reads a benchmark-style configuration, resolves it against the library defaults (sparse and dense) and scores the test split with it; submit_all_evaluations.py passes --ais_params and --result_tag through. The sweep ranking accepts the deep 3d manifests. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…-aware The flow post-processing defaults of hvit_t become sigma 1.0, min_size 50 and the boundary-magnitude filter at 0.4 for images; volumes take min_size 200 and foreground 0.6 through a new 'sparse_volume' override table that default_postprocessing resolves by dimensionality. Against the registry values this gains +2.4 % balanced mSA on eleven 2d development datasets (9 up), +4.3 % on the 2d holdout and +22 % on the 3d LM crops with the joint/v4 geodesic checkpoint. The filter now derives every instance's boundary median from one sort over the boundary pixels, 18x faster with identical output. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…the filter test Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…boundary filter The volume overrides (foreground 0.6, size floor 200 voxels) that won on the 3d tuning crops lost on the seven test-only 3d datasets (two up, two below the loss limit); the registry values plus the filter gain +3.4 % there with every dataset up, and +4.7 % / +9.7 % on the tuning crops. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…results Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
lower_height_under_seeds lowers the height map under the seeds ('zero', or the minimum of a ring around the
seed) so that the monotone flooding of the watershed does not hold a seed's front at the seed's own height.
Off by default; the harness and the sweep scorer mirror it.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ampaign Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…automatic branch (AIS epoch A5) The decoder can now predict a fifth channel, the touching boundary between objects (touching_boundaries / contact=True in the label transforms, Dice + BCE in DirectedDistanceLoss, sigmoid in CustomActivation), and the foreground can be trained with a per-pixel BCE weighted in a band around the object boundary (boundary_weight). Inference infers the channel count from the checkpoint and flow_instance_segmentation takes the contact map as an opt-in ridge (contact_weight) or an excluded-then-reassigned mask (contact_mask_threshold); the default path is unchanged. The AIS harness mirrors the keywords, gains the fg_area_ratio diagnostic and two contact configs. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…, submission, readers train_ais_decoder.py trains the UniSAM2 decoder with the encoder frozen at the v4 joint weights on the train splits of the AIS tuning datasets (four variants: baseline, contact channel, boundary-weighted foreground, both), warm-started from the v4 decoder; stage_ais_decoder_checkpoint.py writes a lean joint-format file the evaluation harness reads through MICRO_SAM2_JOINT_CHECKPOINT_ROOT; the submitter writes single-GPU SLURM jobs. report_ais_decoders.py compares the staged checkpoints on the cached benchmark runs (gate, merge/absorb shares, extent figures) and diagnose_decoder_fields.py measures the contact geometry and the foreground extent of cached predictions. Notes and the proposal move into optimization/notes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ecoder training Python 3.14's fork-server start method made every worker re-import the environment (minutes per job, and every epoch for validation); a 512^2 file with fewer than three objects made torch_em's sampler give up and end the run. The subset wrappers now redraw or step to the next file instead. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…coder campaign notes Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…the chained evaluation Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…aign Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… filter Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…her of the decoder campaign Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…reens Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…mpaign Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…er campaign Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…s and the round-2 hand-over object_boundaries / contact_mode="all" make the auxiliary channel the inner boundary of every object instead of the touching boundaries only; the decoder campaign gains the variants boundary and boundary_fgcal, the unattended scripts take their variant lists from the environment, and notes/AIS_DECODER_HANDOVER.md describes how to launch, chain, monitor and read out round 2. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The two boundary-channel trainings run (48000 iterations each, 3g.40gb slices); finalize_round2_reports.sh submits their dec-top1 screens and writes the six-decoder overview unattended, so no step depends on the session. Also records why the jobs would not start (our own sweep array at the head of grete:preemptible) and why the round-1 finalisation died (the driver script was edited while a job slept in its wait loop). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
diagnose_decoder_fields.py assumed the touching-boundary target, which calls the round-2 boundary head's correct pixels negative (on tnbc the contact decoder's precision reads 0.31 against the touching lines and 0.82 against every object boundary). --contact-mode selects the target; recall_touching and recall_bg_boundary are reported in both modes, so a touching-target and a full-boundary head can be read side by side. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Section 4.5: the 3D table of all four decoders (the plain fine-tune already loses 25-60 % per LM family, the five-channel decoders are 0 because the magnitude filter removes every instance), the field diagnostics of all four, and the fifth channel rescored with the mode-independent recalls - both round-1 heads learned the touching target but stay silent exactly where the campaign lost mSA, and the boundary-weighted foreground loss makes the head less confident. The hand-over now covers reading the chained round-2 results rather than launching them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
With the touching target the mask mode kept a contact line free; with the full boundary it is the classical erode-flood-dilate scheme, so a confident head makes it active for the first time - and both modes can shave objects only a few pixels wide, which the mechanism columns separate from merges. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
baseline's own optimum wants foreground_threshold 0.4; fgcal and both want 0.5. The shared dec-top1 configuration is therefore fgcal's optimum and 1 % below baseline's, so the boundary-weighted foreground loss is worth +1.3 % rather than the +2.4 % of section 4.3 - and its mechanism is the threshold calibration, which is what point 4.1 claims. The move to density 50 / sigma 0.5 also belongs to the loss-changed decoders only; baseline keeps the production density and sigma. The cached sweep scorer reproduces the screened runs to 0.05 %. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
contact's own optimum is 0.4083 at foreground_threshold 0.6, i.e. -3.8 % against baseline's own optimum - within a point of the -4.7 % measured at the shared defaults, so "it was only mis-tuned" is not the explanation. The optimal threshold runs baseline 0.4 -> contact 0.6 -> fgcal/both 0.5: the contact task pushes foreground mass outward and the boundary-weighted BCE pulls it back, which the fg_area_ratio column shows at a fixed threshold on ten of eleven datasets. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The 16:53 edit to launch_tuning_after_caches.sh took down ais_decoder_tuning at 19:03, six hours after it took down ais_decoder_finalize: one edit kills every job sleeping in that file, hours apart. Nothing was lost - the sweeps were already submitted and all four rankings are written. The frozen copies are byte-identical to the on-disk files, so tuning2 and finalize_r2 are unaffected. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The session is stopped so a later one can watch the trainings land. Records where they stood at 21:29, and makes the first command on resume checking how they ended - the evaluation is afterany, so a timed-out or preempted run is evaluated silently rather than failing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Both round-2 trainings finished the full budget, but the tuning launcher re-ran the four round-1 sweeps and never submitted the round-2 ones: SBATCH_EXPORT=none is set on this cluster, so sbatch does not propagate the submitting environment and WAIT_VARIANTS / VARIANTS fell back to the round-1 defaults. The failure is silent and produces plausible work. The launcher now takes --wait / --rank arguments; the redundant 46 tasks are cancelled, their job directories moved to jobs/_superseded/ so tasks_done stops shadowing the finished round-1 ones, and the round-2 sweeps, contact screens and a ranking job are submitted. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The head is confident where the contact head was silent (deepbacs 0.015 -> 0.505 recall, tnbc 0.032 -> 0.587, puma 0.123 -> 0.566, neurips 0.128 -> 0.460), so the class-imbalance diagnosis was right. At dec-top1 + ridge 1 the boundary decoder reaches +3.3 % balanced on dev with 10 of 11 datasets up - the best of the campaign - and repairs covid_if (-19 % -> +0.2 %) and deepseas (-27 % -> +20 %). It fails the gate on deepbacs alone (-14.1 %), whose rods are shaved and split rather than merged, and which loses for every five-channel decoder. Stacking fgcal on top still hurts. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Correction: the boundary head has no pixel above 0.5 on 33 of 50 dic_hepg2 crops, but its soft probability is 0.133 on the true boundary against 0.0020 elsewhere. The ridge reads the soft map and swings that dataset by 30 points; the mask thresholds and cannot. Read the soft contrast, not only Dice and recall at 0.5. The 24-configuration screen also separates the two modes: the mask is the uniform lever (7/11 up, worst -0.5 %) and does not shave thin objects, while seeded splits rise monotonically with the ridge weight. And no post-processing rescues deepbacs - it is -11.7 % with neither mode, so the gate failure is a recipe question. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
boundary's sweep optimum sits at foreground_threshold 0.5, between baseline's 0.4 and contact's 0.6, and keeps the production density 10 / sigma 1.0 - confirming that the regime shift to density 50 / sigma 0.5 belongs to the foreground loss change, not the fifth channel. Also restates the headline: +3.3 % is against baseline at dec-top1, which is 1 % below baseline's own optimum, so the honest figure is +2.3 %. Screens of each decoder at its own optimum with and without the ridge close the missing cell the sweep cannot evaluate. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
baseline at its own optimum scores 0.4244 dev / 0.4052 holdout, not 0.4200 / 0.4025. Against that reference the boundary channel is +2.3 % on dev with 7 of 11 up (deepbacs -10.2 %, neurips -6.1 %, tissuenet -5.0 %, puma -0.3 %) and +0.8 % on the holdout, where round-1 `both` still reaches +1.5 %. tissuenet alone swings 14 points from the reference change. So the target change is worth +4.4 points over the contact channel, but the fifth channel is still not a win over the plain fine-tune, and nothing passes the gate. Also: boundary's own sweep optimum is the wrong basin once the ridge exists (dic_hepg2 -8.6 % against +26.5 %), because the cached scorer cannot evaluate contact keywords at all. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
density_threshold and sigma track the foreground loss alone: all three decoders with the boundary-weighted BCE want density 50 / sigma 0.5, all three without it keep the production 10 / 1.0, and the fifth channel has no influence - which settles 4.7 point 4. foreground_threshold tracks the fifth channel instead: 0.4 with none, 0.6 for touching boundaries, 0.5 for full boundaries, and 0.5 whenever the calibrated foreground loss is present. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
boundary also scores 0 on all six LM families, so the better-posed channel does not repair the volume path - but the mechanism is not the magnitude filter recorded in 4.0: its 3d fg_area_ratio reaches 6.6 (celegans) and 8.4 (gonuclear) against baseline's 2.0 / 3.6, with up to 9 background seeds per object and nothing matching at IoU 0.5. Seeds are not missing; the volume is flooded, and boundary is the worst of the six. fgcal is the only variant that improves the 3d foreground and keeps an LM score at baseline level, and on EM the boundary channel is harmless (best of six on cremi_seen and snemi). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Each at its own optimum against baseline at its own optimum: boundary +2.3 % dev / +0.8 % holdout, boundary_fgcal +1.6/+0.7, fgcal +1.3/+1.0, both +0.6/+1.5, contact -2.1/-0.2. Recommendation: include the boundary-weighted foreground loss - it is the most consistent change and the only one that generalises to 3d. Include the full-boundary channel only with joint 2d+3d training, with contact_weight in the tuning grid, and with a remedy for thin objects. Never use the touching-boundary target. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
dic_hepg2 sits near the mSA floor (0.118-0.190) with a 0.072 spread, so its relative swings dominated the balanced mean without representing segmentation quality. Re-ranked all six sweeps over the remaining ten datasets and read the plateau rather than the top row. Two retractions follow. The "clean 3-3 separation of the seed regime by the foreground loss" is noise: the two regimes are identical to four decimals for fgcal and boundary_fgcal. And "a ridge-blind sweep cannot tune a five-channel decoder" rested entirely on dic_hepg2 - without it boundary's own sweep optimum is its best configuration and the ridge is worth +0.5 %, not +2 %. What survives is the threshold finding, with effects an order of magnitude larger: the fifth channel shifts the optimal foreground threshold in proportion to how ill-posed its target is (none 0.4, full boundary 0.5, touching 0.6). boundary's dev advantage is +1.2 %, not +2.3 %, and fgcal holds up best on the holdout. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
On the nine informative datasets the four improved decoders sit +0.2 to +0.8 % above baseline - inside the sweep's own resolution - and only contact is clearly worse (-2.7 %). boundary's worst dataset improves from -12.3 % to -2.1 %, deepbacs being its only remaining loss. Adds a mechanical account of each optimum: which parameters build the seed map (foreground_threshold, n_iter x dt, sigma, density_threshold) and which build the height map (foreground_weight, plus the non-swept contact ridge), and what each setting's best configuration therefore does. The height map splits by whether the loss touches the foreground twice: the three decoders that predict one clean foreground trust it at 0.75 and are the three best. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The base map is a convex mix of two [0,1] terms, so it is bounded by 1; the ridge is added outside that normalisation, so contact_weight 1.0 is as tall as the map's entire dynamic range. Measured on livecell, the base map's boundary-to-interior contrast is +0.145 while the contact probability is 0.623 against 0.055, so the ridge multiplies the barrier by 3.0x at weight 0.5 and 4.9x at weight 1. That explains both observed behaviours: merges fall from 7.8 % to 4.3 %, and seeded splits rise monotonically because past weight ~2 the ridge overrides rather than assists the boundary evidence. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Closed
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.
This contains all the code for AIS optimization.
This is just for reference, we don't want to merge this.