learn-ml-strategy-with-phoebe / Practitioner session 8 of 10
Learn ML Strategy with Phoebe · Practitioner session 8 of 10

The Optimization Verification test

Some systems do not classify. They search. A scoring function rates candidate outputs, a search procedure hunts for the best-scoring one, and the thing the user sees is whatever the search found. Such a system has two places to be wrong and they look identical from the outside: the scoring function may have ranked the right answer below a wrong one, or the scoring function may have been perfectly correct and the search never found the right answer to score. Telling those apart is one comparison, and it decides which of two very different teams owns the next quarter.

🟠 Advanced Data scientists and ML engineers 45 min
0-3 · Welcome 3-20 · Two ways a search-based system fails 20-40 · Build-along: run the test 40-45 · Q&A
Part 0

Attribution, twice, before the bench

The last two sessions before the bench both answer the same kind of question: given an error, which component produced it. Tonight the components are a scoring function and a search. Next session they are the two stages of a pipeline. Both tests replace a debate with a measurement, and both are cheap enough to run on twenty examples in an afternoon.

Live = presented in the 45 minutes Self-study = the full depth, after class 🔍 Every diagram zooms

★ What you walk out with tonight. A three-line function that turns any wrong output of a search-based system into one of two verdicts. A tally over twenty examples that says which verdict dominates. And the sentence you take to the sprint planning: the next quarter belongs to the search team or to the modelling team, and here is the count that decided it.

LiveWhy guessing here is expensive3 min▶

The two failures cost different things to fix. A search failure is fixed with beam width, better candidate generation, more inference-time compute: engineering work, often measurable in days, and it does not touch the model. A scoring failure is fixed with more data, a better objective, a bigger or differently shaped model: research work, measurable in months, and it does not touch the search.

Teams routinely fund one while suffering from the other. The symptom that gets reported is the same either way, "the system said elk and it was a deer", and the loudest voice in the room decides. The test below removes the room from the decision.

Real world

Lanternfish spent six weeks widening the candidate list for its species pipeline because the field kept reporting confident wrong answers. The correct species had been in the list every time, sitting below the wrong one. Six weeks of search work on a scoring problem, and the extra candidates made the ranking noisier.

Self-studyThe vocabulary for tonight3 min▶
  • Scoring function - the thing that takes an input and a candidate output and returns a number. Higher is meant to mean better.
  • Search - the procedure that walks the space of possible outputs looking for the highest-scoring one. Beam search, greedy decoding, sampling with reranking, a planner, a shortlist of candidates from a cheaper model.
  • Approximate maximization - what the search actually does. It rarely finds the true maximum, and the gap between what it found and what exists is the whole of the first failure mode.
  • The reference output - the answer a human would give. You need one to run the test, and it has to be scoreable by the same function.
  • The verdict - one of two words, "search" or "scoring", per example. The tally over many examples is the deliverable.
Part 1 · covers chapter 44 and the general form in chapter 45

"The Optimization Verification test"

9 min live

Chapter 44 of Machine Learning Yearning is titled "The Optimization Verification test", and it exists because one class of system hides its own failures. Once a system searches rather than classifies, the output you see is the joint product of two components, and no amount of staring at outputs separates them. One comparison does.

LiveThe shape of system this applies to3 min▶

The test applies wherever the system produces an output by searching for the best-scoring candidate rather than by naming a class directly. If your model ends in a softmax over twelve species and you take the argmax, there is no search and no test to run: the argmax is exact. The moment the output space is too large to enumerate, a search appears, and with it a second place to be wrong.

  • Speech recognition. A scoring function rates transcripts; a decoder searches the space of word sequences. The space is unbounded, so the decoder is approximate.
  • Machine translation. Same shape. Beam search over sentences that could have been produced, scored by the model.
  • Any planner or router. A cost function over routes, a search that cannot enumerate all routes.
  • Retrieve-then-rerank. A cheap retriever proposes candidates, an expensive scorer ranks them. The retriever is the search.
  • Lanternfish's pipeline. The species stage emits a ranked candidate list per frame with a score each, produced by a cheap shortlist step and rated by the classifier head.
