# How to Fine-Tune YOLOv5 for Custom Object Detection: A Complete Technical Guide

> Learn to fine-tune YOLOv5 for custom object detection. Prepare your dataset, configure YOLO format, and train with pre-trained weights for faster, accurate results.

- Repository: [Ultralytics/yolov5](https://github.com/ultralytics/yolov5)
- Tags: how-to-guide
- Published: 2026-03-06

---

**Fine-tune YOLOv5 by preparing your dataset in YOLO format, configuring a data YAML file, and executing** [`train.py`](https://github.com/ultralytics/yolov5/blob/main/train.py) **with a pre-trained checkpoint, which transfers learned backbone features from COCO while adapting the detection head to your specific classes.**

YOLOv5's modular architecture makes it ideal for transfer learning on bespoke detection tasks. By leveraging pre-trained weights from the COCO dataset, you can achieve rapid convergence even with limited training data. This guide walks through the complete workflow using the official `ultralytics/yolov5` repository, from data preparation to model export.

## Understanding YOLOv5's Modular Architecture

Before fine-tuning, it helps to understand how the model components interact. YOLOv5 separates feature extraction, aggregation, and prediction into distinct modules that work together during training.

### The Backbone (CSP-Darknet)

Located in [`models/common.py`](https://github.com/ultralytics/yolov5/blob/main/models/common.py), the CSP-Darknet backbone extracts low-level visual features from input images. When fine-tuning, these weights typically remain stable, preserving generic visual representations learned from millions of COCO images while allowing higher-level layers to adapt.

### The Neck (PANet)

Also implemented in [`models/common.py`](https://github.com/ultralytics/yolov5/blob/main/models/common.py), the Path Aggregation Network (PANet) merges multi-scale features to improve detection across different object sizes. This component bridges the backbone and head, handling feature pyramids essential for detecting both small and large objects simultaneously.

### The Detection Head

Defined in [`models/yolo.py`](https://github.com/ultralytics/yolov5/blob/main/models/yolo.py), the detection head produces bounding-box coordinates, objectness scores, and class probabilities. During fine-tuning, [`train.py`](https://github.com/ultralytics/yolov5/blob/main/train.py) automatically detects your dataset's class count from the YAML configuration and reinitializes this head's output layer to match your specific categories, while preserving the backbone's feature extraction capabilities.

## Preparing Your Custom Dataset

Fine-tuning requires data in YOLO format: text files containing normalized coordinates `<class> <cx> <cy> <w> <h>` for each image, where [`utils/datasets.py`](https://github.com/ultralytics/yolov5/blob/main/utils/datasets.py) parses these files during training.

### Dataset Structure and YAML Configuration

Create a data configuration file pointing to your train and validation directories. The YAML must specify the number of classes (`nc`) and class names, allowing [`train.py`](https://github.com/ultralytics/yolov5/blob/main/train.py) to infer the output dimensions for the detection head.

```yaml

# custom_data.yaml  (place anywhere in the repo, e.g. ./data/custom.yaml)

train: ./data/custom/images/train
val:   ./data/custom/images/val
nc: 3                     # number of classes

names: [person, dog, cat]   # class names

```

## Executing the Fine-Tuning Process

The [`train.py`](https://github.com/ultralytics/yolov5/blob/main/train.py) script orchestrates the entire training pipeline, handling dataset loading via [`utils/datasets.py`](https://github.com/ultralytics/yolov5/blob/main/utils/datasets.py), model construction, optimizer setup through [`utils/torch_utils.py`](https://github.com/ultralytics/yolov5/blob/main/utils/torch_utils.py), and the training loop itself.

### Command-Line Training

Launch fine-tuning by specifying your data YAML and a pre-trained checkpoint like `yolov5s.pt`. The script automatically infers class counts from your configuration and initializes the detection head in [`models/yolo.py`](https://github.com/ultralytics/yolov5/blob/main/models/yolo.py) accordingly.

```bash

# Fine-tune YOLOv5s on the custom dataset

python train.py \
  --data ./data/custom.yaml \
  --weights yolov5s.pt \
  --batch 16 \
  --epochs 100 \
  --img 640 \
  --project runs/train \
  --name yolov5s_custom

```

### Programmatic Training

For integration into larger workflows, import the training module and pass parameters as a dictionary.

```python

# Minimal Python snippet for programmatic fine-tuning

import torch
from yolov5 import train  # the train module is executed as a script

cfg = {
    "data": "./data/custom.yaml",
    "weights": "yolov5s.pt",
    "batch": 16,
    "epochs": 100,
    "img": 640,
    "project": "runs/train",
    "name": "yolov5s_custom",
}

# Convert dict to command-line args and launch training

train.main(cfg)

```

## Optimization and Hardware Acceleration

Training efficiency relies on components in [`utils/torch_utils.py`](https://github.com/ultralytics/yolov5/blob/main/utils/torch_utils.py), which builds the optimizer (SGD or Adam) and manages Automatic Mixed Precision (AMP) for gradient scaling on modern GPUs. For small models like YOLOv5s, the repository provides [`data/hyp.scratch-low.yaml`](https://github.com/ultralytics/yolov5/blob/main/data/hyp.scratch-low.yaml) containing tuned hyperparameters specifically optimized for low-resource environments.

## Validation and Model Export

After training, evaluate your model's performance and prepare it for deployment.

### Running Validation

Use [`val.py`](https://github.com/ultralytics/yolov5/blob/main/val.py) to compute mAP (mean Average Precision) metrics on your validation set using the same data loading pipeline defined in [`utils/datasets.py`](https://github.com/ultralytics/yolov5/blob/main/utils/datasets.py).

```bash

# After training, evaluate on the validation set

python val.py --data ./data/custom.yaml --weights runs/train/yolov5s_custom/weights/best.pt --img 640

```

### Exporting to Production Formats

Convert your fine-tuned weights to deployment formats like ONNX, TorchScript, or TensorRT using [`export.py`](https://github.com/ultralytics/yolov5/blob/main/export.py).

```bash

# Export the fine-tuned model to ONNX (for deployment)

python export.py --weights runs/train/yolov5s_custom/weights/best.pt --include onnx --img 640

```

## Summary

- **Prepare data** in YOLO format with class indices and normalized bounding boxes `<class> <cx> <cy> <w> <h>`
- **Create a data YAML** configuration in [`custom_data.yaml`](https://github.com/ultralytics/yolov5/blob/main/custom_data.yaml) pointing to train/val splits and listing class names
- **Run** [`train.py`](https://github.com/ultralytics/yolov5/blob/main/train.py) **with pre-trained weights** to transfer backbone features from [`models/common.py`](https://github.com/ultralytics/yolov5/blob/main/models/common.py) while adapting the head in [`models/yolo.py`](https://github.com/ultralytics/yolov5/blob/main/models/yolo.py)
- **Utilize** [`utils/torch_utils.py`](https://github.com/ultralytics/yolov5/blob/main/utils/torch_utils.py) **for optimized training** with mixed precision and efficient optimizers
- **Validate with** [`val.py`](https://github.com/ultralytics/yolov5/blob/main/val.py) **and deploy via** [`export.py`](https://github.com/ultralytics/yolov5/blob/main/export.py) to convert your model to production-ready formats

## Frequently Asked Questions

### What is the difference between fine-tuning and training from scratch?

Fine-tuning initializes the backbone, neck, and compatible layers from a COCO-pretrained checkpoint (e.g., `yolov5s.pt`), whereas training from scratch starts with random initialization. Fine-tuning preserves low-level visual features in the CSP-Darknet backbone implemented in [`models/common.py`](https://github.com/ultralytics/yolov5/blob/main/models/common.py), allowing faster convergence and better performance with limited data.

### How does YOLOv5 handle different numbers of classes during fine-tuning?

The [`train.py`](https://github.com/ultralytics/yolov5/blob/main/train.py) script automatically detects the number of classes (`nc`) from your data YAML file and reinitializes the detection head in [`models/yolo.py`](https://github.com/ultralytics/yolov5/blob/main/models/yolo.py) to output the correct dimensionality for your specific class count. This allows the model to adapt to new categories while preserving the pre-trained backbone weights.

### What hardware requirements are needed for fine-tuning YOLOv5?

While requirements vary by model size, YOLOv5s can fine-tune on consumer GPUs with limited VRAM by using the hyperparameters defined in [`data/hyp.scratch-low.yaml`](https://github.com/ultralytics/yolov5/blob/main/data/hyp.scratch-low.yaml). The [`utils/torch_utils.py`](https://github.com/ultralytics/yolov5/blob/main/utils/torch_utils.py) module enables mixed-precision training to further reduce memory consumption and accelerate computation on compatible hardware.

### How do I evaluate my fine-tuned model's performance?

Run [`val.py`](https://github.com/ultralytics/yolov5/blob/main/val.py) with your data configuration and the path to your trained weights (e.g., `runs/train/yolov5s_custom/weights/best.pt`) to compute precision-recall metrics and mAP scores. This script uses the same data loading pipeline in [`utils/datasets.py`](https://github.com/ultralytics/yolov5/blob/main/utils/datasets.py) as the training script, ensuring consistent evaluation across your validation split.