【深度学习 超参调优】lr0与lrf 的关系

文章目录

1. 理解 LRF(最终学习率因子)

在 YOLOv5/8 等框架中:

  • lr0:初始学习率(初始值)
  • lrf:最终学习率因子(Final Learning Rate factor)
  • 最终学习率 = lr0 × lrf

例如

  • lr0=0.01, lrf=0.01 → 最终学习率 = 0.0001
  • lr0=0.1, lrf=0.01 → 最终学习率 = 0.001

2. 调整原则:当 lr0 增大时

核心原则:保持最终学习率在合理范围内

python 复制代码
# 最终学习率的合理范围通常是:
合理的最终学习率 ≈ 1e-4 到 1e-6

# 所以:
# 如果增大 lr0,应该相应减小 lrf
新的_lrf = 期望的最终学习率 / 新的_lr0

具体策略:

策略A:保持最终学习率不变(推荐)
python 复制代码
# 原始设置
lr0_old = 0.01
lrf_old = 0.01
final_lr_target = lr0_old * lrf_old  # = 0.0001

# 增大 lr0
lr0_new = 0.05  # 增大5倍

# 计算新的 lrf 以保持最终学习率不变
lrf_new = final_lr_target / lr0_new  # = 0.0001 / 0.05 = 0.002

print(f"lr0: {lr0_old}→{lr0_new}, lrf: {lrf_old}→{lrf_new}")
print(f"最终学习率保持: {final_lr_target}")
策略B:按比例调整(简单但不推荐)
python 复制代码
# 如果 lr0 增大 N 倍,lrf 减小 N 倍
N = lr0_new / lr0_old  # 增大倍数
lrf_new = lrf_old / N

3. 不同场景下的 LRF 设置建议

基础模型训练(YOLOv5/v8 默认)

yaml 复制代码
# 默认配置(适用于大多数情况)
lr0: 0.01
lrf: 0.01  # 最终学习率 = 0.0001

增大 lr0 的场景及调整:

场景1:大 batch size(>64)
yaml 复制代码
# 大 batch size 需要更大的 lr0
batch_size: 128
lr0: 0.05  # 增大 5倍
lrf: 0.002  # 减小到 1/5,保持最终学习率 ~0.0001
场景2:使用预训练权重(迁移学习)
yaml 复制代码
# 预训练模型需要更小的学习率
weights: 'yolov8n.pt'
lr0: 0.001  # 比默认小
lrf: 0.1  # 可以相对大一些,最终学习率 = 0.0001
场景3:小数据集
yaml 复制代码
# 小数据集容易过拟合
dataset_size: 1000
lr0: 0.005  # 使用更小的初始学习率
lrf: 0.02  # 更快的衰减,最终学习率 = 0.0001
场景4:复杂模型(更多参数)
yaml 复制代码
# 模型越大,需要越小的学习率
model: 'yolov8x'
lr0: 0.008  # 稍小于默认
lrf: 0.0125  # 最终学习率 = 0.0001

4. 如何选择最优的 LRF

方法1:网格搜索(系统化)

python 复制代码
# 测试不同组合
lr0_candidates = [0.005, 0.01, 0.02, 0.05]
lrf_candidates = [0.001, 0.01, 0.1]

# 确保最终学习率在合理范围
for lr0 in lr0_candidates:
    for lrf in lrf_candidates:
        final_lr = lr0 * lrf
        if 1e-6 <= final_lr <= 1e-3:  # 合理范围
            print(f"lr0={lr0}, lrf={lrf}, final={final_lr}")

方法2:根据训练曲线调整

python 复制代码
# 观察训练损失曲线
if 训练损失_震荡严重:
    # 学习率太大
    减小_lr0 或 减小_lrf(更快衰减)
    
elif 训练损失_下降太慢:
    # 学习率太小或衰减太快
    增大_lr0 或 增大_lrf(更慢衰减)
    
elif 验证损失_上升(过拟合):
    # 衰减不够快
    减小_lrf(更快衰减到小学习率)

方法3:余弦退火衰减(更平滑)

yaml 复制代码
# 使用余弦衰减代替线性衰减
cos_lr: true  # 启用余弦衰减
lrf: 0.01  # 最小学习率因子
# 余弦衰减:lr = lr0 * (0.5 * (1 + cos(epoch/total_epochs * π)) * (1 - lrf) + lrf)

5. 不同衰减策略对比

线性衰减(默认)

python 复制代码
# 线性衰减公式
lr_epoch = lr0 * (1 - (1 - lrf) * epoch / total_epochs)

# 示例:lr0=0.01, lrf=0.01, epochs=300
# epoch 0: 0.01
# epoch 150: 0.00505
# epoch 300: 0.0001

余弦衰减(更平滑)

python 复制代码
# 余弦衰减公式(启用 cos_lr: true)
lr_epoch = lr0 * ((1 + cos(π * epoch / total_epochs)) / 2) * (1 - lrf) + lrf

# 特点:早期衰减慢,后期衰减快

指数衰减

python 复制代码
# 指数衰减(某些框架支持)
decay_rate = lrf ** (1 / total_epochs)
lr_epoch = lr0 * (decay_rate ** epoch)