One example the system got wrong, two scores, one verdict One wrong example frame 4471, night infrared system chose: elk a human says: deer one scoring function Compare the scores score(deer) = 0.58 score(elk) = 0.71 no model internals need to be understood Human answer scores HIGHER The search is at fault it never found it Funds the search side beam width candidate generation inference-time compute Human answer scores LOWER The scoring function is at fault Funds the model side training data the objective the model itself Two scores decide which team owns the sprint. Nothing else needs explaining.
🔍 Click to zoom - one wrong example, two scores, two branches, two very different sprints.
LiveThe two failure modes, and why they look identical3 min▶

Write the system as two components and the failures fall out cleanly.

  • Failure one: the scoring function is wrong. It gave the correct output a lower score than a wrong one. The search did its job perfectly and returned exactly the highest-scoring candidate, which happened to be wrong. Widening the search here makes things worse, because a wider search finds more high-scoring wrong answers.
  • Failure two: the search is wrong. The scoring function would have preferred the correct output, and the search never brought it forward to be scored, or brought it forward and pruned it before the end. The model is fine. Every hour spent on training data here is wasted.

From the outside both produce the same artefact: a confident wrong answer. That is why the test compares scores rather than outputs. The score of the correct answer is the piece of evidence that the output alone never carries.

LiveThe test, in its general form3 min▶

Chapter 45 gives the general form, and it is three steps.

  1. Take an example the system got wrong.
  2. Take the correct output, the one a human would give, and score it with the system's own scoring function.
  3. Compare that against the score the system assigned to its own output.

If the correct output scores higher, the scoring function preferred the right answer and the search failed to surface it. The search is at fault. If the correct output scores lower, the search returned the true best-scoring candidate and the scoring function is what ranked the right answer down. The scoring function is at fault.

★ Try it now def verdict(correct_score, chosen_score): """Chapter 45, in three lines.""" if correct_score > chosen_score: return "search" # scoring liked the right answer, search missed it return "scoring" # search found the best score, and it was wrong
Self-studyWhat the test does not require3 min▶

This is the property that makes it worth running on a Monday morning rather than scheduling.

  • No understanding of the model. The scoring function is used as a black box that takes an input and a candidate and returns a number.
  • No understanding of the search. You never inspect the beam, the pruning rule or the ordering. The search is judged entirely by what it failed to bring you.
  • No retraining. Both scores come from the model you already have deployed.
  • No new labelled data, beyond the correct outputs, which for a classification-shaped output space you already have in the dev set labels.
  • No statistical machinery. Twenty examples give a tally, and a tally of fourteen to four is not a result that needs a confidence interval to act on.
Part 2 · covers chapter 46 and what the verdict funds

Why this saves a quarter

8 min live

The verdict is not a diagnosis for its own sake. It is a budget allocation. The two branches fund different work, cost different amounts, and in most organisations are staffed by different people who are each convinced the problem is on the other side.

VerdictWhat it meansWhat the sprint fundsTypical ownerTypical horizon
Search at faultThe correct output scores higher and was never surfacedBeam width, candidate generation, reranking depth, inference-time computeSystems and inference engineersDays to weeks
Scoring at faultThe correct output scores lower than the wrong oneTraining data, the objective, model capacity, the lossModelling and data peopleWeeks to a quarter
Near-tieThe two scores sit within noise of each otherAn objective that separates the two cases at allModelling, but a different jobIts own finding
LiveThe same test outside supervised learning3 min▶

Chapter 46 runs the identical argument in a reinforcement learning setting, where the two components are a reward function and the learning algorithm that maximises it. An agent behaves badly; the question is whether the reward function scored the good behaviour below the bad behaviour, or whether the reward function was correct and the algorithm simply failed to find the good behaviour.

The procedure does not change. Take a trajectory the agent produced, take a trajectory a human would call correct, evaluate the reward function on both. Correct trajectory scores higher means the optimisation is at fault and you tune the algorithm. Correct trajectory scores lower means the reward function is at fault and no amount of better optimisation will help, because it will optimise harder toward the wrong thing.

The pattern to carry. Any system built as "a thing that scores" plus "a thing that maximises the score" can be split by this test, whatever the two things are called in your stack: reward and policy, cost and planner, relevance model and retriever, likelihood and decoder.

LiveLanternfish's version of the test3 min▶

