Trim relax mode bias from optimizer
This commit is contained in:
parent
69cc05e6c2
commit
59744d751f
5 changed files with 20 additions and 9 deletions
|
|
@ -62,6 +62,7 @@ Current tile-graph status:
|
|||
- the optimizer now has its own deep-dive map in `docs/optimizer-algorithm-map.md`, and the first cut from that map removed the old UV-optimizer name plus the continuous k-means cluster-boundary scout; the continuous path is now a fixed-lattice, source-first discrete chooser guided by real edge evidence
|
||||
- optimizer preparation is now split into a private `_OptimizerPrep` bundle, so the continuous path has a visible seam between "build the map" and "choose the pixels"
|
||||
- refine is now source-first too: the representative portrait still stabilizes snap, but refine and final structure choice no longer consult it, and the pinned badge smoke improved slightly from `0.07535` to `0.07485`
|
||||
- the next relax cut also paid off: removing the old relax-mode bonus while keeping the core relax stage improved the same pinned badge smoke again from `0.07485` to `0.07451`
|
||||
- after the first pruning pass, tile-graph no longer participates in pipeline phase-rerank probes and no longer carries hybrid geometry priors through its unary cost; the path is now one lattice-conditioned candidate generator plus one local discrete solver
|
||||
- this fixes the core design mismatch that had allowed repeated distant labels to create big same-color patches and opaque black background blocks
|
||||
- on the current `24x24` emblem smoke case, an end-to-end `tile-graph` run dropped from about `2.57s` on CPU to `0.61s` on CUDA on this machine
|
||||
|
|
|
|||
|
|
@ -141,6 +141,18 @@ The third optimizer cut is behavioral:
|
|||
- the dead refine/structure representative knobs were removed from `SolverHyperParams` and the tuning harness
|
||||
- the pinned cleaned-badge continuous smoke run under `artifacts/optimizer-cut-v3-source-refine-badge-126/` improved slightly: snap stayed `0.08100`, final moved from `0.07535` to `0.07485`
|
||||
|
||||
The fourth optimizer cut trims relax rather than removing it:
|
||||
|
||||
- the old `refine_relaxed_mode_weight` bonus is gone, so greedy refine is no longer biased toward the relaxed-mode selection on every candidate score
|
||||
- the core relax stage is still kept, because the earlier ablation showed that turning relax off entirely made the pinned badge worse
|
||||
- the pinned cleaned-badge continuous smoke run under `artifacts/optimizer-cut-v4-relax-bonus-badge-126/` improved again: snap stayed `0.08100`, final moved from `0.07485` to `0.07451`
|
||||
|
||||
Next after that:
|
||||
|
||||
- keep putting relax on trial, but now term-by-term instead of as a monolith
|
||||
- add a focused ablation runner for pinned badge/emblem cases before cutting more behavior
|
||||
- collapse duplicated adjacency / motif / line voices only after ablation shows which stage owns each idea
|
||||
|
||||
The next optimizer simplification pass should use that map as its cutting checklist instead of guessing from scattered helper names.
|
||||
|
||||
## High-value regression case
|
||||
|
|
|
|||
|
|
@ -373,6 +373,11 @@ At the end of relax, the optimizer keeps two things:
|
|||
|
||||
That is the machine hedging its bets before the next stage hardens everything again.
|
||||
|
||||
Recent cut:
|
||||
|
||||
- the old extra `relaxed_mode` bonus in refine is gone
|
||||
- the machine still compares the best refined state against the relaxed mode state at the end, but it no longer biases every greedy candidate score toward the relaxed mode
|
||||
|
||||
## Stage 8: Greedy discrete refine
|
||||
|
||||
Function:
|
||||
|
|
@ -476,7 +481,7 @@ These are the places where the optimizer still speaks in an overly complicated o
|
|||
- the machine still maintains two overlapping portraits of the same lattice, even though refine is now source-first and only snap still arbitrates between them
|
||||
- snap, relax, and refine all carry slightly different versions of adjacency, motif, line, and delta agreement; the same idea is being said three times with different accents
|
||||
- the candidate generator is local and the solver is discrete, but the vocabulary around it still sounds like a continuous deformation engine
|
||||
- the main entry point is now honestly named `optimize_lattice_pixels(...)`, the k-means boundary scout is gone, prep is split from decision-making, and refine no longer consults the representative portrait; those cuts removed four contradictions from the previous map
|
||||
- the main entry point is now honestly named `optimize_lattice_pixels(...)`, the k-means boundary scout is gone, prep is split from decision-making, refine no longer consults the representative portrait, and the relax-mode bonus is gone; those cuts removed five contradictions from the previous map
|
||||
|
||||
This is probably the real cutting checklist for the next optimizer pass.
|
||||
|
||||
|
|
@ -493,7 +498,7 @@ That is much simpler than the surrounding names make it sound.
|
|||
If we keep pruning, the highest-value cuts look like this:
|
||||
|
||||
1. Put relax on trial.
|
||||
The soft relaxation stage may be a useful bridge, or it may be an expensive second solver that mostly repeats refine.
|
||||
The soft relaxation stage still seems useful, but the relax-mode bonus was dead weight. The next question is which remaining relax terms are actually earning their keep.
|
||||
2. Collapse duplicate structure voices.
|
||||
Adjacency, motif, and line are important, but they should not need three near-parallel dialects unless they are truly doing different work.
|
||||
3. Decide whether snap still needs both portraits everywhere.
|
||||
|
|
|
|||
|
|
@ -1243,15 +1243,9 @@ def _discrete_refine_output(
|
|||
solver_params,
|
||||
iterations=relax_iterations,
|
||||
)
|
||||
relaxed_mode_colors = _select_colors(candidate_colors, relaxed_mode_selected)
|
||||
refine_base_energy = base_energy + (
|
||||
(candidate_colors - relaxed_context[..., None, :]).abs().mean(dim=-1) * solver_params.relax_handoff_weight
|
||||
)
|
||||
if solver_params.refine_relaxed_mode_weight > 0.0:
|
||||
refine_base_energy = refine_base_energy + (
|
||||
(candidate_colors - relaxed_mode_colors[..., None, :]).abs().mean(dim=-1)
|
||||
* solver_params.refine_relaxed_mode_weight
|
||||
)
|
||||
start_candidates = [selected, relaxed_mode_selected]
|
||||
selected = selected.clone()
|
||||
best_selected = selected.clone()
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ class SolverHyperParams:
|
|||
refine_diagonal_weight: float = 0.08
|
||||
refine_motif_weight: float = 0.12
|
||||
refine_line_weight: float = 0.10
|
||||
refine_relaxed_mode_weight: float = 0.14
|
||||
refine_candidate_extent: float = 0.70
|
||||
refine_candidate_levels: int = 7
|
||||
guided_candidate_edge_threshold: float = 0.06
|
||||
|
|
|
|||
Loading…
Reference in a new issue