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

Error analysis by parts

Lanternfish's production system is not one model. A motion detector decides whether a frame contains an animal at all, and only then does the species classifier name it. The dev set records 120 wrong answers and says nothing about which of those two components produced them, because a dev set only ever sees the end of the pipeline. Tonight you split the 120 by stage, measure each stage against a human doing that stage's job, and find out that eighteen errors have been sitting in the wrong column since session 3.

🔴 Hardest Data scientists and ML engineers 45 min
0-3 · Welcome 3-20 · Attributing an error to one stage 20-40 · Build-along: attribute all 120 40-45 · Q&A
Part 0

A pipeline hides which part is failing

A single model has one place to be wrong. A pipeline has one per stage, plus the seams between them, and the output the user sees carries no marking to say which. Session 8 split a search-based system into a scoring function and a search. Tonight the split is by stage, the attribution rule is different, and the answer changes which project gets funded next week.

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

★ What you walk out with tonight. A per-stage attribution of every dev error, produced by a procedure rather than by opinion. Two error rates measured against two different human-level estimates, so the stage furthest from a human is visible rather than assumed. And the reading that saves the most money of anything in the track: when every stage is already at human-level and the system still is not, the pipeline's decomposition is what is wrong.

LiveWhy the error category is not the error's owner3 min▶

The session 3 spreadsheet asks what an error looks like. That is exactly the right question when there is one model, because what an error looks like is a property of the one thing that produced it. With two stages the question quietly becomes wrong, because an error can look like a classifier error and have been created two steps earlier.

The clearest case is a frame with no animal in it. The classifier is handed that frame and asked which species it contains. Whatever it answers is wrong, and there is no version of the classifier that answers correctly, because the question it was asked has no correct answer. The error is real, the classifier produced it, and the classifier is not the thing to fix.

Real world

Lanternfish's error sheet has "empty frame called animal" at 18 of 120, filed alongside "deer mistaken for elk". Both rows describe a species answer that was wrong. One of them is a species problem. The other is a motion detector that fires on a branch moving in the wind, and it had been in the classifier's backlog for two quarters.

Self-studyThe two-stage vocabulary3 min▶
  • Stage. A component with an input, an output and a job you can describe in one sentence. Lanternfish has two: motion detector, species classifier.
  • The seam. What one stage passes to the next. Here it is a single boolean, "this frame contains an animal", plus the frame itself.
  • Perfect input. The output the first stage should have produced, written by a human. The whole method rests on being able to make one.
  • Attributed error. An error assigned to the stage that produced it, which is not always the stage that emitted it.
  • Per-stage human-level. How well a person does that stage's job alone, with only that stage's input. The detector's human-level and the classifier's human-level are different numbers and have to be estimated separately.
  • A flawed pipeline. Every stage at or near its own human-level, and the system still short. The decomposition is the fault.
Part 1 · covers chapters 53 and 54

"Error analysis by parts" and "Attributing error to one part"

9 min live

Chapter 53 is titled "Error analysis by parts" and chapter 54 is "Attributing error to one part". Between them they give a procedure that needs no new model and no retraining: give the later stage the input it should have had, run it again, and see whether the error survives.

LiveThe method: hand stage two a perfect input3 min▶

Take one error. Look at what the first stage passed to the second. Replace it with what a human says it should have been, and re-run the second stage on that corrected input. Two outcomes, and each is a verdict.

  • The error disappears. The second stage handles the corrected input correctly, which means it was always capable of getting this example right and was prevented by what it was given. The error belongs to the first stage.
  • The error persists. The second stage gets it wrong even with a perfect input. Nothing upstream was responsible. The error belongs to the second stage.

The rule generalises up the chain. With three stages, correct stage one and re-run stages two and three; whatever survives is not stage one's. Correct stages one and two, re-run stage three; whatever survives belongs to stage three. Each correction peels one stage off the front of the blame.

One empty frame, traced twice through the same two stages As it happened Frame 8812 empty frame no animal in it a branch moved Motion detector says: animal here this is the error nobody logged it Species classifier asked to name the animal in an empty frame. says: deer Recorded in the session 3 sheet as "empty frame called animal" 18 of 120, beside the species rows the classifier takes the blame With the detector decision hand-corrected Frame 8812 the same frame nothing altered same classifier Detector decision hand-corrected to: no animal present what it should say Species classifier is never asked no question, no answer, no error The error is gone so it was the detector's error all 18 of these move to the detector no classifier fix could help Correct the input, re-run, and see what survives. What vanishes was never stage two's.
🔍 Click to zoom - the same frame twice, and the correction that moves the error to its real owner.
LiveThe eighteen errors that were in the wrong column3 min▶