The species stage does not name one animal. For each frame it emits a ranked list of candidate species with a score each, and the pipeline reports the top of that list. That makes the shortlist step the search and the classifier head the scoring function, and the test becomes two concrete questions per frame.

  • Was the correct species in the candidate list at all? If not, score it directly with the classifier head anyway. Absence from the list is a property of the shortlist, not of the score.
  • How did it score against the species the pipeline chose? Higher means the shortlist and the ranking failed to bring a species the model would have preferred. Lower means the model preferred the wrong animal, and no shortlist change rescues that.
Real world

On the twenty frames run tonight, deer scored above the chosen elk on fourteen of them. The species the field wanted was already preferred by the model and was being ranked out by a shortlist tuned for latency. That is a two-week change to candidate generation, not the eight-week specialist model the team had costed.

Twenty misclassified frames, one verdict each 14 examples search is at fault 4 examples scoring at fault 2 near-tie one block per frame, sorted by verdict Search-heavy, like this one The correct species was in the list and outranked. Fund beam width and candidates. A sprint of two weeks, not a model. If it were scoring-heavy The correct species scored below a wrong one. Fund the model, the data, the objective. That is a quarter of work. The two near-ties Scores sit within 0.01 of each other. The function is indifferent, not wrong. Its own finding. A tally of 14 to 4 does not need a confidence interval to act on.
🔍 Click to zoom - the split across twenty examples, and the sprint each split would justify.
Self-studyThe honest limits of the test4 min▶
  • You need a correct output that can be scored. For a species label that is free, it is in the dev set. For an open-ended output, a translation or a summary, somebody has to write the correct answer first, and the test is only as good as that reference. Budget the human time before promising the result.
  • A tie is a finding, not a failure of the test. If the correct and chosen outputs score within noise of each other, the scoring function is not ranking the right answer down; it is failing to distinguish them at all. That funds a different piece of modelling work, an objective that separates the two cases, and it will not be found by widening a beam.
  • The reference must be reachable in principle. If the correct output is something the system's output format cannot express, the test reports "scoring" and it is really a representation problem. Check the format before reading the verdict.
  • The verdict is per example, not per system. A mixed tally is normal and useful. Fourteen to four says where the next sprint goes; it does not say the scoring function is perfect.
  • Twenty examples is a tally, not an estimate. It is enough to choose a sprint. It is not enough to publish a percentage, and it should not be written down as one.
Build-along

Run the test on twenty frames

★ 20 min · everyone builds

Bring a system of yours that searches, and the last hundred outputs it got wrong. If you have nothing to hand, use the Lanternfish candidate tables: one row per frame per candidate species, with a rank and a score from the classifier head.

Pull twenty misclassified frames that came back with a ranked candidate list. Filter to the dev split so the examples are ones you are allowed to look at, and take them in a hash order rather than by date, so you do not accidentally sample one camera or one week.

Obtain the correct output and locate it in the list. The dev set label is the correct species. Record its rank if it appears and record its absence if it does not. Absence is common and is not yet a verdict.

Score both candidates with the same scoring function. The chosen species already has a score. The correct species has one too if it was in the list; if it was not, call the scoring function on it directly. Never compare a score from one function against a score from another, and never compare against a probability that has been renormalised over a different candidate set.

Tabulate the verdict per example. Correct scores higher means search. Correct scores lower means scoring. Within a small epsilon means near-tie, and write the epsilon down: on Lanternfish's head, 0.01 on a 0 to 1 score.

Count the split. Fourteen search, four scoring, two near-ties. Look at the two near-ties by hand before you file them; they are frequently the most interesting frames in the set.

Write which team the next sprint belongs to, in one sentence, with the count in it. "Fourteen of twenty dev errors are search failures, so the next two weeks are candidate generation." That sentence survives a planning meeting; "I think it is the shortlist" does not.

