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

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, 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 – Contains the main evolution loop, population management, and fitness evaluation logic
  • utils/general.py – Houses print_mutation(), which logs individual metrics to CSV and YAML formats
  • 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 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 (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 – 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:


# 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:

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, with optional --resume_evolve for continuity
  • Fitness Metric: Validation mAP@0.5 determines individual survival, logged via utils/general.py
  • Deliverables: The process outputs hyp_evolve.yaml (best config), evolve.csv (full log), and evolve.png (visualization)

Frequently Asked Questions

The mutability of each hyperparameter is controlled by metadata in the YAML file loaded via opt.hyp. In 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 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 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →