Skip to content

YOLO Object Detection

YOLO (You Only Look Once) is the dominant architecture for real-time object detection. Instead of sliding-window or region-proposal approaches, YOLO treats detection as a single regression problem — predict bounding boxes and classes in one pass. The Ultralytics library makes YOLOv8 and v11 the practical default for training, inference, and deployment.

Table of Contents

Installation / Setup

pip install ultralytics              # or: uv add ultralytics
# this installs YOLOv8 / YOLOv11 and dependencies

Key models (Ultralytics):

Model Params Speed (A100) COCO mAP Best for
yolov8n.pt 3.2M 0.99ms 37.3 Fast inference, edge devices
yolov8s.pt 11.2M 1.20ms 44.9 Good speed/accuracy
yolov8m.pt 25.9M 1.83ms 50.2 Balanced
yolov8l.pt 43.7M 2.39ms 52.9 High accuracy
yolov8x.pt 68.2M 3.53ms 53.9 Best accuracy
yolo11n.pt 2.6M 1.5ms 39.5 Latest architecture

Core Syntax

Inference (detection)

from ultralytics import YOLO

model = YOLO("yolov8n.pt")              # load pretrained (downloads automatically)
results = model("photo.jpg")              # predict on a single image

# results is a list of Results objects
for r in results:
    boxes = r.boxes                     # BoundingBoxes object
    print(boxes.xyxy)                   # [[x1, y1, x2, y2], ...]
    print(boxes.conf)                   # confidence scores
    print(boxes.cls)                    # class indices
    print(r.names)                      # {0: 'person', 1: 'bicycle', ...}

Inference on multiple images / video

# batch of images
results = model(["img1.jpg", "img2.jpg", "img3.jpg"])

# video / webcam / stream
results = model("video.mp4", stream=True)    # memory-efficient streaming
results = model(0)                            # webcam (index 0)

# save annotated output
results = model("video.mp4", save=True, project="runs", name="detect")

Extract results programmatically

for r in results:
    for box in r.boxes:
        x1, y1, x2, y2 = box.xyxy[0].tolist()
        conf = box.conf[0].item()
        cls = int(box.cls[0].item())
        name = r.names[cls]
        print(f"{name}: {conf:.2f} at ({x1:.0f},{y1:.0f})-({x2:.0f},{y2:.0f})")

Common arguments

Argument Default Description
conf 0.25 Confidence threshold
iou 0.7 NMS IoU threshold
imgsz 640 Inference image size
device auto 'cpu', '0' (GPU), 'mps'
max_det 300 Maximum detections per image
classes all Filter specific classes, e.g. [0, 2]
save False Save annotated images
show False Display in window
stream False Generator for video (memory-efficient)

Common Operations

Training on a custom dataset

from ultralytics import YOLO

model = YOLO("yolov8n.pt")       # start from pretrained weights

results = model.train(
    data="dataset.yaml",         # path to dataset config
    epochs=100,
    imgsz=640,
    batch=16,
    device="0",                  # GPU index
    patience=20,                 # early stopping patience
    save=True,
    project="runs/train",
    name="my_model",
)

Dataset YAML format

# dataset.yaml
path: /path/to/dataset
train: images/train
val: images/val
test: images/test

names:
  0: cat
  1: dog
  2: bird

Directory structure:

dataset/
  images/
    train/  → img1.jpg, img2.jpg
    val/    → img1.jpg, img2.jpg
  labels/
    train/  → img1.txt, img2.txt   (YOLO format: class x_center y_center w h)
    val/    → img1.txt, img2.txt

YOLO label format (per line):

class_id x_center y_center width height    (all normalized 0-1)

Validation / evaluation

from ultralytics import YOLO

model = YOLO("runs/train/my_model/weights/best.pt")
metrics = model.val(data="dataset.yaml")

print(f"mAP50:    {metrics.box.map50:.3f}")
print(f"mAP50-95: {metrics.box.map:.3f}")
print(f"Precision: {metrics.box.mp:.3f}")
print(f"Recall:    {metrics.box.mr:.3f}")

Model export

model = YOLO("runs/train/my_model/weights/best.pt")

# ONNX
model.export(format="onnx", imgsz=640, dynamic=True)

# TensorRT (GPU)
model.export(format="engine", half=True, device="0")

# CoreML (iOS/macOS)
model.export(format="coreml", imgsz=640)

# TFLite (Android/edge)
model.export(format="tflite", imgsz=640)

# TorchScript
model.export(format="torchscript", imgsz=640)
Format Use case
onnx Cross-platform, runtime-agnostic
engine (TensorRT) NVIDIA GPU, fastest inference
coreml Apple devices (iOS/macOS)
tflite Edge / mobile (Android, Coral)
torchscript PyTorch deployment
pb TensorFlow SavedModel