Of Lanternfish's 120 dev errors, 18 are frames with no animal in them that the pipeline named a species for. Run the method: correct the detector decision to "no animal", and the classifier is never invoked. All 18 vanish. Not one of them survives, because none of them was ever a species question.

That is a sixth of the error budget moving stage in an afternoon. The classifier's share of the dev set drops from 120 wrong to 102, and 18 errors join a component that nobody had been measuring at all.

The category that does not move, and why that matters. "Animal half out of frame" at 22 of 120 is the row everyone expects to be a detector problem. Correct the detector on those frames and it already says "animal present", correctly, because there is an animal in the frame. The errors survive. They are species errors on a hard crop, and they stay with the classifier. Attribution is a measurement, not a guess about which stage sounds responsible.

LiveWhy the spreadsheet cannot find this on its own3 min▶

The session 3 sheet has one row per misclassified image and one column per category, and the categories are written by a person looking at what the error looks like. Every column it can hold is a description of the output. None of them is a claim about which component made the output that way, and no amount of care in filling it in produces one, because the information is not in the image.

The fix is a column, not a new sheet. Add "stage" beside "category", populate it with the attribution procedure rather than with a judgement, and the ceiling arithmetic from session 3 starts ranking projects that belong to two different teams against each other honestly.

Real world

Lanternfish's sheet had the motion-trigger filter sitting in the classifier team's backlog, competing for the same engineer as the deer-versus-elk model. With a stage column it is the detector team's only project, it does not compete with anything, and the two can run in the same two weeks.

Part 2 · covers chapters 56 and 57

Each stage against its own human-level, and the flawed pipeline

8 min live

An attributed error count is not yet a decision. Eighteen against 102 looks like an easy call, until you ask what a person achieves at each of those two jobs. Chapter 56 measures each part against a human doing that part alone, and chapter 57, "Spotting a flawed ML pipeline", says what to conclude when every part passes and the system still fails.

StageIts jobAttributed dev errorsError rateHuman-level for that stageGap
Motion detectorDoes this frame contain an animal18 of 1201.8 percent of 1,000 frames0.5 percent1.3 points
Species classifierWhich animal is it102 of 12010.2 percent of 1,000 frames1.5 percent8.7 points
Whole systemName the animal in the frame120 of 12012.0 percent2.0 percent10.0 points
LiveMeasuring a stage against a human doing that stage3 min▶

Each human-level estimate is its own small study, and it has to give the person the same input the stage gets and no more. Show a labeller a single frame and ask only "is there an animal in this", and count how often they are wrong: that is the detector's human-level, and on Lanternfish's night infrared it is about 0.5 percent. Show a labeller a frame that definitely contains an animal and ask which species: that is the classifier's human-level, about 1.5 percent, higher because deer and elk at forty metres in infrared are genuinely hard.

Then the ranking is by gap, not by count. The detector has 18 errors and is 1.3 points from a person. The classifier has 102 and is 8.7 points from a person. The classifier is the stage to fund, and now that is a measured statement rather than the thing everyone already believed.

Counts and gaps can disagree. If the detector's human-level had come out at 1.7 percent, its 1.8 percent would be 0.1 points from a person and the 18 errors would be close to unavoidable, whatever anybody wanted to build. The count tells you the size of the prize; the gap tells you whether it is available.

Each stage against a human doing that stage alone 12% 0 furthest from human-level Motion detector 1.8 percent, 18 errors human-level 0.5, gap 1.3 Species classifier 10.2 percent, 102 errors human-level 1.5, gap 8.7 dashed line = human-level If every stage were at human-level and the whole system still was not, there would be no stage left to fund. The fault is then the decomposition itself: the seam throws away what the next stage needed, or the task is split in the wrong place. Chapters 47 to 52 hold the alternative, one model from raw frame to species. Check the stages first. Redesign is dear. Rank by gap, not by count. 18 errors 1.3 points off beats 102 errors 8.7 points off.
🔍 Click to zoom - two stages, two human-level lines, and the reading when both bars sit on their line.
Live"Spotting a flawed ML pipeline"3 min▶

Chapter 57 is titled "Spotting a flawed ML pipeline", and the diagnosis it names is the one nobody looks for, because it is invisible to every stage-level metric on the dashboard. Suppose the detector reaches 0.5 percent, matching a person, and the classifier reaches 1.5 percent, matching a person, and the whole system is still wrong on 8 percent of frames. Every part passes. The system fails. There is no stage to fund.

