{"course":{"slug":"evaluating-ai","title":"Knowing If It Works","url":"https://addaly.com/learn/evaluating-ai","level":"intermediate","track":"build"},"lesson":{"slug":"evaluating-vision-models","title":"Images: the background the model is actually reading","url":"https://addaly.com/learn/evaluating-ai/evaluating-vision-models","position":36,"of":76,"minutes":9,"answer":"Vision sets leak through sessions and reward shortcuts in the background, so split by capture session, test with the correlation deliberately broken.","keyIdea":"Vision sets leak through sessions and reward shortcuts in the background, so split by capture session, test with the correlation deliberately broken, and report accuracy under the blur and low light your users' phones actually produce."},"body":{"format":"markdown","text":"## The three tasks and their metrics\n\n**Classification** uses accuracy per class and the same confusion matrix arithmetic as anywhere else.\n\n**Detection** uses mean average precision at an intersection-over-union threshold. IoU is the overlap of the predicted and true boxes divided by their union, and a prediction counts as correct only above the threshold: commonly 0.5.\n\nThat threshold has a sharp consequence worth seeing. A box that is correct in every practical sense but shifted by a quarter of its width can fall below 0.5, and it is then counted twice against you: once as a false positive, once as a missed detection. So mAP at 0.5 and mAP at 0.75 can rank two models differently, and quoting one without saying which is not a result. Report the IoU threshold every time, and look at the localisation error separately from the classification error.\n\n**Segmentation** uses mean IoU per class, where thin structures and boundaries dominate the error and human annotators disagree about them too.\n\n## Your test set probably leaks through the session\n\nThe classic vision leak is not a duplicated file. It is the photo session: forty images of the same object, taken in one place with one camera in one minute, split at random across train and test. The model then recognises the carpet.\n\nSplit by capture session, by device, by patient, by shop: whatever unit generated a batch of similar images. And run a near-duplicate check before trusting any split:\n\n```python\nimport imagehash\nfrom PIL import Image\nh = {p: imagehash.phash(Image.open(p)) for p in paths}\n# pairs within a small Hamming distance are near-duplicates\n```\n\n## Shortcuts: what the model is keyed on\n\nModels learn whatever separates the classes fastest, which is often the background. Cows are photographed on grass, so a cow on a beach stops being a cow. Medical imaging models learn the scanner, the ward label burned into the corner, or the ruler that clinicians place beside a suspicious lesion.\n\nThe test is direct: build a slice where the correlation is broken (the object on an unusual background, images from a different site, the marker removed) and measure the gap. A model at 94% on the ordinary set and 61% on the broken-correlation set is not a 94% model. Two hundred such images will tell you more than ten thousand ordinary ones.\n\nGradient-based attribution maps are worth one afternoon here, not as evidence but as a lead: they show where the model is looking, and you check the suspicion properly with a slice.\n\n## The images your users will actually send\n\nAn evaluation built from clean catalogue photographs measures a product nobody has. Real intake is a phone camera, held at an angle, in a shop with a fluorescent tube, at 40% battery with the screen dimmed.\n\nBuild a perturbation suite and report accuracy at each level: Gaussian blur, JPEG compression at quality 40 and 20, brightness at half and double, 10-degree rotation, motion blur, and downscaling to 480 pixels. `albumentations` and `PIL` do all of it free, and the curve of accuracy against perturbation level is a more useful artefact than any single number: it tells the product team what to ask the camera screen to enforce.\n\n## Detection has a threshold problem of its own\n\nEvery detector emits a confidence per box, and mAP integrates over all of them, which means it describes no operating point you will ship. Pick the confidence threshold the product will use, and report ordinary precision and recall there, per class. A model with mAP 0.68 that must run at 0.9 precision to keep the review queue sane is a different proposition from one with mAP 0.66 that holds 0.9 precision at twice the recall.\n\n## Group slices, handled carefully\n\nWhere the images are of people, performance differs by skin tone, age and lighting, and reporting an average hides it. The complication is that measuring this requires the sensitive attributes you are trying to be careful about. The workable practice is to use an established annotation scale, collect it for the evaluation set only, keep it access-controlled, state in the report that it exists and why, and do not attach it to production records.\n\n## Two honest limits\n\nLabel noise in image sets is real, several per cent even in well-known public sets, so re-label 200 items yourself and measure the disagreement rate before treating the last two points of accuracy as signal. And a model evaluated only on your set tells you nothing about images from a new market, a new device generation, or a new season; that gap is measured after deployment, with the monitoring covered later in this course."},"check":{"question":"A detector reports mAP 0.71 at IoU 0.5 and 0.38 at IoU 0.75. What does that gap most directly indicate?","options":[{"text":"The model misses many objects entirely, and the stricter threshold makes those misses visible.","correct":false,"tempting":"Missed objects hurt equally at both thresholds; a gap between thresholds is about the quality of boxes that were found, not about objects that were not."},{"text":"The model finds objects but localises them loosely, so many boxes overlap enough to count at 0.5 and not at 0.75.","correct":true},{"text":"The test set is too small for stable mAP estimation at high IoU thresholds.","correct":false,"tempting":"Small sets do make mAP noisy, but a systematic 33-point drop between thresholds is a localisation signal rather than sampling noise."},{"text":"The classes are imbalanced, so mean average precision is dominated by rare classes at strict thresholds.","correct":false,"tempting":"Class imbalance affects the mean across classes, but it does not by itself produce a threshold-dependent gap of this shape."}]},"prev":{"slug":"evaluating-search-and-recommendation","title":"Ranking systems, where the labels are clicks and the clicks are biased","url":"https://addaly.com/learn/evaluating-ai/evaluating-search-and-recommendation"},"next":{"slug":"evaluating-speech","title":"Speech: word error rate, and the words that matter","url":"https://addaly.com/learn/evaluating-ai/evaluating-speech"},"authorship":"Founder and series editor: Dr Mustafa Mun. Written by AI models to a written standard. Exam keys checked blind by a second model: 3,665 of 3,666 agreed. Academic review invited.","review":{"status":"Draft, open for academic review"},"cite":"Addaly (2026) 'Images: the background the model is actually reading', in Knowing If It Works. Edited by M. Mun. Addaly. Available at: https://addaly.com/learn/evaluating-ai/evaluating-vision-models (Accessed: 13 October 2026).","licence":{"name":"CC BY-NC-SA 4.0","url":"https://creativecommons.org/licenses/by-nc-sa/4.0/"},"reader":{"schema":1,"title":"Images: the background the model is actually reading","courseTitle":"Knowing If It Works","module":{"index":4,"slug":"task-shapes","title":"The systems you will actually be handed"},"answer":null,"keyIdea":"Vision sets leak through sessions and reward shortcuts in the background, so split by capture session, test with the correlation deliberately broken, and report accuracy under the blur and low light your users’ phones actually produce.","hero":{"kind":"plate","image":null,"alt":null,"caption":null},"blocks":[{"t":"h2","id":"the-three-tasks-and-their-metrics","runs":[{"text":"The three tasks and their metrics"}]},{"t":"p","runs":[{"text":"Classification","b":true},{"text":" uses accuracy per class and the same confusion matrix arithmetic as anywhere else."}]},{"t":"p","runs":[{"text":"Detection","b":true},{"text":" uses mean average precision at an intersection-over-union threshold. IoU is the overlap of the predicted and true boxes divided by their union, and a prediction counts as correct only above the threshold: commonly 0.5."}]},{"t":"p","runs":[{"text":"That threshold has a sharp consequence worth seeing. A box that is correct in every practical sense but shifted by a quarter of its width can fall below 0.5, and it is then counted twice against you: once as a false positive, once as a missed detection. So mAP at 0.5 and mAP at 0.75 can rank two models differently, and quoting one without saying which is not a result. Report the IoU threshold every time, and look at the localisation error separately from the classification error."}]},{"t":"p","runs":[{"text":"Segmentation","b":true},{"text":" uses mean IoU per class, where thin structures and boundaries dominate the error and human annotators disagree about them too."}]},{"t":"h2","id":"your-test-set-probably-leaks-through-the-session","runs":[{"text":"Your test set probably leaks through the session"}]},{"t":"p","runs":[{"text":"The classic vision leak is not a duplicated file. It is the photo session: forty images of the same object, taken in one place with one camera in one minute, split at random across train and test. The model then recognises the carpet."}]},{"t":"p","runs":[{"text":"Split by capture session, by device, by patient, by shop: whatever unit generated a batch of similar images. And run a near-duplicate check before trusting any split:"}]},{"t":"code","lang":"python","label":"Python","text":"import imagehash\nfrom PIL import Image\nh = {p: imagehash.phash(Image.open(p)) for p in paths}\n# pairs within a small Hamming distance are near-duplicates"},{"t":"h2","id":"shortcuts-what-the-model-is-keyed-on","runs":[{"text":"Shortcuts: what the model is keyed on"}]},{"t":"p","runs":[{"text":"Models learn whatever separates the classes fastest, which is often the background. Cows are photographed on grass, so a cow on a beach stops being a cow. Medical imaging models learn the scanner, the ward label burned into the corner, or the ruler that clinicians place beside a suspicious lesion."}]},{"t":"p","runs":[{"text":"The test is direct: build a slice where the correlation is broken (the object on an unusual background, images from a different site, the marker removed) and measure the gap. A model at 94% on the ordinary set and 61% on the broken-correlation set is not a 94% model. Two hundred such images will tell you more than ten thousand ordinary ones."}]},{"t":"p","runs":[{"text":"Gradient-based attribution maps are worth one afternoon here, not as evidence but as a lead: they show where the model is looking, and you check the suspicion properly with a slice."}]},{"t":"h2","id":"the-images-your-users-will-actually-send","runs":[{"text":"The images your users will actually send"}]},{"t":"p","runs":[{"text":"An evaluation built from clean catalogue photographs measures a product nobody has. Real intake is a phone camera, held at an angle, in a shop with a fluorescent tube, at 40% battery with the screen dimmed."}]},{"t":"p","runs":[{"text":"Build a perturbation suite and report accuracy at each level: Gaussian blur, JPEG compression at quality 40 and 20, brightness at half and double, 10-degree rotation, motion blur, and downscaling to 480 pixels. "},{"text":"albumentations","code":true},{"text":" and "},{"text":"PIL","code":true},{"text":" do all of it free, and the curve of accuracy against perturbation level is a more useful artefact than any single number: it tells the product team what to ask the camera screen to enforce."}]},{"t":"h2","id":"detection-has-a-threshold-problem-of-its-own","runs":[{"text":"Detection has a threshold problem of its own"}]},{"t":"p","runs":[{"text":"Every detector emits a confidence per box, and mAP integrates over all of them, which means it describes no operating point you will ship. Pick the confidence threshold the product will use, and report ordinary precision and recall there, per class. A model with mAP 0.68 that must run at 0.9 precision to keep the review queue sane is a different proposition from one with mAP 0.66 that holds 0.9 precision at twice the recall."}]},{"t":"h2","id":"group-slices-handled-carefully","runs":[{"text":"Group slices, handled carefully"}]},{"t":"p","runs":[{"text":"Where the images are of people, performance differs by skin tone, age and lighting, and reporting an average hides it. The complication is that measuring this requires the sensitive attributes you are trying to be careful about. The workable practice is to use an established annotation scale, collect it for the evaluation set only, keep it access-controlled, state in the report that it exists and why, and do not attach it to production records."}]},{"t":"h2","id":"two-honest-limits","runs":[{"text":"Two honest limits"}]},{"t":"p","runs":[{"text":"Label noise in image sets is real, several per cent even in well-known public sets, so re-label 200 items yourself and measure the disagreement rate before treating the last two points of accuracy as signal. And a model evaluated only on your set tells you nothing about images from a new market, a new device generation, or a new season; that gap is measured after deployment, with the monitoring covered later in this course."}]}],"check":{"question":[{"text":"A detector reports mAP 0.71 at IoU 0.5 and 0.38 at IoU 0.75. What does that gap most directly indicate?"}],"options":[{"text":[{"text":"The model misses many objects entirely, and the stricter threshold makes those misses visible."}],"correct":false,"tempting":[{"text":"Missed objects hurt equally at both thresholds; a gap between thresholds is about the quality of boxes that were found, not about objects that were not."}]},{"text":[{"text":"The model finds objects but localises them loosely, so many boxes overlap enough to count at 0.5 and not at 0.75."}],"correct":true,"tempting":null},{"text":[{"text":"The test set is too small for stable mAP estimation at high IoU thresholds."}],"correct":false,"tempting":[{"text":"Small sets do make mAP noisy, but a systematic 33-point drop between thresholds is a localisation signal rather than sampling noise."}]},{"text":[{"text":"The classes are imbalanced, so mean average precision is dominated by rare classes at strict thresholds."}],"correct":false,"tempting":[{"text":"Class imbalance affects the mean across classes, but it does not by itself produce a threshold-dependent gap of this shape."}]}],"order":[3,0,2,1],"why":null},"prev":{"slug":"evaluating-search-and-recommendation","title":"Ranking systems, where the labels are clicks and the clicks are biased","minutes":10},"next":{"slug":"evaluating-speech","title":"Speech: word error rate, and the words that matter","minutes":9}}}