Practical Examples

Example 1 — Detect objects in an image and annotate

from ultralytics import YOLO

model = YOLO("yolov8n.pt")
results = model("street.jpg", conf=0.5, save=True)

for r in results:
    for box in r.boxes:
        name = r.names[int(box.cls)]
        conf = box.conf[0].item()
        xyxy = box.xyxy[0].tolist()
        print(f"{name} ({conf:.2f}): {xyxy}")

Example 2 — Count objects in a video

from ultralytics import YOLO
from collections import Counter

model = YOLO("yolov8n.pt")
class_counts = Counter()

for r in model("traffic.mp4", stream=True, conf=0.4):
    for cls in r.boxes.cls:
        class_counts[r.names[int(cls)]] += 1

print("Objects detected:")
for name, count in class_counts.most_common():
    print(f"  {name}: {count}")

Example 3 — Fine-tune on a custom dataset

from ultralytics import YOLO

# start from pretrained weights (better than training from scratch)
model = YOLO("yolov8n.pt")

model.train(
    data="my_dataset.yaml",
    epochs=50,
    imgsz=640,
    batch=16,
    lr0=0.01,             # initial learning rate
    patience=15,
    augment=True,
    mosaic=1.0,           # mosaic augmentation
    mixup=0.1,            # mixup augmentation
    device="0",
)

# evaluate the best model
best = YOLO("runs/train/exp/weights/best.pt")
metrics = best.val()
print(f"mAP50-95: {metrics.box.map:.3f}")

Common Patterns

Pattern: YOLO inference in a Flask API

from fastapi import FastAPI, UploadFile
from ultralytics import YOLO
import tempfile, os

app = FastAPI()
model = YOLO("yolov8n.pt")

@app.post("/detect")
async def detect(file: UploadFile):
    with tempfile.NamedTemporaryFile(suffix=".jpg", delete=False) as tmp:
        tmp.write(await file.read())
        tmp_path = tmp.name
    results = model(tmp_path, conf=0.5)
    os.unlink(tmp_path)

    detections = []
    for r in results:
        for box in r.boxes:
            detections.append({
                "class": r.names[int(box.cls)],
                "confidence": round(box.conf[0].item(), 3),
                "bbox": [round(v, 1) for v in box.xyxy[0].tolist()],
            })
    return {"detections": detections}

Pattern: class-filtered detection

# only detect people (class 0 in COCO) and cars (class 2)
results = model("street.jpg", classes=[0, 2], conf=0.5)

Pattern: benchmark inference speed

from ultralytics import YOLO

model = YOLO("yolov8n.pt")
metrics = model.benchmark(imgsz=640, device="0")
# prints FPS and latency

Best Practices

  • Start from pretrained weights (yolov8n.pt); training from scratch needs 10× more data and epochs.
  • Use yolov8n for edge devices (Jetson, mobile); yolov8x for server-side accuracy.
  • stream=True for video processing — avoids loading the entire video into memory.
  • YOLO label format: normalized class x_center y_center w h (0-1 scale).
  • Always validate on a held-out set; report mAP50 and mAP50-95.
  • Use conf=0.5 as a starting threshold; tune based on precision/recall needs.
  • Export to ONNX/TensorRT for production; model.export(format="onnx").
  • Mosaic + mixup augmentation help for small datasets.

Common Mistakes

Mistake Fix
Training from scratch on <1000 images Use pretrained weights; fine-tune with more data
Wrong label format (xmin,ymin,xmax,ymax vs YOLO) YOLO format is normalized x_center y_center w h
Forgetting model.eval() for manual inference Ultralytics handles this; manual PyTorch needs it
Using show=True in scripts without display Remove show=True or use save=True
COCO class names don't match your dataset Use your dataset's names from the YAML
Export fails for a format Check the format is supported; some require specific dependencies
Inference too slow on CPU Use a smaller model (yolov8n) or export to ONNX/TensorRT

Troubleshooting

Symptom Cause / Fix
ModuleNotFoundError: No module named 'ultralytics' pip install ultralytics
No detections on clear images Lower conf threshold; check imgsz matches your input
CUDA out of memory Lower batch size; use a smaller model
KeyError on class names Dataset YAML names don't match training data
Training loss stuck Check label format; verify dataset paths in YAML
Export to TensorRT fails Needs NVIDIA GPU + tensorrt installed; try pip install tensorrt
Poor mAP on custom data More data, more epochs, tune lr0, check annotation quality

Official Documentation

Last Updated

2026-09-06 — Initial version.