Skip to main content

Evolução de Hiperparâmetros para YOLOv5

📚 Este guia explica evolução de hiperparâmetros para YOLOv5 🚀. A evolução de hiperparâmetros é um método de Otimização de Hiperparâmetros usando um Algoritmo Genético (GA) para otimização.

Hiperparâmetros em machine learning controlam vários aspectos do treinamento, e encontrar valores ideais para eles pode ser um desafio. Métodos tradicionais como busca em grade (grid searches) podem rapidamente se tornar impraticáveis devido a:

  1. O espaço de busca de alta dimensionalidade
  2. Correlações desconhecidas entre as dimensões
  3. A natureza cara de avaliar a aptidão (fitness) em cada ponto

Isso torna os algoritmos genéticos um candidato adequado para buscas de hiperparâmetros.

Antes de começar

Clone o repositório e instale requirements.txt em um Python>=3.8.0 ambiente, incluindo PyTorch>=1.8. Modelos e datasets download automaticamente a partir do YOLOv5 mais recente release.

git clone https://github.com/ultralytics/yolov5 # clone
cd yolov5
pip install -r requirements.txt # install

1. Inicializar Hiperparâmetros

O YOLOv5 possui cerca de 30 hiperparâmetros usados para várias configurações de treinamento. Eles são definidos em arquivos *.yaml no diretório /data/hyps. Melhores estimativas iniciais produzirão melhores resultados finais, portanto, é importante inicializar esses valores corretamente antes de evoluir. Em caso de dúvida, simplesmente use os valores padrão, que são otimizados para o treinamento YOLOv5 COCO do zero.

# YOLOv5 🚀 by Ultralytics, AGPL-3.0 license
# Hyperparameters for low-augmentation COCO training from scratch
# python train.py --batch 64 --cfg yolov5n6.yaml --weights '' --data coco.yaml --img 640 --epochs 300 --linear
# See tutorials for hyperparameter evolution https://github.com/ultralytics/yolov5#tutorials

lr0: 0.01 # initial learning rate (SGD=1E-2, Adam=1E-3)
lrf: 0.01 # final OneCycleLR learning rate (lr0 * lrf)
momentum: 0.937 # SGD momentum/Adam beta1
weight_decay: 0.0005 # optimizer weight decay 5e-4
warmup_epochs: 3.0 # warmup epochs (fractions ok)
warmup_momentum: 0.8 # warmup initial momentum
warmup_bias_lr: 0.1 # warmup initial bias lr
box: 0.05 # box loss gain
cls: 0.5 # cls loss gain
cls_pw: 1.0 # cls BCELoss positive_weight
obj: 1.0 # obj loss gain (scale with pixels)
obj_pw: 1.0 # obj BCELoss positive_weight
iou_t: 0.20 # IoU training threshold
anchor_t: 4.0 # anchor-multiple threshold
# anchors: 3  # anchors per output layer (0 to ignore)
fl_gamma: 0.0 # focal loss gamma (efficientDet default gamma=1.5)
hsv_h: 0.015 # image HSV-Hue augmentation (fraction)
hsv_s: 0.7 # image HSV-Saturation augmentation (fraction)
hsv_v: 0.4 # image HSV-Value augmentation (fraction)
degrees: 0.0 # image rotation (+/- deg)
translate: 0.1 # image translation (+/- fraction)
scale: 0.5 # image scale (+/- gain)
shear: 0.0 # image shear (+/- deg)
perspective: 0.0 # image perspective (+/- fraction), range 0-0.001
flipud: 0.0 # image flip up-down (probability)
fliplr: 0.5 # image flip left-right (probability)
mosaic: 1.0 # image mosaic (probability)
mixup: 0.0 # image mixup (probability)
copy_paste: 0.0 # segment copy-paste (probability)

2. Definir Aptidão (Fitness)

Aptidão é o valor que buscamos maximizar. No YOLOv5, definimos uma função de aptidão padrão como uma combinação ponderada de métricas: mAP@0.5 contribui com 10% do peso e mAP@0.5:0.95 contribui com os 90% restantes, com precisão (P) e revocação (R) ausentes. Você pode ajustar isso como achar melhor ou usar a definição de aptidão padrão em utils/metrics.py (recomendado).

def fitness(x):
    """Return model fitness as the sum of weighted metrics [P, R, mAP@0.5, mAP@0.5:0.95]."""
    w = [0.0, 0.0, 0.1, 0.9]  # weights for [P, R, mAP@0.5, mAP@0.5:0.95]
    return (x[:, :4] * w).sum(1)

3. Evoluir

A evolução é realizada em torno de um cenário base que buscamos melhorar. O cenário base neste exemplo é dicas de treino de modelos COCO128 por 10 epochs usando o YOLOv5s pré-treinado. O comando de treinamento do cenário base é:

python train.py --epochs 10 --data coco128.yaml --weights yolov5s.pt --cache

Para evoluir hiperparâmetros específicos para este cenário, começando de nossos valores iniciais definidos na Seção 1., e maximizando a aptidão definida na Seção 2., anexe --evolve:

# Single-GPU
python train.py --epochs 10 --data coco128.yaml --weights yolov5s.pt --cache --evolve

