tf.keras.models.load_model参数及模型权重恢复失败求助
Keras模型权重保存与恢复问题排查
问题背景
作为Python新手,配置Keras模型权重的保存与恢复时遇到问题:训练彩票预测模型时,老旧电脑在900轮后会随机冻结,因此使用ModelCheckpoint保存权重以实现断点续训,但加载权重后模型准确率仅0.08%(之前训练曾达60%),仿佛回到初始状态。
相关代码
检查点配置
checkpoint_filepath="/home/ubuntu/Downloads/Lottery/checkpoints/lottery/" model_checkpoint_callback = ModelCheckpoint( filepath=os.path.join(checkpoint_filepath,"weights-improvement.hd5"), monitor='val_accuracy', verbose=1, save_best_only=True, save_weights_only=True, save_freq='epoch', mode='max') es = EarlyStopping(monitor='val_accuracy', patience=5) callbacks_list = [model_checkpoint_callback, es]
模型加载代码
model.load_weights("/home/ubuntu/Downloads/Lottery/checkpoints/lottery/weights-improvement.hd5") loss, acc = model.evaluate(train_samples, train_labels, verbose=2) print("Restored model, accuracy: {:5.2f}%".format(100 * acc)) load_model('/home/ubuntu/Downloads/Lottery/lottery/')
模型训练代码
model.fit(x=x_train, y=y_train, batch_size=32, epochs=1200, verbose=2, callbacks=[model_checkpoint_callback], validation_split=0.22) model.save('lottery')
错误分析
- 加载顺序错误,权重被覆盖:加载代码中,先执行
model.load_weights()加载了训练好的权重,随后调用的load_model()会创建新的模型实例并加载该模型文件中的权重,直接覆盖了之前加载的checkpoint权重,导致最终使用的是lottery模型的权重(可能为初始或训练早期权重),因此准确率回到初始状态。 - 断点续训未指定起始轮次:即使正确加载了权重,若继续训练时未设置
initial_epoch参数,模型会从第0轮重新训练,覆盖已加载的权重。
正确解决方案
1. 修正权重加载流程
删除加载代码中多余的load_model()调用,确保加载的checkpoint权重不被覆盖。如果需要先加载模型结构,可先加载完整模型再覆盖权重:
方式一:先构建模型结构,再加载权重
# 先编写与训练时完全一致的模型构建代码,例如: # model = Sequential([ # Dense(64, activation='relu', input_shape=(input_dim,)), # Dense(32, activation='relu'), # Dense(num_classes, activation='softmax') # ]) # model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) # 加载checkpoint权重 model.load_weights("/home/ubuntu/Downloads/Lottery/checkpoints/lottery/weights-improvement.hd5") # 评估模型 loss, acc = model.evaluate(train_samples, train_labels, verbose=2) print("Restored model, accuracy: {:5.2f}%".format(100 * acc)) # 继续训练(假设之前训练到899轮) model.fit(x=x_train, y=y_train, batch_size=32, epochs=1200, verbose=2, callbacks=[model_checkpoint_callback], validation_split=0.22, initial_epoch=899)
方式二:先加载完整模型,再覆盖最优权重
from tensorflow.keras.models import load_model # 加载之前保存的完整模型 model = load_model('/home/ubuntu/Downloads/Lottery/lottery/') # 加载checkpoint中的最优权重 model.load_weights("/home/ubuntu/Downloads/Lottery/checkpoints/lottery/weights-improvement.hd5") # 评估或继续训练
2. 断点续训的关键配置
继续训练时,必须通过initial_epoch参数指定起始轮次,避免模型从第0轮重新训练:
# 例如之前训练到899轮,设置initial_epoch=899,模型会从第900轮开始训练 model.fit(..., initial_epoch=899)
3. tf.keras.models.load_model正确参数说明
load_model用于加载完整模型(结构、权重、优化器状态等),核心参数:
filepath:必填,模型保存的路径(如你之前保存的lottery文件夹路径)compile:可选,默认True,加载时是否编译模型,仅做预测时可设为Falsecustom_objects:可选,若模型使用了自定义层、损失函数,需在此指定映射,例如custom_objects={'my_custom_loss': my_loss_func}
内容的提问来源于stack exchange,提问作者Wisdom
相关产品推荐
相关产品推荐

