YOLO v8

One forward pass emits every box the model will ever consider. Move the confidence and NMS thresholds and watch objects appear, duplicate and vanish.

8,400 predictions, and the two thresholds that discard them

This explorer needs JavaScript: every shape, parameter count and curve on it is computed in the page rather than downloaded as an image.

Worth knowing

Three feature levels at strides 8, 16 and 32 give 80² + 40² + 20² = 8,400 predictions at 640×640.
v8 is anchor-free. A cell predicts distances to the four box edges directly, so there are no anchor sizes to tune per dataset.
The box is predicted as four 16-bin distributions and collapsed by taking the expectation — that is what the DFL loss trains.
Confidence and NMS thresholds are inference-time knobs. Changing them changes your metrics without retraining anything.

Overview

One forward pass emits every box the model will ever consider.

In this guide
  1. One stage means one pass
  2. Backbone, neck, head
  3. Anchor-free, and what that replaced
  4. The two thresholds
  5. Why the model sizes are letters
  6. Reading the mismatch counter
  7. Questions people ask
  8. Recap in one screen

YOLO v8

One pass, 8,400 pick boxes. Two thresholds that decide which of them you ever see.

One stage means one pass

A two-stage finder like Faster R-CNN proposes regions, then classifies and refines each one. A one-stage finder does it in a single forward pass: the head emits, for each cell of each feature level, a class vector and a box. Nothing is proposed, nothing is cropped, nothing is re-run.

That is where the speed comes from and also where the awkwardness comes from, because "each cell of each level" is a lot of boxes and almost all of them are wrong. At 640×640 with three levels:

LevelStrideGridPredictions
P3880 × 806,400
P41640 × 401,600
P53220 × 20400
8,400

Turn on the grid overlay in the explorer to see the three resolutions. P3's cells are 8 input pixels across. This Is why it's the level that finds small objects. P5's are 32 across. This Is why it handles large ones. This is the feature pyramid, and it's the reason a finder can span an order of magnitude of object size at all.

Backbone, neck, head

each modern finder has this three-part shape, and it's worth being able to name the parts.

The backbone is a classification network with the classifier removed — in v8, a CSPDarknet variant whose repeating unit is the C2f block: a split, a few bottleneck convolutions, and a concatenation of all the mid outputs. It makes feature maps at strides 8, 16 and 32.

The neck mixes those levels. Semantic info is strongest at stride 32 and spatial precision is strongest at stride 8. So A top-down path carries semantics down and a bottom-up path carries precision back up — the PAN setup, itself a descendant of FPN. Without it, the level that can see small objects has no idea what they're.

The head turns each level into guesses. v8's head is *decoupled*: one small convolutional branch for classification and a separate one for box regression, rather than a single branch predicting both. Sharing them makes the two tasks fight over the same features, and separating them is worth about a point of mAP for a small amount of find.

Anchor-free, and what that replaced

Versions 2 through 7 were anchor-based: each cell carried a few prior boxes of fixed size and aspect ratio, and the network predicted an offset from the nearest one. That meant a set of anchor dims had to be chosen per dataset — often by k-means over the training boxes. And it meant three or more guesses per cell.

v8 predicts, from each cell, the distances from that cell's centre to the four edges of the box. No priors, no offsets, one guess per cell. The setting is gone.

The regression isn't a plain regression, though. Each of the four distances is predicted as a spread over 16 bins. So The box branch emits 4 × 16 = 64 channels per cell, and the actual distance is the expectation of that spread. This is Spread Focal Loss, and the reason for it's that box edges are truly ambiguous. Where just does a blurred or occluded boundary lie? — and a spread can express "probably 12, possibly 15" where a single number can't. The network's own uncertainty turns trainable.

There's also no objectness score in v8. Older versions predicted "is there any of it here" apart from "what is it". V8's trust is just the class score. One fewer output, one fewer loss term, one fewer thing to calibrate.

set during training is handled by TaskAlignedAssigner: rather than a fixed rule about which cell owns which object, it scores each pick by a combination of its classification trust and its IoU with the ground truth, and assigns the top few. Cells that are already good at both get the label, which is a mild form of the network choosing its own oversight.

The two thresholds

All above is fixed at training time. The two controls in the explorer aren't — they're applied after the forward pass, and changing them changes your reported metrics without retraining any of it.

trust threshold. each guess below it's discarded. Push it up in the explorer and boxes vanish. Push it past 0.55 and the note changes to warn you, because the objects you lose first are just the hard ones — small, occluded, unusual pose — which are the ones with low scores. A high threshold makes a demo look clean and makes recall quietly terrible. The default of 0.25 for visualisation is a display choice. For finding mAP you use a thing like 0.001, because mAP integrates over the whole precision-recall curve and truncating it early just throws away area.

NMS IoU threshold. a few neighbouring cells will each decide the same object is theirs, so the head emits a cluster of near-the same boxes. Non- max suppression sorts by trust, keeps the top box, and deletes any of it shared it by more than the threshold, per class. Turn NMS off in the explorer to see the raw cluster.

The threshold is a genuine trade and the "crowd" scene is there to show it. Set it low, around 0.3, and two people standing close — who really do share by more than 0.3. Are treated as duplicates and one is deleted. Set it high, around 0.9, and duplicates live. There's no value that is right for both a sparse scene and a dense one. This Is why crowded-scene spotting has its own literature: Soft-NMS. This Decays scores instead of deleting, and set-guess models like DETR. This Have no NMS at all because their loss forbids duplicate guesses in the first place.

