You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Keras的ReduceLROnPlateau回调时如何在每一折重置学习率

Keras交叉验证逐折重置学习率实现方案

核心逻辑:ReduceLROnPlateau的动态调整状态是绑定在回调实例和模型优化器上的,只要在每一折训练前清空两类状态,就能实现每折lr从初始值开始重新触发衰减规则,不会继承上一折的调整结果。

具体实现步骤

  • 不要在交叉验证循环外提前定义ReduceLROnPlateau回调实例,将回调初始化逻辑放到每一折的循环内部,保证每折用的是无历史状态的全新回调。
  • 每一折训练前显式重置模型优化器的学习率为初始值,避免上一折训练结束时优化器已经将lr调整到较低值,新折训练起步lr异常。
  • 推荐每折直接实例化全新编译的模型,避免上一折训练的权重、优化器动量等状态跨折残留,保证交叉验证结果的可靠性。

可直接复用的代码示例

from sklearn.model_selection import KFold
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.callbacks import ReduceLROnPlateau

# 配置项
N_FOLDS = 5
INITIAL_LR = 1e-3
BATCH_SIZE = 32
EPOCHS = 50

# 加载数据、定义模型构建函数(略)
# def build_model():
#     模型结构定义
#     return model

kfold = KFold(n_splits=N_FOLDS, shuffle=True, random_state=42)
for fold_id, (train_idx, val_idx) in enumerate(kfold.split(X, y)):
    print(f"=== 开始训练第 {fold_id+1} 折 ===")
    # 拆分当前折的训练、验证集
    X_train, X_val = X[train_idx], X[val_idx]
    y_train, y_val = y[train_idx], y[val_idx]
    
    # 每折新建并编译模型,显式指定初始学习率
    model = build_model()
    model.compile(
        optimizer=Adam(learning_rate=INITIAL_LR),
        loss="categorical_crossentropy",
        metrics=["accuracy"]
    )
    
    # 每折初始化全新的lr调整回调,无历史状态
    lr_scheduler = ReduceLROnPlateau(
        monitor="val_loss",
        factor=0.5,
        patience=3,
        min_lr=1e-6,
        verbose=1
    )
    
    # 启动当前折训练
    model.fit(
        X_train, y_train,
        validation_data=(X_val, y_val),
        epochs=EPOCHS,
        batch_size=BATCH_SIZE,
        callbacks=[lr_scheduler]
    )

常见踩坑说明

如果你把ReduceLROnPlateau实例定义在交叉验证循环外,所有折共用同一个回调对象,回调内部存储的最优验证loss、等待衰减轮次、当前lr倍率等状态会跨折传递,直接导致lr调整逻辑混乱,完全达不到每折重置的效果。
如果你因为特殊需求不需要每折重建模型,只需要在每折训练前执行tf.keras.backend.set_value(model.optimizer.lr, INITIAL_LR)重置优化器lr,同时重新初始化ReduceLROnPlateau实例即可。

内容的提问来源于stack exchange,提问作者talha06

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 12:42:17