★ Twenty dev errors, with both scores side by side with errors as ( select f.frame_id, f.true_species, p.chosen_species, p.chosen_score from cams.dev_frames f join cams.predictions p using (frame_id) where f.split = 'dev' and p.chosen_species is distinct from f.true_species ), listed as ( select e.frame_id, e.true_species, e.chosen_species, e.chosen_score, c.candidate_species, c.score, c.rank from errors e join cams.candidates c using (frame_id) ) select frame_id, true_species, chosen_species, chosen_score, max(case when candidate_species = true_species then score end) as correct_score, max(case when candidate_species = true_species then rank end) as correct_rank, count(*) as list_length from listed group by frame_id, true_species, chosen_species, chosen_score order by hash(frame_id) limit 20; -- correct_score null means the species never made the list, not that it scores badly
★ The verdict, and the tally that ends the argument EPS = 0.01 # scores run 0 to 1 on this head; anything tighter is noise def verdict(row, score_fn): """The test from chapter 45. Two scores in, one word out.""" correct = row["correct_score"] if correct is None: # never emitted, so score it by hand correct = score_fn(row["frame_id"], row["true_species"]) gap = correct - row["chosen_score"] if abs(gap) < EPS: return "tie" # indifferent, which is its own finding return "search" if gap > 0 else "scoring" frames["verdict"] = frames.apply(verdict, axis=1, score_fn=classifier_head) counts = frames["verdict"].value_counts() print(counts) # search 14 # scoring 4 # tie 2 owner = "search team" if counts.get("search", 0) > counts.get("scoring", 0) else "modelling team" print(f"{counts.get('search', 0)} of {len(frames)} are search failures; next sprint: {owner}")

Run it before the planning meeting, not after. The test costs an afternoon and twenty labelled examples you already own. The sprint it redirects costs six weeks. Lanternfish ran it in the seventh week of a six-week search project.

Homework

Before session 9

30 min
  1. Decide whether any system you own actually searches. Write down its scoring function and its search procedure by name. If you cannot name both, there is no test to run and that is a useful answer.
  2. Run the test on ten wrong outputs. Ten is enough to see whether the split is lopsided, and lopsided is the only reading you need.
  3. Check what your team funded last quarter against the verdict you just computed. Note whether the money went to the branch the tally points at.
  4. For any near-ties, write one sentence on what the objective would have to reward for the two outputs to separate. That sentence is the start of the next objective.
  5. Sketch your production system as a sequence of stages, one box each, and mark which stage produces the output the user complains about. Session 9 starts from that sketch.
Check yourself

Three questions

A frame is labelled deer and the pipeline said elk. The classifier head scores deer at 0.83 and elk at 0.71. Which component is at fault?

Correct output scores higher means the scoring function already preferred the right answer, so the failure is that the search did not bring it forward. Fund beam width and candidate generation, not the model.

A team plans to widen the beam because the system keeps returning confident wrong answers. The test says the correct output scores lower than the chosen one on eighteen of twenty examples. What happens if they widen the beam anyway?

When the scoring function is at fault, a better search optimises harder toward the wrong answer. The work is the model, the data and the objective.

On two frames the correct species and the chosen species score within 0.004 of each other. What should be recorded?

A tie says the function cannot tell the two outputs apart. That is a modelling job, but a different one from ranking the right answer down, and widening the search will not touch it.

Sources covered

What tonight maps to

✓ Machine Learning Yearning, chapter 44 "The Optimization Verification test": the shape of system it applies to, and the two failure modes that look identical from the outside.
✓ Machine Learning Yearning, chapter 45 The general form of the test, run on twenty Lanternfish frames with both scores computed from the deployed head.
✓ Machine Learning Yearning, chapter 46 The same test in a reinforcement learning setting, with a reward function and a learning algorithm as the two components.
◐ Machine Learning Yearning, chapters 53 to 57 Error analysis by parts. Session 9 attributes error to a pipeline stage rather than to search versus scoring.
· Beam search, decoding algorithms and search implementation Not covered by design. The verdict says which side to fund; the algorithms belong to an NLP or systems course.

Session 8 cheat sheet

Only for systems that searchA scoring function plus a search over candidates. An exact argmax has no test to run.
Two failure modes, one symptomRight answer ranked below a wrong one, or right answer never found. Both look like a confident wrong output.
The test in one lineScore the human's answer, score the system's, compare.
Higher means searchThe scoring function preferred the right answer and the search missed it.
Lower means scoringThe search found the true best score, and the score was wrong.
Different teams, different clocksSearch work is days to weeks. Scoring work is weeks to a quarter.
A tie is a findingThe function is indifferent, not wrong. That funds a new objective, not a wider beam.
Twenty examples is enoughTo choose a sprint. Not to publish a percentage.