Recognition & Detection

YOLO

A family of real-time one-stage object detectors, begun by Redmon et al. in 2016, that predict every box and class probability of an image in a single network pass; later versions from several groups added anchors, multi-scale heads, anchor-free heads and NMS-free training.

intermediate

YOLO (“You Only Look Once”) is a family of real-time one-stage object detectors. The first version, by Redmon, Divvala, Girshick and Farhadi (CVPR 2016), treated object detection as a single regression problem: one convolutional neural network reads the whole image once and outputs a fixed-size tensor of boxes, confidences and class probabilities, with no region proposals. Redmon and Farhadi followed with YOLOv2 (2017) and YOLOv3 (2018); later versions come from other groups, some with peer-reviewed papers and some released only as code. This article describes the original model in detail and the later versions as milestones.

Problem Addressed

In 2015 accurate detectors were pipelines: R-CNN classified about 2,000 Selective Search proposals per image, refined the boxes and removed duplicates, with each stage tuned separately. The YOLO paper listed Fast R-CNN at 0.5 frames per second and Faster R-CNN (VGG-16) at 7 on PASCAL VOC 2007; the only real-time (30 frames per second or more) detectors it knew of were fast GPU implementations of DPM, at 26.1% mAP at 30 Hz and 16.0% at 100 Hz. YOLO replaced the pipeline with one network trained end to end, and since each prediction uses features of the whole image, it can use context that a classifier of one proposal cannot.

Architecture

Grid and Output Tensor

YOLO divides the input into an S×SS \times S grid. The cell that contains the center of an object is responsible for detecting it. Each cell predicts BB boxes, each with five numbers (x,y,w,h,confidence)(x, y, w, h, \text{confidence}), plus one set of CC conditional class probabilities Pr⁡(classi∣object)\Pr(\text{class}_i \mid \text{object}) shared by its boxes. The center (x,y)(x, y) is an offset within the cell, and the width and height are fractions of the image, so all four lie in [0,1][0, 1]. The confidence is trained toward Pr⁡(object)⋅IoUpredtruth\Pr(\text{object}) \cdot \mathrm{IoU}^{\text{truth}}_{\text{pred}}: zero when the cell holds no object, otherwise the intersection over union of the predicted box with the ground truth. The output is an S×S×(5B+C)S \times S \times (5B + C) tensor; for VOC the authors used S=7S = 7, B=2B = 2 and C=20C = 20, giving 7×7×307 \times 7 \times 30 and 98 boxes per image.

Network

The network, inspired by GoogLeNet, has 24 convolutional layers and 2 fully connected layers on a 448×448448 \times 448 input. Instead of inception modules it alternates 1×11 \times 1 reduction layers with 3×33 \times 3 convolutions, reducing the image to a 7×7×10247 \times 7 \times 1024 map; a 4,096-unit fully connected layer and a linear layer with 7⋅7⋅30=1,4707 \cdot 7 \cdot 30 = 1{,}470 outputs produce the tensor. All other layers use a leaky ReLU with slope 0.1 for negative inputs. Fast YOLO has 9 convolutional layers with fewer filters.

Training

The first 20 convolutional layers were pretrained on ImageNet classification at 224×224224 \times 224 for about a week (88% single-crop top-5 accuracy on the 2012 validation set); for detection the authors added four convolutional and two fully connected layers and doubled the input resolution.

The loss is sum-squared error, which the authors chose because it is easy to optimize, although it does not match the goal of maximizing average precision. Most cells hold no object, and their confidence errors could overwhelm the gradient from the cells that do and, they write, make training diverge early; so confidences without an object are weighted by λnoobj=0.5\lambda_{\text{noobj}} = 0.5 and coordinates by λcoord=5\lambda_{\text{coord}} = 5. Predicting w\sqrt{w} and h\sqrt{h} partly makes a given error count more for a small box than for a large one. Of the BB predictors in a cell, the one whose current prediction has the highest IoU with the ground truth is made “responsible” for it, which the authors report makes the predictors specialize in sizes, aspect ratios or classes. With 1iobj\mathbb{1}^{\text{obj}}_{i} indicating that an object appears in cell ii and 1ijobj\mathbb{1}^{\text{obj}}_{ij} that predictor jj of cell ii is responsible, the loss is

