.h5与.hdf5格式差异解析及Keras中load_model与load_weights的使用疑问解答
1. .h5 与 .hdf5 格式有什么区别?
其实这俩完全是一回事!HDF5是Hierarchical Data Format 5的缩写,.h5只是它的简写扩展名,本质上属于同一种文件格式。不管你用哪个后缀,Keras、HDFView这类工具对它们的处理没有任何区别——你甚至可以把一个.h5文件直接重命名为.hdf5,功能丝毫不影响。
2. Keras 中模型/权重文件加载的常见疑问
下面针对你提到的几个问题逐个拆解,结合代码示例让你一目了然:
2.1 能否用 load_model 加载预训练权重/模型?
这得看文件是怎么保存的:
- 如果这个
.h5/.hdf5文件是用model.save()保存的完整模型(包含架构、权重、优化器状态、损失函数配置等所有信息),那直接用load_model加载完全没问题,加载完就能直接用。 - 但如果只是单独的权重文件(比如作者用
model.save_weights()导出的),那load_model加载会直接报错——因为它找不到模型架构的元数据。
2.2 load_model 与 load_weights 之间有什么区别?
这两个方法的定位完全不同,我用实际场景和代码来区分:
load_model:加载完整的"即用型"模型
它会把整个模型的所有信息都加载进来,包括:
- 模型的层结构和连接方式
- 所有层的权重参数
- 训练时的优化器状态(比如之前训练到第几轮、学习率是多少)
- 损失函数、评估指标的配置
加载后你不需要做额外操作,直接就能用model.predict()预测,或者继续model.fit()训练。
from tensorflow.keras.models import load_model # 加载用model.save()保存的完整模型 model = load_model('full_model.h5') # 直接预测 predictions = model.predict(test_images) # 继续训练 model.fit(train_images, train_labels, epochs=3)
load_weights:仅加载权重参数
它只负责把预训练的权重数值赋值给你预先定义好的模型架构,不包含任何架构、优化器或损失函数的信息。所以使用它的前提是:你必须先手动构建一个和原模型完全一致的架构(层类型、参数数量、输入输出形状都要匹配)。
from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense # 第一步:复刻原模型的架构 def build_mnist_model(): model = Sequential([ Conv2D(32, (3,3), activation='relu', input_shape=(28,28,1)), MaxPooling2D((2,2)), Flatten(), Dense(128, activation='relu'), Dense(10, activation='softmax') ]) return model model = build_mnist_model() # 第二步:加载单独的权重文件 model.load_weights('mnist_weights.h5') # 注意:此时模型还没编译,如果要训练的话需要先编译 model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) model.fit(train_images, train_labels, epochs=3) # 只是预测的话,不用编译也能直接用 predictions = model.predict(test_images)
2.3 能否用Keras的load_model加载权重文件,还是应该用load_weights?
绝对不能用load_model加载单独的权重文件!load_model需要文件里包含模型架构的配置信息(比如JSON格式的层定义),而单独的权重文件只有参数张量,没有这些元数据,加载时会抛出类似ValueError: No model found in config file的错误。
正确的做法是:单独的权重文件必须用load_weights加载,而且要先构建好对应的模型架构。
2.4 如果加载权重,是否必须同时加载完整的模型架构?
是的,必须要有和原模型完全一致的架构。因为权重文件里的参数是和模型的层一一绑定的——每个层的参数形状、数量都要严格匹配。比如原模型第一层是32个3x3的卷积核,你新定义的模型第一层也得是一样的参数,否则加载时会报形状不兼容的错误。
要是你没有原模型的代码,很多作者会同时提供架构的JSON/YAML文件,你可以先加载架构再加载权重:
from tensorflow.keras.models import model_from_json # 加载架构JSON文件 with open('model_architecture.json', 'r') as f: model_json = f.read() model = model_from_json(model_json) # 加载权重 model.load_weights('model_weights.h5')
内容的提问来源于stack exchange,提问作者user2986845