# Multi-GPU with delay
for i in {0..7}; do
  sleep $((30 * i)) # 30-second delay (optional)
  echo "Starting GPU $i..."
  nohup python train.py --epochs 10 --data coco128.yaml --weights yolov5s.pt --cache --device $i --evolve > "evolve_gpu_$i.log" &
done

# Continuous training (use with caution)
# for i in {0..7}; do
#   sleep $((30 * i))  # 30-second delay (optional)
#   echo "Starting continuous training on GPU $i..."
#   (
#     while true; do
#       python train.py --epochs 10 --data coco128.yaml --weights yolov5s.pt --cache --device $i --evolve > "evolve_gpu_$i.log"
#     done
#   ) &
# done

As configurações padrão de evolução executarão o cenário base 300 vezes, ou seja, por 300 gerações. Você pode modificar as gerações através do argumento --evolve, ou seja, python train.py --evolve 1000.

Os principais operadores genéticos são cruzamento (crossover) e mutação. Neste trabalho, a mutação é usada, com 80% de probabilidade e 0,04 de variância para criar novas descendências baseadas em uma combinação dos melhores pais de todas as gerações anteriores. Os resultados são registrados em runs/evolve/exp/evolve.csv, e a descendência com maior aptidão é salva a cada geração como runs/evolve/hyp_evolved.yaml:

# YOLOv5 Hyperparameter Evolution Results
# Best generation: 287
# Last generation: 300
#    metrics/precision,       metrics/recall,      metrics/mAP_0.5, metrics/mAP_0.5:0.95,         val/box_loss,         val/obj_loss,         val/cls_loss
#              0.54634,              0.55625,              0.58201,              0.33665,             0.056451,             0.042892,             0.013441

lr0: 0.01 # initial learning rate (SGD=1E-2, Adam=1E-3)
lrf: 0.2 # final OneCycleLR learning rate (lr0 * lrf)
momentum: 0.937 # SGD momentum/Adam beta1
weight_decay: 0.0005 # optimizer weight decay 5e-4
warmup_epochs: 3.0 # warmup epochs (fractions ok)
warmup_momentum: 0.8 # warmup initial momentum
warmup_bias_lr: 0.1 # warmup initial bias lr
box: 0.05 # box loss gain
cls: 0.5 # cls loss gain
cls_pw: 1.0 # cls BCELoss positive_weight
obj: 1.0 # obj loss gain (scale with pixels)
obj_pw: 1.0 # obj BCELoss positive_weight
iou_t: 0.20 # IoU training threshold
anchor_t: 4.0 # anchor-multiple threshold
# anchors: 3  # anchors per output layer (0 to ignore)
fl_gamma: 0.0 # focal loss gamma (efficientDet default gamma=1.5)
hsv_h: 0.015 # image HSV-Hue augmentation (fraction)
hsv_s: 0.7 # image HSV-Saturation augmentation (fraction)
hsv_v: 0.4 # image HSV-Value augmentation (fraction)
degrees: 0.0 # image rotation (+/- deg)
translate: 0.1 # image translation (+/- fraction)
scale: 0.5 # image scale (+/- gain)
shear: 0.0 # image shear (+/- deg)
perspective: 0.0 # image perspective (+/- fraction), range 0-0.001
flipud: 0.0 # image flip up-down (probability)
fliplr: 0.5 # image flip left-right (probability)
mosaic: 1.0 # image mosaic (probability)
mixup: 0.0 # image mixup (probability)
copy_paste: 0.0 # segment copy-paste (probability)

Recomendamos um mínimo de 300 gerações de evolução para melhores resultados. Note que a evolução é geralmente cara e consome muito tempo, pois o cenário base é treinado centenas de vezes, possivelmente exigindo centenas ou milhares de horas de GPU.

Quando a evolução terminar, reutilize as configurações descobertas apontando o treinamento para o arquivo salvo, por exemplo python train.py --hyp runs/evolve/hyp_evolved.yaml --data your.yaml --weights yolov5s.pt.

4. Visualizar

evolve.csv é plotado como evolve.png por utils.plots.plot_evolve() após a conclusão da evolução com um subgráfico por hiperparâmetro mostrando a aptidão (eixo y) versus valores de hiperparâmetros (eixo x). Amarelo indica maiores concentrações. Distribuições verticais indicam que um parâmetro foi desativado e não sofre mutação. Isso é selecionável pelo usuário no dicionário meta em train.py, e é útil para fixar parâmetros e impedi-los de evoluir.

Resultados de aptidão da evolução de hiperparâmetros do YOLOv5

Ambientes Suportados

A Ultralytics fornece uma gama de ambientes prontos para uso, cada um pré-instalado com dependências essenciais, como CUDA, CUDNN, Python, e Modelos , para dar início aos teus projetos.

Status do Projeto

YOLOv5 CI

Este selo indica que todos os testes de Integração Contínua (CI) do YOLOv5 GitHub Actions foram concluídos com sucesso. Esses testes de CI verificam rigorosamente a funcionalidade e o desempenho do YOLOv5 em vários aspectos fundamentais: training, validação, inferência, export, e benchmarks. Eles garantem uma operação consistente e confiável no macOS, Windows e Ubuntu, com testes conduzidos a cada 24 horas e a cada novo commit.

Comentários