from ultralytics import YOLO

model = YOLO("yolov8n.pt")

results = model.predict(
    "street.jpg",
    conf=0.25,     # the confidence cut
    iou=0.7,       # the NMS IoU threshold
    imgsz=640,     # must be a multiple of 32: strides are 8, 16, 32
    max_det=300,
)

for box in results[0].boxes:
    print(model.names[int(box.cls)], float(box.conf), box.xyxy[0].tolist())

imgsz has to be a multiple of 32 or the three levels don't divide evenly. Raising it raises small-object recall roughly in proportion to the extra pixels and costs latency as n² — often the single most effective knob, and the one people forget exists while they tune conf.

Why the model sizes are letters

v8 ships as n, s, m, l and x. Nano through extra-large — and they are the same architecture with two multipliers applied: one to the channel counts and one to the number of repeats in each C2f block. Nothing structural differs between them.

That matters because it makes the fit/latency trade a dial rather than a choice of architecture, and because the scaling is predictable: roughly, depth and width both scale, so params grow faster than latency does. The nano model is around 3 M params and the extra-large around 68 M, for perhaps five points of COCO mAP between them.

The hands-on sequence for picking one is the reverse of what people often do. Start from the latency budget on the actual target hardware, pick the largest model that fits it, and only then look at fit. Choosing the model first and optimising afterwards often ends in quantisation and pruning work that a smaller model would have made unneeded.

Reading the mismatch counter

The explorer's fourth statistic is missed / duplicate / false, recomputed as you move the sliders. It's worth playing with on purpose, because the three failure modes have three different causes:

  • Missed objects mean the trust threshold is too high, or the object is smaller than P3 can resolve.
  • Duplicates mean the NMS threshold is too high, or NMS is off.
  • False positives mean the trust threshold is too low.

each real tuning session is spent trading these against each other, and mAP is the single number that summarises the whole curve so you don't have to pick a point on it until deployment.

Questions people ask

Why are there 8,400 guesses for maybe five objects? Because a one-stage head emits one guess per cell per level. 80² + 40² + 20² = 8,400 cells at 640×640. Almost all are background. The trust cut plus NMS reduce them to the handful you see. Nothing is proposed and nothing is cropped. This Is just where the speed comes from.

What trust threshold should I use? Two answers for two jobs. For a demo or a production filter, a thing like 0.25. A display choice. For finding mAP, a thing like 0.001. MAP integrates the whole precision-recall curve and a high cut simply discards area. Reporting mAP measured at 0.25 understates your own model.

Why does it miss small objects? P3 has stride 8. Its cells are 8 input pixels across and an object a few pixels wide leaves almost no signal at any level. Raising imgsz is the fix, roughly in proportion to the extra pixels. Often a bigger win than any threshold change, and it costs latency as n².

Why does my imgsz get rounded? It has to be a multiple of 32 so strides 8, 16 and 32 all divide evenly. That is also why 640 and 1280 are the conventional sizes.

Two shared people became one box. Is that the model failing? often not. It's NMS. Two people standing close truly share by more than a 0.3 IoU threshold. One is deleted as a duplicate. Raise the threshold and duplicates live instead. No single value is right for both sparse and crowded scenes. This Is why Soft-NMS and set-guess models like DETR exist.

How do I choose between n, s, m, l and x? Backwards from how it's often done. They're one architecture with a width and a depth multiplier. Roughly 3 M to 68 M params for about five points of COCO mAP. So start from the latency budget on the hardware you'll really deploy to, take the largest model that fits, and look at fit last.

Recap in one screen

  • One pass, one guess per cell per level: 6,400 + 1,600 + 400 = 8,400 picks at 640×640.
  • Backbone, neck, head — features at strides 8/16/32, a PAN neck carrying semantics down and precision back up. A decoupled head so classification and regression stop fighting over the same features.
  • Anchor-free: each cell predicts four edge distances, each as a spread over 16 bins. The box branch emits 64 channels and the model's own uncertainty turns trainable.
  • Both thresholds are applied after the forward pass. trust decides what you see. NMS IoU decides what counts as a duplicate. Neither needs retraining.
  • Missed means trust too high or the object is below P3's detail, duplicates mean NMS IoU too high, false positives mean trust too low.

Check yourself

0 of 4

Answer without scrolling back up.

  1. Where do the 8,400 predictions at 640x640 come from?

  2. What does the box branch actually output per cell?

  3. You raise the confidence threshold from 0.25 to 0.7 and your demo looks much cleaner. What has happened to your metrics?

  4. Why does lowering the NMS IoU threshold hurt in a crowd?

Cheat sheet

YOLO v8

See all 8,400 raw YOLO predictions, then move the confidence and NMS thresholds and watch objects appear, duplicate and disappear.

COMPUTER VISION · vizlearn.in/computer_vision/yolov8_detection.html

Further reading

About the author

Ashish Jangra builds and maintains VizLearn. Every module here is written and the visualisation behind it hand-built, so the numbers in a readout come from the same code that draws the picture. Corrections are genuinely welcome and get priority over everything else — if a page states something wrong, or an animation misrepresents what the algorithm does, get in touch.