Skip to content

超参数演化

📚 本指南解释了YOLOv5 🚀 的超参数进化。超参数进化是一种使用遗传算法 (GA) 进行优化的超参数优化方法。

在机器学习中,超参数控制着训练的各个方面,找到它们的优化值可能是一个挑战。传统的网格搜索方法由于1) 高维搜索空间 2) 维度之间的未知相关性,以及3) 在每个点评估适应度的昂贵性,使得遗传算法成为超参数搜索的合适候选。

开始之前

克隆仓库并在Python>=3.8.0环境中安装requirements.txt,包括PyTorch>=1.8模型数据集会自动从最新的YOLOv5发布版本下载。

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

1. 初始化超参数

YOLOv5大约有30个超参数用于各种训练设置。这些参数在/data/hyps目录中的*.yaml文件中定义。更好的初始猜测将产生更好的最终结果,因此在进化之前正确初始化这些值非常重要。如果有疑问,只需使用默认值,这些值是为从头开始训练YOLOv5 COCO而优化的。

# YOLOv5 🚀 by Ultralytics, AGPL-3.0 license
# 用于从头开始低增强COCO训练的超参数
# python train.py --batch 64 --cfg yolov5n6.yaml --weights '' --data coco.yaml --img 640 --epochs 300 --linear
# 有关超参数进化的教程请参见 https://github.com/ultralytics/yolov5#tutorials

lr0: 0.01 # 初始学习率 (SGD=1E-2, Adam=1E-3)
lrf: 0.01 # 最终OneCycleLR学习率 (lr0 * lrf)
momentum: 0.937 # SGD动量/Adam beta1
weight_decay: 0.0005 # 优化器权重衰减 5e-4
warmup_epochs: 3.0 # 预热轮数 (分数可接受)
warmup_momentum: 0.8 # 预热初始动量
warmup_bias_lr: 0.1 # 预热初始偏置学习率
box: 0.05 # 边界框损失增益
cls: 0.5 # 分类损失增益
cls_pw: 1.0 # 分类BCELoss正权重
obj: 1.0 # 目标损失增益 (按像素缩放)
obj_pw: 1.0 # 目标BCELoss正权重
iou_t: 0.20 # IoU训练阈值
anchor_t: 4.0 # 锚点倍数阈值
# anchors: 3  # 每个输出层的锚点数 (0表示忽略)
fl_gamma: 0.0 # 焦点损失gamma (efficientDet默认gamma=1.5)
hsv_h: 0.015 # 图像HSV-色调增强 (分数)
hsv_s: 0.7 # 图像HSV-饱和度增强 (分数)
hsv_v: 0.4 # 图像HSV-值增强 (分数)
degrees: 0.0 # 图像旋转 (+/- 度)
translate: 0.1 # 图像平移 (+/- 分数)
scale: 0.5 # 图像缩放 (+/- 增益)
shear: 0.0 # 图像剪切 (+/- 度)
perspective: 0.0 # 图像透视 (+/- 分数), 范围 0-0.001
flipud: 0.0 # 图像上下翻转 (概率)
fliplr: 0.5 # 图像左右翻转 (概率)
mosaic: 1.0 # 图像马赛克 (概率)
mixup: 0.0 # 图像混合 (概率)
copy_paste: 0.0 # 分割复制粘贴 (概率)

2. 定义适应度

适应度是我们寻求最大化的值。在YOLOv5中,我们定义了一个默认的适应度函数,作为指标的加权组合:mAP@0.5贡献10%的权重,mAP@0.5:0.95贡献剩余的90%,精度 P召回率 R 不包括在内。您可以根据需要调整这些参数,或者使用utils/metrics.py中的默认适应度定义(推荐)。

def fitness(x):
    """返回模型适应度作为加权指标的总和 [P, R, mAP@0.5, mAP@0.5:0.95]。"""
    w = [0.0, 0.0, 0.1, 0.9]  # 权重 [P, R, mAP@0.5, mAP@0.5:0.95]
    return (x[:, :4] * w).sum(1)

3. 进化

进化是基于我们寻求改进的基础场景进行的。本例中的基础场景是使用预训练的YOLOv5s对COCO128进行10微调。基础场景的训练命令是:

python train.py --epochs 10 --data coco128.yaml --weights yolov5s.pt --cache
为了针对此场景进化超参数,从我们在第1节中定义的初始值开始,并最大化在第2节中定义的适应度,请追加 --evolve

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