L=λcoord∑i=1S2∑j=1B1ijobj[(xi−x^i)2+(yi−y^i)2]+λcoord∑i=1S2∑j=1B1ijobj[(wi−w^i)2+(hi−h^i)2]+∑i=1S2∑j=1B1ijobj(Ci−C^i)2+λnoobj∑i=1S2∑j=1B1ijnoobj(Ci−C^i)2+∑i=1S21iobj∑c∈classes(pi(c)−p^i(c))2,\begin{aligned} \mathcal{L} = {} & \lambda_{\text{coord}} \sum_{i=1}^{S^2} \sum_{j=1}^{B} \mathbb{1}^{\text{obj}}_{ij} \left[ (x_i - \hat{x}_i)^2 + (y_i - \hat{y}_i)^2 \right] \\ & + \lambda_{\text{coord}} \sum_{i=1}^{S^2} \sum_{j=1}^{B} \mathbb{1}^{\text{obj}}_{ij} \left[ \left(\sqrt{w_i} - \sqrt{\hat{w}_i}\right)^2 + \left(\sqrt{h_i} - \sqrt{\hat{h}_i}\right)^2 \right] \\ & + \sum_{i=1}^{S^2} \sum_{j=1}^{B} \mathbb{1}^{\text{obj}}_{ij} \left(C_i - \hat{C}_i\right)^2 + \lambda_{\text{noobj}} \sum_{i=1}^{S^2} \sum_{j=1}^{B} \mathbb{1}^{\text{noobj}}_{ij} \left(C_i - \hat{C}_i\right)^2 \\ & + \sum_{i=1}^{S^2} \mathbb{1}^{\text{obj}}_{i} \sum_{c \in \text{classes}} \left( p_i(c) - \hat{p}_i(c) \right)^2 , \end{aligned}

where CiC_i is the confidence and pi(c)p_i(c) the class probability. Classification errors count only in cells that contain an object, and coordinate errors only for the responsible predictor. The paper defines 1ijnoobj\mathbb{1}^{\text{noobj}}_{ij} only implicitly; in our reading, used in the code below, it covers every predictor that is not responsible, including the second predictor of an object’s cell.

Training ran for about 135 epochs on VOC 2007 and 2012 trainval with batch size 64, momentum 0.9 and weight decay 0.0005, a learning rate raised from 10−310^{-3} to 10−210^{-2} over the first epochs (starting high often diverged) and then stepped down to 10−410^{-4}, dropout of 0.5 after the first fully connected layer, and random scaling, translation, exposure and saturation changes.

Example: Targets, Decoding and Loss on a Synthetic Image

The NumPy code below draws three objects on a 448×448448 \times 448 image and builds the 7×7×307 \times 7 \times 30 target (our layout per cell: two box slots, then 20 VOC class probabilities). It fabricates a noisy prediction, with a good and a rougher predictor in each object’s cell and a second cell firing on the tall person, decodes all 98 boxes with class-specific confidence Pr⁡(class∣object)⋅confidence\Pr(\text{class} \mid \text{object}) \cdot \text{confidence}, keeps those above 0.2, applies per-class non-maximum suppression at IoU 0.5, and evaluates each loss term.

import numpy as np

S, B, C, SIZE = 7, 2, 20, 448
CELL = SIZE / S                                   # 64 pixels per grid cell
VOC = ["aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow",
       "diningtable", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa",
       "train", "tvmonitor"]

# A synthetic 448 x 448 image with three objects; boxes are read off the object masks.
img = np.zeros((SIZE, SIZE))
objects = [("person", 60, 120, 150, 380, 0.9),    # (class, x1, y1, x2, y2, brightness)
           ("car", 230, 280, 420, 400, 0.6),
           ("dog", 250, 60, 330, 130, 0.3)]