What is left is the decomposition. The two candidates are always the same two.

  • The seam is too narrow. The detector passes a boolean, and the classifier never learns that the detector was uncertain, or where in the frame the motion was. A person doing the whole job uses information the pipeline deletes at the seam.
  • The split is in the wrong place. Deciding "animal present" and deciding "which species" may not be separable on infrared at forty metres: the evidence that says "animal" is the same evidence that says "deer". A cut that a human does not make is a cut that costs accuracy.

Chapters 47 to 52 hold the alternative, end-to-end learning, one model from raw frame to species name with no seam to lose information at. It is an architecture decision with its own trade-offs, and the deep learning course owns them.

Self-studyThe honest limits, and what the attribution does to the ceiling sheet4 min▶
  • Perfect input means hand-labelling. Somebody watches 120 frames and writes the detector decision each should have got. That is roughly a day of one person's time, and it is the cheapest day in the quarter: it reassigns a sixth of the error budget and it never needs redoing for this dev set.
  • It only works where you can produce the corrected output. A boolean is easy. A corrected bounding box is a morning. A corrected intermediate embedding cannot be written by a human at all, and for that seam the method does not apply.
  • The re-run has to be the real stage two. Not a retrained one, not one with a different threshold. You are asking what the deployed classifier would have done with a better input, and that question has one honest implementation.
  • It changes the ceiling sheet, not just the labels. Session 3 ranked projects by the share of errors they could remove. Moving 18 errors out of the classifier's column shrinks the classifier's total to 102 and makes every classifier project's ceiling a slightly smaller fraction, while the motion-trigger filter now sits against a detector budget of 18 rather than competing inside a budget of 120.
  • The order of work changes with it. Two projects owned by two teams are not in the same queue. The detector work and the classifier work can start in the same week, which is a scheduling fact the single-column sheet could not express.
  • Every error still counts the same. Attribution does not weight severity. A mislabelled endangered species and a blurry deer are still one error each, on either side of the stage column.
Build-along

Attribute all 120

★ 20 min · everyone builds

The corrected detector decisions are supplied for all 120 frames, so the hand-labelling day is already spent. Bring your own pipeline if you have one; the shape of the code is the same wherever the seam is.

Pull all 120 dev errors with their session 3 category. Night infrared blur 42, deer mistaken for elk 24, animal half out of frame 22, empty frame called animal 18, label was wrong 14. Check the total before going further; an attribution run on 118 rows is a debugging session, not a finding.

Attach the hand-corrected detector decision to each row. In the exercise the column is given. In your own pipeline this is the day of labelling, and it is worth writing down who did it and when, because a second person will disagree on a handful of frames and you want that visible.

Re-run the classifier on the corrected inputs. The deployed classifier, unchanged. Where the corrected decision is "no animal", the classifier is not called at all, and that absence is the result.

Count what survives. 120 before, 102 after. The 18 that vanished are detector errors; the 102 that remain are classifier errors, including all 22 half-out-of-frame ones, which is the result that surprises the room.

Produce a per-stage error rate and compare each to its own human-level. Detector 1.8 percent against 0.5, gap 1.3. Classifier 10.2 percent against 1.5, gap 8.7. Rank by gap. If either stage lands within a few tenths of its human-level, say so out loud: that stage is close to done and further work on it is close to unavailable.

Rewrite the session 3 sheet with a stage column, and note which projects moved. The motion-trigger filter changes owner and stops competing with the classifier backlog. Everything else stays with the classifier against a smaller denominator. Write the two sentences that tell each team what it now owns.