# 多GPU
for i in 0 1 2 3 4 5 6 7; do
  sleep $(expr 30 \* $i) &&  # 30秒延迟(可选)
  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

# 多GPU bash-while(不推荐)
for i in 0 1 2 3 4 5 6 7; do
  sleep $(expr 30 \* $i) &&  # 30秒延迟(可选)
  echo 'Starting GPU '$i'...' &&
  "$(while true; do nohup python train.py... --device $i --evolve 1 > evolve_gpu_$i.log; done)" &
done

默认的进化设置将运行基础场景300次,即300代。您可以通过 --evolve 参数修改代数,例如 python train.py --evolve 1000

主要的遗传操作符是交叉变异。在这项工作中使用了变异,变异概率为80%,方差为0.04,以基于所有先前代中最佳父代的组合创建新的后代。结果记录在 runs/evolve/exp/evolve.csv 中,每代最高适应度的后代保存为 runs/evolve/hyp_evolved.yaml

# YOLOv5 超参数进化结果
# 最佳代数: 287
# 最后代数: 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 # 初始学习率 (SGD=1E-2, Adam=1E-3)
lrf: 0.2 # 最终 OneCycleLR 学习率 (lr0 * lrf)
momentum: 0.937 # SGD 动量/Adam beta1
weight_decay: 0.0005 # 优化器权重衰减 5e-4
warmup_epochs: 3.0 # 预热轮数 (分数可接受)
warmup_momentum: 0.8 # 预热初始动量
warmup_bias_lr: 0.1 # 预热初始偏置学习率
box: 0.05 # 边界框损失增益
cls: 0.5 # 分类损失增益
cls_pw: 1.0 # 分类 BCELoss 正样本权重
obj: 1.0 # 目标损失增益 (按像素缩放)
obj_pw: 1.0 # 目标 BCELoss 正样本权重
iou_t: 0.20 # IoU 训练阈值
anchor_t: 4.0 # 锚点倍数阈值
# anchors: 3  # 每个输出层的锚点数 (0 表示忽略)
fl_gamma: 0.0 # 焦点损失 gamma (efficientDet 默认 gamma=1.5)
hsv_h: 0.015 # 图像 HSV-Hue 增强 (分数)
hsv_s: 0.7 # 图像 HSV-Saturation 增强 (分数)
hsv_v: 0.4 # 图像 HSV-Value 增强 (分数)
degrees: 0.0 # 图像旋转 (+/- 度)
translate: 0.1 # 图像平移 (+/- 分数)
scale: 0.5 # 图像缩放 (+/- 增益)
shear: 0.0 # 图像剪切 (+/- 度)
perspective: 0.0 # 图像透视 (+/- 分数), 范围 0-0.001
flipud: 0.0 # 图像上下翻转 (概率)
fliplr: 0.5 # 图像左右翻转 (概率)
mosaic: 1.0 # 图像马赛克 (概率)
mixup: 0.0 # 图像混合 (概率)
copy_paste: 0.0 # 分割复制粘贴 (概率)

我们建议至少进行300代的进化以获得最佳结果。请注意,进化通常是昂贵且耗时的,因为基础场景需要训练数百次,可能需要数百或数千个GPU小时。

4. 可视化

evolve.csv 在进化完成后由 utils.plots.plot_evolve() 绘制为 evolve.png,每个超参数显示一个子图,展示适应度(y轴)与超参数值(x轴)的关系。黄色表示更高的浓度。垂直分布表示参数已被禁用且不发生变异。这在 train.pymeta 字典中是用户可选的,对于固定参数并防止其进化非常有用。

evolve

支持的环境

Ultralytics 提供了一系列开箱即用的环境,每个环境都预装了必要的依赖项,如 CUDACUDNNPythonPyTorch,以快速启动您的项目。

项目状态

YOLOv5 CI

此徽章表示所有 YOLOv5 GitHub Actions 持续集成 (CI) 测试均成功通过。这些 CI 测试严格检查 YOLOv5 在多个关键方面的功能和性能:训练验证推理导出基准测试。它们确保在 macOS、Windows 和 Ubuntu 上的操作一致且可靠,测试每 24 小时进行一次,并在每次新提交时进行。


📅 Created 11 months ago ✏️ Updated 20 days ago

Comments