# 特点:早期衰减快,后期衰减慢

6. 实战建议与经验法则

经验法则表格

场景 lr0 lrf 最终学习率 说明
标准训练 0.01 0.01 1e-4 默认配置
大batch 0.02-0.05 0.002-0.005 1e-4 线性缩放规则
小数据集 0.005 0.02 1e-4 防止过拟合
迁移学习 0.001 0.1 1e-4 微调需要小学习率
复杂任务 0.008 0.0125 1e-4 更稳定的训练
简单任务 0.02 0.005 1e-4 快速收敛

推荐配置模板

yaml 复制代码
# 配置文件中的学习率设置
lr0: 0.01  # 初始学习率
lrf: 0.01  # 最终学习率因子
# 最终学习率 = 0.01 * 0.01 = 0.0001

# 如果需要调整:
# 1. 先确定期望的最终学习率(通常 0.00001 - 0.001)
# 2. 根据任务难度调整 lr0
# 3. 计算 lrf = 期望最终学习率 / lr0

自动调整脚本

python 复制代码
def auto_adjust_lrf(lr0_new, lr0_default=0.01, lrf_default=0.01):
    """
    根据新的 lr0 自动调整 lrf
    保持最终学习率与默认配置相似
    """
    final_lr_default = lr0_default * lrf_default  # 0.0001
    
    # 计算新的 lrf
    lrf_new = final_lr_default / lr0_new
    
    # 设置边界
    lrf_new = max(0.0001, min(0.1, lrf_new))
    
    print(f"建议配置: lr0={lr0_new}, lrf={lrf_new:.4f}")
    print(f"最终学习率: {lr0_new * lrf_new:.6f}")
    
    return lrf_new

# 使用示例
lrf_adjusted = auto_adjust_lrf(lr0_new=0.05)

7. 调试技巧

监控学习率变化

python 复制代码
import matplotlib.pyplot as plt

def plot_lr_schedule(lr0, lrf, epochs=300):
    """绘制学习率衰减曲线"""
    lrs = []
    for epoch in range(epochs):
        # 线性衰减公式
        lr = lr0 * (1 - (1 - lrf) * epoch / epochs)
        lrs.append(lr)
    
    plt.figure(figsize=(10, 4))
    plt.plot(lrs)
    plt.xlabel('Epoch')
    plt.ylabel('Learning Rate')
    plt.title(f'lr0={lr0}, lrf={lrf}, final={lrs[-1]:.6f}')
    plt.grid(True)
    plt.show()

# 对比不同配置
plot_lr_schedule(lr0=0.01, lrf=0.01)
plot_lr_schedule(lr0=0.05, lrf=0.002)

训练中验证

bash 复制代码
# 训练时观察日志
python train.py --lr0 0.05 --lrf 0.002 --epochs 50

# 监控训练曲线
# 1. 损失是否平稳下降?
# 2. 验证精度是否稳定上升?
# 3. 是否有震荡或不收敛?

总结建议

  1. 基本原则 :当 lr0 增大时,lrf 应减小,以保持最终学习率在合理范围(1e-4 到 1e-6)

  2. 实用公式

    复制代码
    lrf_new = (期望的最终学习率) / lr0_new
    # 期望的最终学习率通常取 0.0001
  3. 推荐流程

    python 复制代码
    1. 先用默认配置训练几轮,观察收敛情况
    2. 如果收敛慢,尝试增大 lr0(如 0.01→0.02)
    3. 按比例调整 lrf:lrf_new = lrf_default * (lr0_default / lr0_new)
    4. 重新训练,监控损失曲线
    5. 微调 lrf 直到获得最佳效果
  4. 注意:没有绝对的最优值,最佳配置取决于你的:

    • 数据集大小和复杂度
    • 模型结构
    • 训练硬件(batch size)
    • 任务难度

最简单的做法 :如果你只是轻微调整 lr0(比如 0.01→0.02),那么将 lrf 减半(0.01→0.005)通常是个不错的起点。

相关推荐
eastyuxiao10 小时前
思维导图拆解项目范围 3 个真实落地案例
大数据·运维·人工智能·流程图
风落无尘10 小时前
《智能重生:从垃圾堆到AI工程师》——第五章 代码与灵魂
服务器·网络·人工智能
冬奇Lab11 小时前
RAG 系列(八):RAG 评估体系——用数据说话
人工智能·llm
landyjzlai11 小时前
蓝迪哥玩转Ai(8)---端侧AI:RK3588 端侧大语言模型(LLM)开发实战指南
人工智能·python
ZhengEnCi13 小时前
05-自注意力机制详解 🧠
人工智能·pytorch·深度学习
前端程序媛-Tian14 小时前
前端 AI 提效实战:从 0 到 1 打造团队专属 AI 代码评审工具
前端·人工智能·ai
weixin_4171970514 小时前
DeepSeek V4绑定华为:一场飞行中换引擎的国产算力革命
人工智能·华为
翼龙云_cloud14 小时前
阿里云代理商:阿里云深度适配DeepSeek V4让中小企业 AI零门槛上云
人工智能·阿里云·云计算·ai智能体·deepseek v4