# How Hyperparameter Evolution Works in YOLOv5 Training: A Complete Guide to Genetic Algorithm Optimization

> Discover how YOLOv5 uses genetic algorithm hyperparameter evolution to automatically find optimal training settings. Learn to leverage the evolve flag for better mAP.

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

---

**YOLOv5 implements a genetic algorithm (GA)-based hyperparameter evolution system, triggered by the `--evolve` CLI flag, that automatically discovers optimal training configurations by iteratively mutating, evaluating, and selecting hyperparameter sets based on validation mAP metrics.**

Hyperparameter evolution in the `ultralytics/yolov5` repository eliminates manual tuning by treating training configurations as genetic individuals that adapt over generations. This system searches across mutable parameters—such as learning rate, weight decay, and augmentation probabilities—to maximize validation performance without human intervention.

## Overview of the Genetic Algorithm Implementation

The evolution engine resides primarily in [`train.py`](https://github.com/ultralytics/yolov5/blob/main/train.py), where the standard training loop is replaced by a GA when the `--evolve` argument is passed. Instead of training a single model to completion, the script runs a population of hyperparameter sets through shortened training cycles, treating the resulting mAP@0.5 as a fitness score.

Key source files include:
- **[`train.py`](https://github.com/ultralytics/yolov5/blob/main/train.py)** – Contains the main evolution loop, population management, and fitness evaluation logic
- **[`utils/general.py`](https://github.com/ultralytics/yolov5/blob/main/utils/general.py)** – Houses `print_mutation()`, which logs individual metrics to CSV and YAML formats
- **[`utils/plots.py`](https://github.com/ultralytics/yolov5/blob/main/utils/plots.py)** – Provides `plot_evolve()` to visualize fitness trends across generations

## Evolution Workflow Step-by-Step

The GA follows a structured pipeline from initialization to final output, with each generation refining the search space toward higher-performing configurations.

### Configuration and Search Space Setup

The process begins by loading baseline hyperparameters from the file specified in `opt.hyp` (typically located in `data/hyps/`). In [`train.py`](https://github.com/ultralytics/yolov5/blob/main/train.py) lines 36-62, the system filters this dictionary to retain only mutable entries—those not explicitly marked with `False` in their metadata. Lines 63-66 then extract lower and upper bound values from the meta dictionary, creating `lower_limit` and `upper_limit` arrays that constrain the search space.

Fixed GA hyperparameters are defined in lines 25-35, including:
- Population size
- Minimum and maximum elite sizes
- Tournament size ranges
- Initial and final mutation/crossover rates

### Population Initialization

Depending on CLI arguments, the population is seeded differently. If `--resume_evolve` is provided, the system loads previously saved individuals from the specified YAML file (lines 70-90). Otherwise, it generates random individuals by sampling uniformly within the defined bounds or loading candidate sets from files in `opt.evolve_population`.

### The Evolution Loop

Each generation follows a strict evaluation and reproduction cycle repeated for the number of iterations specified by `opt.evolve` (default 300):

**Fitness Evaluation (lines 14-22):** For each individual, genes are copied into a temporary hyperparameter dictionary `hyp_GA`, then `train()` is invoked with `nosave` and `noval` disabled. The third metric returned—mAP@0.5—serves as the fitness score. The `print_mutation()` function in [`utils/general.py`](https://github.com/ultralytics/yolov5/blob/main/utils/general.py) (lines 38-46) records these metrics to `evolve.csv`.

**Elite Selection (lines 11-13):** The top-performing individuals, determined by an adaptive `elite_size` parameter, are preserved unchanged into the next generation to ensure high-quality solutions persist.

**Tournament Selection (lines 34-42):** Remaining parents are chosen via tournament selection where a random subset of size `tournament_size` competes, and the fittest individual wins. This subset size shrinks linearly over generations to transition from broad exploration to focused exploitation.

**Crossover (lines 56-63):** With probability `crossover_rate`, two parents exchange genetic material at a random crossover point, producing a child individual that combines traits from both parents.

**Mutation (lines 66-72):** Each gene in the child mutates with probability `mutation_rate`, adding a uniform offset (±0.1) and clamping the result to the parameter's allowed range. Both crossover and mutation rates decay linearly across generations to stabilize convergence.

After creating offspring, the new population replaces the old (lines 74-75), and the loop continues.

## Adaptive Evolutionary Parameters

YOLOv5's GA dynamically adjusts its operators to balance exploration and exploitation:

- **`elite_size`** – Grows linearly from `min_elite_size` to `max_elite_size`, increasing preservation pressure on high-fitness individuals as the search progresses
- **`tournament_size`** – Decays from `tournament_size_max` to `tournament_size_min`, shifting from diverse early competition to elite-focused selection later
- **`crossover_rate` and `mutation_rate`** – Both start at their maximum values and decay to minimums, reducing genetic diversity disruption as the population converges toward optimal regions

## Output Files and Results

Upon completion, the system generates three key artifacts in the runs directory:

- **`evolve.csv`** – Comma-separated log of every individual's hyperparameters and corresponding fitness metrics across all generations
- **[`hyp_evolve.yaml`](https://github.com/ultralytics/yolov5/blob/main/hyp_evolve.yaml)** – YAML file containing only the best-performing hyperparameter set (highest fitness) ready for production training
- **`evolve.png`** – Visualization of fitness trends and parameter distributions generated by `utils/plots.plot_evolve()` (lines 400-410)

## Running Hyperparameter Evolution

Execute evolution from the command line or programmatically:

```bash

# Quick 10-generation test evolution

python train.py --data coco.yaml --cfg yolov5s.yaml --hyp data/hyps/hyp.scratch-low.yaml --evolve 10

# Full 300-generation evolution (default)

python train.py --evolve

# Resume interrupted evolution

python train.py --evolve 300 --resume_evolve data/hyps/evolve_population.yaml

```

For programmatic control within Python:

```python
from train import run

# Run 50-generation evolution with custom hyperparameters

run(evolve=50, hyp='data/hyps/hyp.scratch-high.yaml')

```

## Summary

- **Genetic Algorithm Core:** YOLOv5's hyperparameter evolution uses a full GA implementation with elite preservation, tournament selection, crossover, and mutation
- **Adaptive Strategy:** Evolutionary operators (elite size, tournament size, crossover/mutation rates) adapt linearly across generations to shift from exploration to exploitation
- **Entry Point:** Trigger via `--evolve N` flag in [`train.py`](https://github.com/ultralytics/yolov5/blob/main/train.py), with optional `--resume_evolve` for continuity
- **Fitness Metric:** Validation mAP@0.5 determines individual survival, logged via [`utils/general.py`](https://github.com/ultralytics/yolov5/blob/main/utils/general.py)
- **Deliverables:** The process outputs [`hyp_evolve.yaml`](https://github.com/ultralytics/yolov5/blob/main/hyp_evolve.yaml) (best config), `evolve.csv` (full log), and `evolve.png` (visualization)

## Frequently Asked Questions

### How do I know which hyperparameters are mutable in the evolution search?

The mutability of each hyperparameter is controlled by metadata in the YAML file loaded via `opt.hyp`. In [`train.py`](https://github.com/ultralytics/yolov5/blob/main/train.py) lines 36-62, the system removes any entries where the mutable flag is explicitly set to `False`, leaving only parameters marked as mutable in the search space.

### What fitness metric does YOLOv5 use to evaluate hyperparameter sets?

According to the source code in [`train.py`](https://github.com/ultralytics/yolov5/blob/main/train.py) lines 14-22, the GA uses the third validation metric returned by the training function—specifically **mAP@0.5** (mean Average Precision at IoU threshold 0.5)—as the fitness score for selection decisions.

### Can I resume a hyperparameter evolution run if it gets interrupted?

Yes. Pass the `--resume_evolve` flag followed by the path to a YAML file containing the previous population. The system loads these saved individuals in [`train.py`](https://github.com/ultralytics/yolov5/blob/main/train.py) lines 70-90 instead of generating random initial candidates, allowing evolution to continue from the last known state.

### Why do the mutation and crossover rates decrease over generations?

As implemented in the adaptive parameter logic, both rates decay linearly from maximum to minimum values across the evolution duration. This design reduces genetic disruption as the population converges, allowing broad exploration in early generations while enabling fine-grained optimization and stability in later generations.