gt = []
for name, x1, y1, x2, y2, v in objects:
    img[y1:y2, x1:x2] = v
    ys, xs = np.nonzero(img == v)
    gt.append((VOC.index(name), xs.min(), ys.min(), xs.max() + 1, ys.max() + 1))

def encode(gt):
    """YOLOv1 target: per cell [x, y, sqrt(w), sqrt(h), 1] for each of B slots, then C class probs."""
    T = np.zeros((S, S, 5 * B + C))
    for c, x1, y1, x2, y2 in gt:
        cx, cy, w, h = (x1 + x2) / 2, (y1 + y2) / 2, x2 - x1, y2 - y1
        col, row = int(cx // CELL), int(cy // CELL)    # the cell containing the center is responsible
        box = [cx / CELL - col, cy / CELL - row, np.sqrt(w / SIZE), np.sqrt(h / SIZE), 1.0]
        for b in range(B):
            T[row, col, 5 * b:5 * b + 5] = box
        T[row, col, 5 * B + c] = 1.0
    return T

def to_corners(t, row, col):
    """(x, y, sqrt w, sqrt h) in YOLO units -> (x1, y1, x2, y2) in pixels."""
    cx, cy = (col + t[0]) * CELL, (row + t[1]) * CELL
    w, h = t[2] ** 2 * SIZE, t[3] ** 2 * SIZE
    return np.array([cx - w / 2, cy - h / 2, cx + w / 2, cy + h / 2])

def iou(a, b):
    iw = max(0.0, min(a[2], b[2]) - max(a[0], b[0]))
    ih = max(0.0, min(a[3], b[3]) - max(a[1], b[1]))
    inter = iw * ih
    return inter / ((a[2] - a[0]) * (a[3] - a[1]) + (b[2] - b[0]) * (b[3] - b[1]) - inter)

T = encode(gt)
obj_cells = np.argwhere(T[:, :, 4] == 1)
print("target tensor", T.shape, "| object cells (row, col):", [tuple(int(v) for v in rc) for rc in obj_cells])
for row, col in obj_cells:
    t = T[row, col]
    print(f"  cell ({row},{col}) {VOC[int(np.argmax(t[10:]))]:>6}: x={t[0]:.3f} y={t[1]:.3f} "
          f"sqrt(w)={t[2]:.3f} sqrt(h)={t[3]:.3f}")

# A noisy "network output": boxes near the truth, background confidences near zero.
rng = np.random.default_rng(7)
P = np.zeros_like(T)
P[..., 0:2] = rng.uniform(0, 1, (S, S, 2)); P[..., 5:7] = rng.uniform(0, 1, (S, S, 2))
P[..., 2:4] = rng.uniform(0.1, 0.6, (S, S, 2)); P[..., 7:9] = rng.uniform(0.1, 0.6, (S, S, 2))
P[..., 4] = rng.uniform(0, 0.15, (S, S)); P[..., 9] = rng.uniform(0, 0.15, (S, S))
P[..., 10:] = rng.dirichlet(np.ones(C), (S, S))   # class probabilities, uninformative off-object
for row, col in obj_cells:
    t = T[row, col]
    P[row, col, 0:4] = t[0:4] + rng.normal(0, 0.03, 4)    # predictor 0: close to the object
    P[row, col, 5:9] = t[0:4] + rng.normal(0, 0.06, 4)    # predictor 1: rougher
    P[row, col, 4], P[row, col, 9] = 0.8, 0.4
    p = np.full(C, 0.1 / (C - 1)); p[np.argmax(t[10:])] = 0.9
    P[row, col, 10:] = p
# The cell above also fires on the (tall) person, with its center in its own cell.
P[2, 1, 0:4] = [0.64, 0.98, 0.45, 0.75]; P[2, 1, 4] = 0.5
P[2, 1, 10:] = 0.1 / (C - 1); P[2, 1, 10 + VOC.index("person")] = 0.9

# Decode: class-specific confidence = Pr(class | object) * confidence, for all 7 x 7 x 2 = 98 boxes.
dets = []
for row in range(S):
    for col in range(S):
        for b in range(B):
            scores = P[row, col, 10:] * P[row, col, 5 * b + 4]
            c = int(np.argmax(scores))
            dets.append((scores[c], c, to_corners(P[row, col, 5 * b:5 * b + 4], row, col)))
kept = [d for d in dets if d[0] > 0.2]
print(f"\n{len(dets)} boxes, {len(kept)} with class-specific confidence > 0.2")

def nms(dets, thr=0.5):
    out = []
    for d in sorted(dets, key=lambda d: -d[0]):
        if all(o[1] != d[1] or iou(o[2], d[2]) <= thr for o in out):
            out.append(d)
    return out

final = nms(kept)
print(f"after per-class NMS at IoU 0.5: {len(final)}")
for score, c, box in final:
    match = max(gt, key=lambda g: iou(box, g[1:]) if g[0] == c else -1)
    print(f"  {VOC[c]:>6} {score:.2f}  box {np.round(box).astype(int)}  "
          f"truth {np.array(match[1:])}  IoU {iou(box, match[1:]):.2f}")

# YOLOv1 loss (Eq. 3) with lambda_coord = 5, lambda_noobj = 0.5.
l_xy = l_wh = l_obj = l_noobj = l_cls = 0.0
resp = np.zeros((S, S, B), bool)
conf_target = np.zeros((S, S, B))
for row, col in obj_cells:
    truth = to_corners(T[row, col, 0:4], row, col)
    ious = [iou(to_corners(P[row, col, 5 * b:5 * b + 4], row, col), truth) for b in range(B)]
    j = int(np.argmax(ious))                     # responsible predictor: highest IoU with the truth
    resp[row, col, j], conf_target[row, col, j] = True, ious[j]
    p, t = P[row, col, 5 * j:5 * j + 5], T[row, col]
    l_xy += (p[0] - t[0]) ** 2 + (p[1] - t[1]) ** 2
    l_wh += (p[2] - t[2]) ** 2 + (p[3] - t[3]) ** 2
    l_obj += (p[4] - ious[j]) ** 2
    l_cls += np.sum((P[row, col, 10:] - t[10:]) ** 2)
conf = P[..., [4, 9]]
l_noobj = np.sum(conf[~resp] ** 2)               # every predictor that is not responsible
terms = {"5 * coord (x, y)": 5 * l_xy, "5 * coord (sqrt w, sqrt h)": 5 * l_wh,
         "confidence, responsible": l_obj, "0.5 * confidence, others": 0.5 * l_noobj,
         "class probabilities": l_cls}
print(f"\nloss terms ({resp.sum()} responsible predictors, {(~resp).sum()} others):")
for k, v in terms.items():
    print(f"  {k:<28} {v:.4f}")
print(f"  {'total':<28} {sum(terms.values()):.4f}")

Output:

target tensor (7, 7, 30) | object cells (row, col): [(1, 4), (3, 1), (5, 5)]
  cell (1,4)    dog: x=0.531 y=0.484 sqrt(w)=0.423 sqrt(h)=0.395
  cell (3,1) person: x=0.641 y=0.906 sqrt(w)=0.448 sqrt(h)=0.762
  cell (5,5)    car: x=0.078 y=0.312 sqrt(w)=0.651 sqrt(h)=0.518

98 boxes, 7 with class-specific confidence > 0.2
after per-class NMS at IoU 0.5: 3
     dog 0.72  box [247  59 331 128]  truth [250  60 330 130]  IoU 0.92
  person 0.72  box [ 65 128 144 368]  truth [ 60 120 150 380]  IoU 0.81
     car 0.72  box [215 274 435 401]  truth [230 280 420 400]  IoU 0.82

loss terms (3 responsible predictors, 95 others):
  5 * coord (x, y)             0.0155
  5 * coord (sqrt w, sqrt h)   0.0220
  confidence, responsible      0.0137
  0.5 * confidence, others     0.7342
  class probabilities          0.0316
  total                        0.8170

The person’s center (105, 250) lies in row 3, column 1, 58/64=0.90658/64 = 0.906 of the way down the cell. Seven boxes pass the threshold, and NMS removes the four duplicates. Even with λnoobj=0.5\lambda_{\text{noobj}} = 0.5, the 95 non-responsible predictors contribute 90% of the loss, the imbalance the weighting addresses. Over seeds 0–7, exactly three detections survived in six runs; in two, a rough second box overlapped the best one by less than 0.5 and survived, and in one the rougher predictor won responsibility for two objects, so the more confident predictor was pushed toward zero.

Inference

Each of the 98 confidences is multiplied by its cell’s class probabilities; the resulting class-specific scores are thresholded and duplicates removed with NMS. Because the grid usually assigns an object to one cell, the authors found NMS less critical than for R-CNN or DPM, adding 2–3% mAP by removing duplicates of large objects or objects near cell borders. On a Titan X without batching, YOLO ran at 45 frames per second and Fast YOLO at 155.

Performance

Redmon et al. (2016) trained on VOC 2007+2012 trainval and reported mAP at IoU 0.5:

  • VOC 2007 test. YOLO 63.4% at 45 fps and Fast YOLO 52.7% at 155 fps, against 26.1% for the 30 Hz DPM; Faster R-CNN with VGG-16 reached 73.2% at 7 fps, and YOLO on a VGG-16 backbone 66.4% at 21 fps.
  • Error analysis. On VOC 2007, localization errors (correct class, 0.1<IoU<0.50.1 < \text{IoU} < 0.5) made up 19.0% of YOLO’s top detections against 8.6% for Fast R-CNN, and background errors (IoU below 0.1 with every object) 4.75% against 13.6%.
  • Combined with Fast R-CNN. Boosting Fast R-CNN boxes that YOLO also predicted raised its VOC 2007 test mAP from 71.8% to 75.0%, while combining two Fast R-CNN variants gained only 0.3–0.6 points; the authors attribute the difference to YOLO making different mistakes.
  • VOC 2012 test (VOC 2007 test added to training). YOLO 57.9%; the authors put it 8–10% below R-CNN or Feature Edit on classes with small objects such as bottle, sheep and tv/monitor. The combination scored 70.7%.
  • Artwork. Person AP for YOLO was 59.2 on VOC 2007, 53.3 on the Picasso dataset and 45 on People-Art (trained on VOC 2007, 2012 and 2010 data respectively), while R-CNN’s fell from 54.2 to 10.4 and 26. The authors credit YOLO’s modeling of object size, shape and layout.

Strengths

  • Speed and simplicity. One network, one pass, no proposals.
  • Global context. Every prediction sees the whole image, which the authors link to its few background errors.
  • Generalization. On artwork it kept the highest person AP of the methods compared and lost far less than R-CNN.

Limitations

The authors list these:

  • Spatial constraints. Each cell predicts two boxes and one class, which limits how many nearby objects can be detected; small objects in groups, such as flocks of birds, are hard. (In our reading of the encoding, two objects whose centers fall in one cell must also share its single class vector.)
  • New aspect ratios. Boxes are learned from data with no priors, so objects in unusual aspect ratios or configurations generalize poorly.
  • Coarse features. Repeated downsampling leaves only 7×77 \times 7 features to predict from.
  • Localization. The loss still treats errors in small and large boxes alike, and incorrect localization is the main source of error.

Historical Importance

YOLO showed in 2016 that a single network could detect objects in real time at more than twice the mAP of earlier real-time systems. Its grid assignment, objectness confidence and unified loss carried into the later versions, and YOLO-family detectors became a common per-frame detector in tracking by detection; ByteTrack, for example, uses YOLOX. The YOLOv3 report closed by asking researchers to consider the harm their work might do, citing personal-data harvesting and military funding, and in February 2020 Redmon posted that he had stopped doing computer vision research, citing its military applications and privacy concerns.

Variants

YOLOv2 and YOLO9000 (2017)

Redmon and Farhadi targeted recall and localization, reporting each change’s VOC 2007 gain: batch normalization (over 2% mAP, replacing dropout); fine-tuning the classifier at 448 before detection (almost 4%); convolutional anchor boxes on a 13×1313 \times 13 map, with class and objectness per anchor (mAP 69.5 to 69.2%, but recall 81% to 88%); k-means anchor shapes plus sigmoid-constrained centers (almost 5% together); a passthrough layer that stacks 26×2626 \times 26 features into channels (1%); and multi-scale training on inputs from 320 to 608. With the new Darknet-19 backbone (19 convolutional layers), one set of weights trades speed for accuracy on VOC 2007 test: 69.0% mAP at 91 fps at 288 pixels, 76.8% at 67 fps at 416, 78.6% at 40 fps at 544 (GeForce GTX Titan X). YOLOv2 scored 73.4% on VOC 2012 test and 21.6 AP (44.0 AP50_{50}) on COCO test-dev 2015.

YOLO9000 trained jointly on COCO detection and the top 9,000 ImageNet classes. To merge the labels, the authors built WordTree from WordNet (9,418 classes here) and predicted a softmax over the children of each node, so a class probability is a product of conditional probabilities down the tree; the class loss reaches only nodes at or above the labeled one, since finer labels are unknown. YOLO9000 reached 19.7 mAP on ImageNet detection validation, and 16.0 on the 156 classes absent from COCO.

YOLOv3 (2018)

YOLOv3 appeared as an arXiv technical report in a deliberately informal style, with joking captions and a “Rebuttal” appendix. It predicts objectness by logistic regression and classes with independent logistic classifiers trained with binary cross-entropy, so overlapping labels such as “woman” and “person” can coexist. It predicts at three scales, an idea the authors relate to feature pyramid networks, with three of nine k-means anchors each, and its backbone, Darknet-53, adds residual connections. In a table adapted from the RetinaNet paper’s COCO test-dev comparison (the report does not state the split of its own entry), YOLOv3 at 608 pixels scored 33.0 AP and 57.9 AP50_{50} in 51 ms on a Titan X, against 57.5 AP50_{50} in 198 ms for RetinaNet; its AP fell at stricter IoU thresholds. The authors report that the focal loss cost about 2 mAP.

After Redmon

Version numbers after v3 were chosen by their authors and imply neither a shared codebase nor an ordering of accuracy. Beyond the table:

  • YOLOv4 (Bochkovskiy, Wang & Liao, 2020) sorted the changes it tested into a “bag of freebies” (training-only, such as Mosaic augmentation and the CIoU loss) and a “bag of specials” (cheap inference-time modules such as SPP), aiming at detectors trainable on one conventional GPU.
  • Ultralytics states that it has not published a formal paper for YOLOv5, YOLOv8 or YOLO11 and asks users to cite the repositories. YOLOX’s authors describe YOLOv5 as anchor-based; YOLOv8 has an anchor-free head.
  • YOLOX (Ge et al., 2021) started from YOLOv3. Its SimOTA assigns each object a dynamic number of lowest-cost predictions; an NMS-free variant cost 0.8 AP and was left out of the final models.
  • YOLOv6‘s report says the name was used with the YOLO authors’ permission, and YOLOv9’s programmable gradient information runs an auxiliary reversible branch only in training.
  • YOLOv10 (NeurIPS 2024) trains one-to-many and one-to-one heads and keeps only the one-to-one head, so inference needs no NMS; YOLO26 makes such a head optional. YOLOv12 (Tian, Ye & Doermann, arXiv 2025) is attention-centric.
Version Year Authors or organization Key change Reported result
YOLO 2016 Redmon, Divvala, Girshick, Farhadi Single-pass grid regression, 7×7×307 \times 7 \times 30 output VOC 2007 test 63.4% mAP, 45 fps (Titan X)
YOLOv2 2017 Redmon, Farhadi Batch norm, k-means anchors, Darknet-19, multi-scale training VOC 2007 test 78.6% mAP at 40 fps, 76.8% at 67 fps (Titan X)
YOLOv3 2018 Redmon, Farhadi Darknet-53, three scales, logistic classifiers COCO (split unstated) 33.0 AP, 57.9 AP50_{50}, 51 ms at 608 (Titan X)
YOLOv4 2020 Bochkovskiy, Wang, Liao CSPDarknet53, SPP, PANet, bag of freebies and specials COCO test-dev 43.5 AP (65.7 AP50_{50}), 62 fps at 608 (V100)
YOLOv5 2020 Ultralytics PyTorch implementation, no paper YOLOv5-L: COCO test-dev 48.2 AP at 640, as listed by YOLOX
YOLOX 2021 Ge et al. (Megvii) Anchor-free, decoupled head, SimOTA YOLOX-L: COCO test-dev 50.0 AP at 640, 69 fps (V100)
YOLOv6 2022 Li et al. (Meituan) Re-parameterizable blocks, TAL, self-distillation YOLOv6-S: COCO val2017 43.5 AP, 495 fps (T4, TensorRT, batch 32)
YOLOv7 2022 / 2023 Wang, Bochkovskiy, Liao E-ELAN, planned re-parameterization, lead-guided assignment COCO test2017 51.4 AP at 640, 118 fps; E6E 56.8 AP at 1280, 35 fps (V100)
YOLOv8 2023 Ultralytics Anchor-free split head, multi-task framework, no paper YOLOv8x: COCO val 53.9 AP at 640 (documentation)
YOLOv9 2024 Wang, Yeh, Liao PGI, GELAN YOLOv9-E: COCO val 55.6 AP
YOLOv10 2024 Wang et al. (Tsinghua) Consistent dual assignments, NMS-free YOLOv10-X: COCO val 54.4 AP; YOLOv10-S 46.3 AP at 2.49 ms (T4, TensorRT)
YOLO11 2024 Ultralytics Revised backbone and neck, no paper YOLO11x: COCO val 54.7 AP at 640 (documentation)
YOLO26 2026 Ultralytics Optional native NMS-free head, no DFL, MuSGD COCO val 40.1–56.9 AP NMS-free (40.9–57.5 with NMS) across scales, 1.7–11.8 ms NMS-free (T4, TensorRT; documentation)

COCO AP is averaged over IoU thresholds 0.50–0.95, and VOC mAP uses IoU 0.5 (see average precision). YOLOv7 reports on what it calls the COCO test 2017 set, without naming test-dev.

Implementations

Redmon’s code was written in his C framework Darknet, and YOLOv4 was released in Bochkovskiy’s fork of it. Licenses differ, as listed in the repositories’ GitHub metadata: Apache-2.0 for YOLOX, GPL-3.0 for YOLOv6, YOLOv7 and YOLOv9, AGPL-3.0 for YOLOv10, and AGPL-3.0 or an enterprise license for the Ultralytics models.

The snippet below builds the original fully connected head in PyTorch (run with PyTorch 2.14.1), from the 7×7×10247 \times 7 \times 1024 feature map to the 7×7×307 \times 7 \times 30 tensor.

import torch
from torch import nn

print("torch", torch.__version__)
S, B, C = 7, 2, 20
head = nn.Sequential(
    nn.Flatten(),                                  # 7 x 7 x 1024 features from the last conv layer
    nn.Linear(7 * 7 * 1024, 4096),
    nn.LeakyReLU(0.1),
    nn.Dropout(0.5),                               # after the first connected layer, as in the paper
    nn.Linear(4096, S * S * (5 * B + C)),          # linear output: 1470 numbers
    nn.Unflatten(1, (S, S, 5 * B + C)),
)
features = torch.randn(2, 1024, 7, 7)              # stand-in for two 448 x 448 images
print("output:", tuple(head(features).shape))
for i in (1, 4):
    n = sum(p.numel() for p in head[i].parameters())
    print(f"{head[i]}: {n:,} parameters")

Output:

torch 2.14.1
output: (2, 7, 7, 30)
Linear(in_features=50176, out_features=4096, bias=True): 205,524,992 parameters
Linear(in_features=4096, out_features=1470, bias=True): 6,022,590 parameters

The first fully connected layer alone holds about 206 million weights and fixes the input size. YOLOv2’s convolutional head removed both, which is what let it be resized on the fly for multi-scale training.

Related

  • You Only Look Once: Unified, Real-Time Object Detection

    The 2016 CVPR paper by Redmon, Divvala, Girshick and Farhadi that introduced YOLO, recasting object detection as one regression from image pixels to boxes and class probabilities, solved by a single network fast enough for live video.

  • Faster R-CNN

    A two-stage object detector in which a region proposal network, sharing the detector's convolutional features, replaces hand-designed region proposals, making proposal generation nearly free and the whole detector one network.

  • Anchor Boxes

    Reference boxes of fixed sizes and aspect ratios, tiled at every feature-map position, that a detector classifies and refines, and that decide which of its predictions are trained on which objects.

  • Non-Maximum Suppression

    The post-processing step that removes duplicate detections by repeatedly keeping the highest-scoring box and discarding the boxes that overlap it beyond an IoU threshold, with its soft, distance-aware and learned variants.

  • PASCAL VOC

    The PASCAL Visual Object Classes challenge (2005–2012), whose 20-class datasets of Flickr photographs with bounding boxes and segmentations set the standard protocol for evaluating object detection.

  • ByteTrack

    A multi-object tracker that associates high-score detections first and then matches the remaining tracks to low-score detections, recovering occluded objects that score thresholds would discard.

References

  1. Redmon, J., Divvala, S., Girshick, R. & Farhadi, A. (2016). You Only Look Once: Unified, Real-Time Object Detection. IEEE Conference on Computer Vision and Pattern Recognition (CVPR), 779–788.
  2. Redmon, J. & Farhadi, A. (2017). YOLO9000: Better, Faster, Stronger. IEEE Conference on Computer Vision and Pattern Recognition (CVPR), 6517–6525.
  3. Redmon, J. & Farhadi, A. (2018). YOLOv3: An Incremental Improvement. Technical report, arXiv:1804.02767.
  4. Bochkovskiy, A., Wang, C.-Y. & Liao, H.-Y. M. (2020). YOLOv4: Optimal Speed and Accuracy of Object Detection. arXiv:2004.10934.
  5. Jocher, G. (2020). Ultralytics YOLOv5 (software). Zenodo.
  6. Ge, Z., Liu, S., Wang, F., Li, Z. & Sun, J. (2021). YOLOX: Exceeding YOLO Series in 2021. arXiv:2107.08430.
  7. Li, C., Li, L., Jiang, H., Weng, K., Geng, Y., Li, L., Ke, Z., Li, Q., Cheng, M., Nie, W., Li, Y., Zhang, B., Liang, Y., Zhou, L., Xu, X., Chu, X., Wei, X. & Wei, X. (2022). YOLOv6: A Single-Stage Object Detection Framework for Industrial Applications. Technical report, arXiv:2209.02976.
  8. Wang, C.-Y., Bochkovskiy, A. & Liao, H.-Y. M. (2023). YOLOv7: Trainable Bag-of-Freebies Sets New State-of-the-Art for Real-Time Object Detectors. IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR), 7464–7475.
  9. Ultralytics documentation: YOLOv8.
  10. Wang, C.-Y., Yeh, I.-H. & Liao, H.-Y. M. (2024). YOLOv9: Learning What You Want to Learn Using Programmable Gradient Information. European Conference on Computer Vision (ECCV), Lecture Notes in Computer Science, 1–21.
  11. Wang, A., Chen, H., Liu, L., Chen, K., Lin, Z., Han, J. & Ding, G. (2024). YOLOv10: Real-Time End-to-End Object Detection. Advances in Neural Information Processing Systems 37 (NeurIPS).
  12. Ultralytics documentation: YOLO11.
  13. Tian, Y., Ye, Q. & Doermann, D. (2025). YOLOv12: Attention-Centric Real-Time Object Detectors. arXiv:2502.12524.
  14. Jocher, G., Qiu, J., Liu, M., Lyu, S., Akyon, F. C. & Kalfaoglu, M. E. (2026). Ultralytics YOLO26: Unified Real-Time End-to-End Vision Models. arXiv:2606.03748.
  15. Redmon, J. [@pjreddie] (2020, February 20). Post on Twitter (now X) about stopping computer vision research.