Charge candidates for detail the target does not have - #93
Merged
Conversation
rasros
force-pushed
the
staleness-top-tier
branch
from
August 17, 2026 15:45
9e991f1 to
8cfd257
Compare
rasros
force-pushed
the
detail-objective
branch
from
August 17, 2026 15:45
eac1d8b to
ae74d4f
Compare
rasros
force-pushed
the
detail-objective
branch
from
August 17, 2026 15:52
ae74d4f to
ece3482
Compare
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.
The other objectives all reward agreement with the reference at a pixel or an edge, and local search can buy that agreement by adding detail the target does not have — stipple a flat region and the edge map lights up in roughly the right places. Measured: on a 45-minute single-epoch run the round score fell 64% against a three-epoch run while the evaluator scored the two within 0.000004 of each other. The search was paying for detail no perceptual judge would credit, and the drawing showed it.
detail()is deflate over the raw RGB bytes of the render — not the PNG, which is already deflated and would mostly measure the encoder. It reads the render, so rewriting the source cannot talk it down.One-sided, and this is the important part
The objective is
max(0, detail(candidate) − detail(reference)) / detail(reference).It first went in as a symmetric distance, on the reasoning that a pure minimum would make an empty drawing optimal on this axis. Both halves of that were wrong.
Symmetric breaks on any noisy target. Noise is the most incompressible thing an image can carry, and generated or photographed inputs carry some. On the duck at working resolution:
A symmetric reading calls a correct vector render 90% wrong on this axis, and the only way to improve it is to add incompressible speckle. The regulariser would drive exactly the artefacts it exists to suppress.
The degenerate needed no guard. An empty drawing does score 0 here, but it wins this one axis while losing colour, edge and shape — one win against three losses is dominated whatever the arity. I had assumed it would split 2–2 and become incomparable; it cannot, because it can only win one axis.
Sanity check on the real case: the current duck SVG against its clean target scores exactly 0.0 excess, so this is inert until a candidate actually gets busier than the target.
Side effect: the arity is now even
With three objectives, wins and losses cannot split evenly, so every pair is comparable, the relation is a total tournament, and the top tier holds one candidate. A 2–2 split is the first time two candidates can be mutually unbeaten because they are good at different things — genuine fronts exist now. It also weakens selection pressure, which is the documented reason majority replaced unanimity, so it cuts both ways.
build_objectivesderives the vector fromSCORER_METRICSrather than a hardcoded triple, so a registered measure cannot silently be left out of ranking again — which is how the blend happened. The ranking cache key had the same hardcoding and would have served stale rankings; it derives from the registry too.Known limit
A striped image compresses nearly as small as a blank one — 67 bytes against 50. That is correct (a regular pattern genuinely is low complexity) but it means this charges for irregular detail specifically. Repetitive artefacts — stipple in a grid, hatching, duplicated strokes — will barely register, and catching those would need a measure other than compressed size.