★ All 120 dev errors, with the seam value the detector produced select f.frame_id, f.true_species, p.detector_says_animal, p.chosen_species, e.category, h.corrected_detector_call -- the hand-labelled truth for the seam from cams.dev_frames f join cams.predictions p using (frame_id) join cams.error_sheet e using (frame_id) join cams.seam_labels h using (frame_id) where f.split = 'dev' and p.chosen_species is distinct from f.true_species order by e.category, f.frame_id; -- expect 120 rows: night infrared blur 42, deer mistaken for elk 24, -- animal half out of frame 22, empty frame called animal 18, label was wrong 14
★ Re-run stage two on a perfect stage-one output, and see what survives DEV_N = 1000 detector_errors, classifier_errors = [], [] for row in dev_errors.itertuples(): if not row.corrected_detector_call: # a human says there is no animal here, so stage two is never invoked detector_errors.append(row.frame_id) continue again = classifier(row.frame_id) # the deployed model, unchanged if again != row.true_species: classifier_errors.append(row.frame_id) else: detector_errors.append(row.frame_id) # fixed by a better input, so upstream print(len(dev_errors), "errors before") # 120 print(len(detector_errors), "belong to stage one") # 18 print(len(classifier_errors), "survive stage two") # 102 for stage, errs, human in [("detector", len(detector_errors), 0.5), ("classifier", len(classifier_errors), 1.5)]: rate = 100 * errs / DEV_N print(f"{stage:11} {rate:5.1f} percent human-level {human:4} gap {rate - human:5.1f}") # detector 1.8 percent human-level 0.5 gap 1.3 # classifier 10.2 percent human-level 1.5 gap 8.7
CategoryDev errorsStage that produced itProjectWhose backlog now
Night infrared blur42ClassifierInfrared denoising passClassifier team
Deer mistaken for elk24ClassifierDeer-vs-elk specialist modelClassifier team
Animal half out of frame22ClassifierOcclusion augmentationClassifier team
Empty frame called animal18DetectorMotion-trigger filterDetector team, moved
Label was wrong14Neither: the dev setRe-label the dev setWhoever owns the data

The row at the bottom is worth a minute of its own. Fourteen errors are wrong labels, which is not a stage failing but the measuring instrument being wrong. It appears in the stage column as neither, and it is still the cheapest points on the sheet.

Homework

Before session 10

40 min
  1. Draw your production system as boxes and arrows, one box per stage, and label every arrow with what actually crosses it. The arrows are where the method attaches.
  2. Pick the seam you can hand-correct most cheaply and correct it for twenty errors. Twenty is enough to see whether a stage is holding errors that are not its own.
  3. Write a human-level estimate for each stage, with the instruction you would give the person doing that stage alone. If you cannot write the instruction, the stage is not as separable as the diagram suggests.
  4. Add a stage column to your error sheet and re-sort. Note any project whose owner changed, and any two projects that can now run in parallel.
  5. Bring the re-sorted sheet to session 10. It is the input to the bench.
Check yourself

Three questions

The classifier named a species on a frame that contains no animal. The error sheet files it as a species error. Who owns it?

An error can look like a classifier error and belong to the stage before it. Any answer the classifier gives on an empty frame is wrong, so no classifier change removes it. All 18 of these move stage.

The detector holds 18 attributed errors against a human-level of 0.5 percent; the classifier holds 102 against a human-level of 1.5 percent. Which stage do you fund?

Rank by distance from human-level, not by error count. The count says how big the prize is; the gap says how much of it is actually available.

Both stages have reached their own human-level and the system as a whole is still wrong on 8 percent of frames. What does that say?

When no stage is behind a person and the system still is, there is no stage left to fund. That is a flawed pipeline, and the fix is the design of the split rather than any component in it.

Sources covered

What tonight maps to

✓ Machine Learning Yearning, chapter 53 "Error analysis by parts", run on the two-stage detector-then-classifier pipeline behind the Lanternfish dev set.
✓ Machine Learning Yearning, chapter 54 "Attributing error to one part": feed stage two a hand-corrected stage-one output and keep what survives. All 120 errors attributed.
✓ Machine Learning Yearning, chapter 56 Each part compared against a human-level estimate for that part alone, and the ranking by gap rather than by count.
✓ Machine Learning Yearning, chapter 57 "Spotting a flawed ML pipeline": every stage at human-level and the system still short means the decomposition is the fault.
◐ Machine Learning Yearning, chapters 47 to 52 End-to-end learning as the alternative to a pipeline. Named as the architecture decision; the deep learning course owns its trade-offs.
· Object detection architecture and training Not covered by design. The attribution says which stage to fund; how to build a better detector belongs elsewhere.

Session 9 cheat sheet

Correct the input, re-runError disappears means stage one. Error persists means stage two.
18 of 120 change ownerEmpty frames named as a species were never a species question.
Half out of frame does not moveThe detector fired correctly there. Attribution is measured, not guessed.
Category is not ownerThe session 3 sheet records what an error looks like. Add a stage column.
One human-level per stageSame input the stage gets, nothing more. Detector 0.5, classifier 1.5.
Rank by gap1.3 points against 8.7. The count is the prize; the gap is what is available.
All stages passing, system failingThe decomposition is the fault. A narrow seam or a split in the wrong place.
A day of labelling120 corrected seam values reassign a sixth of the error budget, once.