Where we start
You have a frozen model, a locked test set, a declared noise plant, a detector that finds wrong labels out of sample, a bench that scores every edit, and a way to find the weak slice without peeking. What you do not have yet is the document. A data edit that lives in someone's notebook is gone the day they change teams. A data edit written as a spec can be audited by a reviewer, rerun by a stranger, and reused when the next model arrives.
★ What you walk out with tonight. A combination of data edits that takes the frozen model to 96.6 percent against a 91.4 percent baseline, the discipline to judge it against twenty-seed means rather than one lucky digit, a filled one-page data-edit spec another person could rerun, a 20-flag audit that estimates the detector's precision without an answer key, and a stopping rule written down before the next cleaning pass starts.
Beat the bench, model untouched
5 min liveThe Data-Centric AI Competition of 2021 set the format this capstone copies: "improve a dataset given a fixed model", scored on accuracy, submissions closed on 4 September 2021. Tonight's version runs on the session 4 bench. The best preset on the 800 rows alone is 96.0 percent, 480 of 500, from relabelling the flags and shifting the weakest digit. The best combination anywhere on the bench is 96.6 percent, 483, on the 1,297 rows with relabelling and the ambiguous rows dropped. The ceiling, the same model on the true labels, is 97.8 percent. The hard part is not finding a higher number; it is knowing whether a higher number means anything.
LiveThe capstone rules2 min▶
Only data edits. Relabel, remove, drop ambiguous rows, add shifted copies, add the 497 extra rows: anything the knobs on the session 4 bench allow, in any combination.
The model and the seed are frozen. kNN with k = 10, squared distance on the 64 raw pixels, seed 20210921 for the split and the plant. If you want to try k = 5, that is a model-centric experiment and belongs in a different document.
The test set is untouched. Not relabelled, not filtered, and not used to pick the edit. Reading per-digit test accuracy after the choice is fine; choosing by it is not.
Every edit is logged. A row that changed without a line in the log is a row nobody can defend. Part 2 is that log.
LiveHow to read a win2 min▶
On 500 test digits, one digit is 0.2 points. So 96.6 against 96.4 is one digit, and one digit on one seed is not a win. It could flip if the split moved. The honest comparison is against the twenty-seed sweep, where it exists: relabel averages 94.45, relabel plus shift 94.52, and collect plus clean 94.60. Those three edits look different on the shipped seed, and over twenty seeds they are within 0.15 points of each other, less than one test digit. Treat them as about equal.
The 96.6 combination beats the best 800-row preset by three digits, 0.6 points, on one seed. That is a promising lead, not a finding: the sweep did not run it. Two combinations tie at 483, the 1,297 rows with relabel and drop ambiguous, and the 1,297 with remove, drop ambiguous and shift. When two edits tie, prefer the one with fewer steps and fewer rows: it is cheaper to explain and to rerun.
Self-studyWhy the ceiling is not 100 percent2 min▶
Trained on the true labels, the frozen model still misses 11 of the 500 test digits: 489 correct, 97.8 percent. Those misses are not label errors in training, because there are none. They are digits the model cannot separate: a 4 whose ten nearest training images happen to be 9s, a sloppy 8 that sits in the 3s' neighbourhood. No data edit to the labels can fix them. Only more coverage near those shapes, or a different model, could.
That makes the gap you are allowed to close 32 digits, from 457 to 489, and not 43. On this seed the best combination closes 26 of them. Quoting "96.6 against a perfect 100" would overstate what is left for the data to do.
The competition that fixed the model. DeepLearning.AI and Landing AI ran the Data-Centric AI Competition on a noisy set of handwritten Roman numerals, with every entrant training the same model and changing only the data: "fixing incorrect labels, adding examples that represent edge cases, apply data augmentation". Submissions closed on 4 September 2021 and were scored on accuracy. The fixed model is reported as a cut-down ResNet50 on 32 by 32 images, with about 1,500 starting images and a cap of 10,000; those details come from participants' write-ups, not an official page.
Write the edit down so it outlives the model
5 min liveA data-edit spec is one page with seven fields. Each field answers a question somebody will ask six months from now, usually when a new model arrives or a number looks too good. Which model was frozen, and how? Which test file, and was it ever touched? Which version of the label rule? Which detector, with which settings? Which rows changed, from what to what, and who said so? What did it buy on both counters? And what does the result not prove?
LiveThe edit log: one line per touched row3 min▶
The edit log is the field the other six exist to make trustworthy. One line per row the edit touched: the row id, the old label, the new label or "removed", what the detector said and how strongly, who reviewed it, and which guideline version they reviewed it against. With that line, any single change can be questioned and reversed. Without it, the only way to undo a bad cleaning pass is to throw the whole dataset away.
Here is a constructed sample, four lines long. The rows, labels and votes are real outputs of the session 3 detector on the 800 training digits; the reviewer column and the decisions on the two false alarms are constructed to show what a reviewed log looks like.
| Row | Old | New | Detector votes (of 10) | Reviewer | Guideline |
|---|---|---|---|---|---|
| 5 | 1 | 7 | 8 for 7, 2 for 1 | R1: confirmed, it has a top bar | v2 |
| 25 | 7 | 1 | 7 for 1, 3 for 7 | R1: confirmed, single stroke | v2 |
| 0 | 8 | 3 | 7 for 3, 3 for 8 | R2: confirmed, open on the left | v2 |
| 63 | 3 | 3 (kept) | 7 for 8, 3 for 3 | R2: false alarm, label stands | v2 |
Row 63 is the one that matters. The detector suggested 8; the digit is a 3. On the bench, the 13 false alarms among the 98 flags were all relabelled wrongly, because nobody reviewed them. A reviewer column is what turns a detector's suggestion into a decision.
LiveThe freeze list, and the rest of the form2 min▶
Freeze list. The model and every setting that decides its output: kNN, k = 10, squared Euclidean distance on 64 integer pixels, distance ties to the earlier training row, vote ties to the nearest tied neighbour, seed 20210921, no preprocessing, accuracy as the metric, and a checksum of the test file so anyone can prove it is the same 500 digits.
Test-set rule. Never edited, never used for decisions. The MIT notes: evaluation examples "should only be used for computing evaluation scores, not for any modeling decisions."
Guideline version from session 2, detector and settings from session 3 (four folds, per-class thresholds, out of sample), result table with both counters from session 4, and what not to claim: no one-seed, one-digit wins; no precision or recall quoted from a declared plant as if it were the real noise.
Ng's closing checklist makes a good acceptance test for the finished page. Good data is "defined consistently", has "cover of important cases", has "timely feedback from production data", and is "sized appropriately". The guideline field answers the first, the slice work of session 5 the second, the result table the fourth. The third is production monitoring, and Data Observability ↗ owns it.
Self-studyVersioning the dataset like code3 min▶
A spec is only as good as its link to the exact rows it describes. The simplest working pattern: keep the raw labels read-only, store the edit log as a small table next to them, and build the training set by applying the log to the raw labels. Then the dataset version is the log's version, a diff between two versions is a diff between two logs, and a reviewer can read a change the way they read a pull request.
Three habits make it hold up. Give the edit log a version that moves with the guideline version, so a rule change forces a new log. Record the detector settings in the log header, so a rerun cannot silently use different folds. And never overwrite a label in place: an overwritten label is a change with no author and no reason.
Three transcripts of the same sentence. Ng's example of inconsistent labels is speech: one labeller writes "Um, today's weather", another "Um... today's weather", a third "Today's weather". None is wrong; the instruction left room. The fix is a guideline version, and the reason the spec records it is that a relabelled row is only correct relative to a rule. Change the rule and the same row can become an error again.
Audit a sample, then stop on a rule
5 min liveAt work there is no declared plant. Nobody can tell you the detector's precision is 86.7 percent, because nobody knows which labels are wrong. What you can do is draw a random sample of the flags and check them by hand. That estimate goes on the spec, with its sample size. Then a second question: once the first pass is done, is another pass worth it? The answer is a rule written before the pass, not a feeling after it.
LiveEstimate precision by hand-checking a random sample3 min▶
Northcutt, Athalye and Mueller had exactly this problem on ten public test sets: an algorithm flagged candidates, and nobody knew which were real. Their design is the one to copy. Each flagged item went to five crowd workers on Mechanical Turk, and it counted as a label error if fewer than 3 of the 5 agreed with the given label. Across the ten datasets, 51 percent of the flagged candidates were confirmed on average, and the spread was wide: on MNIST, only 15 of 100 flags were real errors. Precision is a property of the detector on this data, not of the method.
The build-along runs the small version. From the 98 flags, a random sample of 20 with seed 6: 17 were real errors, an estimate of 85 percent. On the bench we can compare it with the true precision, 86.7 percent, because the plant is declared. At work you only have the 85. With 20 items the estimate is rough: one more or one fewer real error moves it by 5 points. Write the sample size next to the number on the spec, and check a larger sample before a precision figure decides anything expensive.
LiveThe stopping rule2 min▶
Run the same detector a second time on the relabelled 800. It flags 6 rows, and 5 of them are labels that are still wrong. That sounds efficient until you look at the denominator: 61 wrong labels were left after pass 1, so pass 2 finds 5 of them and misses 56. Test accuracy moves from 478 to 479, one digit, noise. Wrong labels fall from 61 to 57.
The rule: stop when a pass flags few rows and the audited precision of its flags falls, and move the effort to where the remaining errors actually come from. The 56 the detector cannot see are the look-alikes that sit deep in the other digit's neighbourhood; no amount of re-running finds them. They are a guideline problem (session 2) or a coverage problem (session 5). Write the thresholds down before the pass starts. A constructed example: "stop when a pass flags fewer than 10 percent of the previous pass's rows, or when a 20-flag audit finds fewer than half real."
Self-studyWhy the audit has to be random2 min▶
It is tempting to review the top of the list, the flags the detector is most confident about. Those are the easiest ones, and their precision is higher than the rest. An audit of the top 20 estimates the precision of the top 20, and the spec would quote it for all 98. A random draw from all the flags, with the seed recorded, estimates the precision of the whole pass, and anyone can redraw the same sample to check the reviewer.
The same logic sets who reviews. The labelerrors.com design used five independent workers and a 3-of-5 rule so that one tired reviewer could not decide an item. For a small internal audit, two reviewers who disagree on a flag is itself a finding: the guideline has a hole there.
A model ranking that flips on corrected labels. On ImageNet with corrected test labels, ResNet-18 outperforms ResNet-50 if the share of originally mislabelled test examples rises by just 6 percent; on CIFAR-10, VGG-11 outperforms VGG-19 at 5 percent. A result table built on an unaudited test set can pick the wrong model. That is why the spec's test-set field records who checked it, and why the audit design comes from the paper that found the flip.
What to ask for, if you lead the team. Three things, before the cleaning starts, not after. The one-page spec, filled, so someone else could rerun it. The audited precision of the detector with its sample size, "17 of 20", never a bare percentage. And the stopping rule, written in numbers before the next pass, so that "one more pass" is a decision the page makes and not a mood the team is in.
Beat it, audit it, write it down
★ 22 min · everyone buildsFour steps. The first is on the session 4 bench in your browser; the next two continue from session 3's script in numpy, steps 1 to 5, with its variables still in memory; the last is a page of plain text. Every number printed below is what the code produces.
Beat 96.0 on the bench, and record every readout. Open the session 4 bench, go below the eight presets to the knobs, and look for a combination above the best 800-row preset. Add the 497 extra rows, relabel the flags, drop the ambiguous rows, keep the detector out of sample. The readout prints 96.6 percent. Write down all eight numbers, not just the headline: the spec needs the cost as well as the gain.
Audit a random sample of 20 flags. Back in Python, on the 800. Draw 20 of the 98 flags with a recorded seed and check each one. On the bench the true digit stands in for the human reviewer; at work this line is a person with the guideline open.
Run a second pass, and read it against the stopping rule. Take the relabelled labels as the new given labels, recompute the out-of-sample votes with the same four folds, and run confident learning again. Count what it flags, how many of those are still wrong, and what it does to the test score.
Write the spec. One page, plain text, in the repository next to the data. The settings below are the real ones from these six sessions; the guideline version, reviewer names, file names and the stopping thresholds are a constructed example of how to fill the fields. Leave the checksum as a field until you compute it on your own test file.
| Same frozen model, same 500 test digits | Training rows | Correct | Accuracy |
|---|---|---|---|
| The labels you were given | 800 | 457 | 91.4% |
| Relabel the flags, one pass | 800 | 478 | 95.6% |
| Relabel, then a second pass | 800 | 479 | 95.8% |
| Best on the 800 alone: relabel + shift the weakest digit | 1,084 | 480 | 96.0% |
| Best overall: 1,297 rows, relabel, drop ambiguous | 1,154 | 483 | 96.6% |
| The true labels (knowable only because the plant is declared) | 800 | 489 | 97.8% |
Read the audit and the second pass together. The audit says the first pass was mostly right: about 85 percent of its flags were real, on a sample of 20. The second pass says it was also mostly done: 6 flags, one test digit. A detector that is accurate and exhausted is the moment to stop running it and start reading the 56 errors it cannot see.
After the capstone
60 min- Write the spec for your own dataset. All seven fields plus the audit and stopping rule, one page. Leave a field visibly empty rather than guessing; an empty field is a to-do, a guessed one is a future argument.
- Run a 20-flag audit. Draw 20 flags from your detector at random, with a recorded seed, and have them checked by someone holding the guideline. Write the result as "k of 20", not a percentage.
- Set your stopping rule in numbers before the next pass. How few flags, and how low an audited precision, ends the cleaning? Write it on the spec, then run the pass.
- Hand the spec to someone who did not build it and ask them to rerun it. Every question they ask is a missing field. Every number they cannot reproduce is a missing line in the freeze list.
Three questions
Clear all three and session 6 gets stamped in your passport.
1 · On the shipped seed, one combination of edits scores 483 of 500 and another scores 482. What do you conclude?
The sweep shows how small real differences are: relabel, relabel plus shift and collect plus clean average 94.45, 94.52 and 94.60, all within one test digit. A single-seed, single-digit gap is below what this test set can measure. D breaks the test-set rule outright.
2 · At work there is no declared plant. How do you estimate your detector's precision?
Northcutt, Athalye and Mueller checked every flag with five workers and a 3-of-5 rule, and found precision ranging from 15 of 100 on MNIST to much higher elsewhere: it depends on the data, so neither the bench's number nor the study's average transfers. A top-20 review measures only the easiest flags.
3 · A second detector pass flags 6 rows, and test accuracy moves from 478 to 479. What should the team do?
Pass 1 moved 72 wrong labels; pass 2 moved four and one test digit. The stopping rule, written before the pass, says a pass this small ends the cleaning. C is session 3's leak: 95.2 percent precise and only 30.1 percent recall, because each row votes for itself.
What this session teaches, and where it came from
Every fact on this page, and its verification tier, is recorded in the course's source map.
Session 6 cheat sheet · pin this
This is the last of the six. Go back to the course home for the full map, then take the spec where it leads. The next round of error analysis, the spreadsheet that tells you which errors to fix first, lives in ML Strategy ↗. The timely feedback from production that Ng's checklist asks for, catching the data drifting after the spec is signed, lives in Data Observability ↗.