加载Keras模型Checkpoint后首次评估验证损失上升问题求助
问题原因及解决方法
核心原因
- 优化器状态未正确恢复:训练到验证损失0.8时,优化器的学习率已经经过衰减降到了较低值,续训时如果没加载到优化器的衰减状态、动量等参数,学习率会重置回初始值,导致模型参数震荡,验证损失飙升。
- ModelCheckpoint初始阈值默认不合理:续训时新初始化的ModelCheckpoint会把最优值默认设为
inf,第一次评估的0.85虽然比之前的0.8差,但仍小于inf,会被判定为“最优”从而覆盖原有模型。
正确续训步骤
1. 完整保存/加载优化器状态
- 保存时保持
save_weights_only=False(你的代码默认就是该设置),确保模型文件包含优化器状态。 - 加载时不要重新编译模型,直接用
load_model加载后开始续训,否则会重置优化器状态:# 正确加载,无需额外compile model = tf.keras.models.load_model("count_fingers.h5") - 如果用
load_weights,需先构建和原模型结构完全一致的模型,用训练时相同的优化器配置编译后再加载权重:# 先构建原模型结构 model = build_your_finger_count_model() # 替换为你实际的模型构建函数 # 用训练时完全一致的优化器参数编译 optimizer = tf.keras.optimizers.Adam(learning_rate=0.001, decay=1e-6) # 替换为你训练时的配置 model.compile(optimizer=optimizer, loss="sparse_categorical_crossentropy", metrics=["accuracy"]) # 加载权重 model.load_weights("count_fingers.h5")
2. 手动设定ModelCheckpoint初始最优阈值
续训时给ModelCheckpoint传入initial_value_threshold参数,设置为之前保存模型时的验证损失值(0.8),只有当新的验证损失低于该值时才会保存,避免覆盖原有最优模型:
checkpoint = ModelCheckpoint( "count_fingers.h5", monitor="val_loss", verbose=1, save_best_only=True, save_freq="epoch", initial_value_threshold=0.8 # 手动指定初始最优阈值 )
3. 验证学习率是否正确恢复
续训前可以打印当前优化器的学习率,确认是否和训练到保存点时的衰减值一致:
print("当前学习率:", model.optimizer.learning_rate.numpy())
如果显示的是初始学习率,说明优化器状态未恢复,检查加载步骤是否正确。
4. 备选:手动调整续训初始学习率
如果无法恢复优化器状态,可以手动设置一个接近训练后期的低学习率:
model.optimizer.learning_rate.assign(0.0001) # 替换为你估算的衰减后学习率
内容的提问来源于stack exchange,提问作者Spider
相关产品推荐
相关产品推荐

