Keras 3 加载模型不支持格式?四种方法解决报错
2025-03-30 09:17:22
搞定 Keras 3 加载模型报错:File format not supported
完全指南
用 Keras 3 加载模型时,你可能踩到一个坑,看到这样一个让人头疼的 ValueError
:
ValueError: File format not supported: filepath=C:\Users\fedmor\Desktop\AI\resnet50_coco_best_v2.0.1 (1). Keras 3 only supports V3 `.keras` files and legacy H5 format files (`.h5` extension). Note that the legacy SavedModel format is not supported by `load_model()` in Keras 3. In order to reload a TensorFlow SavedModel as an inference-only layer in Keras 3, use `keras.layers.TFSMLayer(C:\Users\fedmor\Desktop\AI\resnet50_coco_best_v2.0.1 (1), call_endpoint='serving_default')` (note that your `call_endpoint` might have a different name).
这串错误信息看着挺吓人,但别慌,这其实是 Keras 3 版本更新后的一个常见问题。简单说,就是 Keras 3 的 load_model
函数不再支持某些旧的模型格式了。
问题来了: Keras 3 加载模型咋就报错了?
这个 ValueError
的核心信息很明确:你试图加载的文件格式,Keras 3 的 load_model
不认。它告诉你,Keras 3 只认两种格式:
- V3
.keras
文件: 这是 Keras 3 推荐的新格式,通常更现代、功能更全。 - 旧版 H5 格式 (
.h5
扩展名): 这是 Keras 以前常用的格式,Keras 3 为了兼容性,还继续支持。
错误信息还特意强调了一点:旧版的 TensorFlow SavedModel 格式,load_model
不再支持了 。
看到你的文件路径 C:\Users\fedmor\Desktop\AI\resnet50_coco_best_v2.0.1 (1)
,它没有 .keras
或 .h5
扩展名,并且路径看起来像个文件夹名(特别是那个 (1)
可能意味着重名)。这十有八九就是 TensorFlow SavedModel 格式——它通常是一个包含 saved_model.pb
文件和 variables
、assets
等子目录的文件夹。
刨根问底:为什么 Keras 3 不认这个文件?
Keras 3 在设计上做了一些调整,目标是提供一个更统一、更简洁的 API,并更好地整合跨后端(TensorFlow, PyTorch, JAX)的能力。在这个过程中,开发团队决定简化模型加载机制:
- 主推
.keras
格式: 这是 Keras 3 的原生格式,设计上考虑了跨后端兼容性和更好的序列化能力。 - 保留
.h5
兼容: 因为.h5
格式过去非常流行,完全抛弃会带来很大麻烦,所以保留了支持。 - 移除 SavedModel 支持 (在
load_model
中): TensorFlow 的 SavedModel 格式与 TensorFlow 运行时紧密耦合,包含了很多 TensorFlow 特有的信息。直接在 Keras 3 的通用load_model
里支持它,会增加复杂性,也可能与跨后端的理念不太契合。官方认为,如果你需要加载 SavedModel,应该使用更特定的方式。
所以,当你拿着一个 SavedModel 文件夹(或者指向这个文件夹的路径)去调用 Keras 3 的 load_model
时,它就会直接告诉你:“兄弟,这格式我不熟,不支持!”
解决方案:让模型顺利加载
别担心,有几种方法可以解决这个问题。咱们一个一个来看。
方案一:确认文件格式与扩展名 (最常见!)
有时候问题可能很简单,就是文件本身搞错了,或者扩展名不对。
原理和作用:
keras.models.load_model
函数通过文件路径或者文件内容来判断格式。如果路径指向的确实是一个 .h5
文件或者 .keras
文件,但你没有给对扩展名,或者路径给错了,它就懵了。如果路径指向的是一个 SavedModel 文件夹,它也会报错(正如我们遇到的情况)。
操作步骤:
-
检查文件/文件夹: 去你的路径
C:\Users\fedmor\Desktop\AI\
下看看,resnet50_coco_best_v2.0.1 (1)
到底是个啥?- 它是一个文件吗? 如果是,它有没有扩展名?如果是其他人给你的,问问原始格式是啥?如果它本身就是 HDF5 文件(
.h5
)或 Keras V3 文件(.keras
),尝试给它加上正确的扩展名再加载。 - 它是一个文件夹吗? 打开看看,里面是不是有
saved_model.pb
文件和variables
目录?如果是,那它就是 TensorFlow SavedModel 格式。你需要用下面的其他方法来处理。
- 它是一个文件吗? 如果是,它有没有扩展名?如果是其他人给你的,问问原始格式是啥?如果它本身就是 HDF5 文件(
-
尝试加载(如果确认是
.h5
或.keras
):import keras # 假设你确认它是 H5 文件,并已重命名或路径正确 try: model_path_h5 = 'C:/Users/fedmor/Desktop/AI/your_model.h5' # 替换成你的正确路径 model = keras.models.load_model(model_path_h5) print("成功加载 H5 模型!") # 之后就可以用 model.predict() 等方法了 except Exception as e: print(f"加载 H5 模型失败: {e}") # 假设你确认它是 Keras V3 文件,并已重命名或路径正确 try: model_path_keras = 'C:/Users/fedmor/Desktop/AI/your_model.keras' # 替换成你的正确路径 model = keras.models.load_model(model_path_keras) print("成功加载 .keras 模型!") # 之后就可以用 model.predict() 等方法了 except Exception as e: print(f"加载 .keras 模型失败: {e}")
安全建议:
从不可信来源获取模型文件时要小心。.h5
和 .keras
文件理论上可以包含恶意代码(虽然不常见)。尽量从官方或可信赖的渠道下载模型。
方案二:加载 TensorFlow SavedModel (推荐用于推理)
错误信息里其实已经给出了提示,如果你只是想把这个 TensorFlow SavedModel 当作一个只进行推理(inference-only)的层来用,可以使用 keras.layers.TFSMLayer
。
原理和作用:
TFSMLayer
是 Keras 3 提供的一个特殊层,它可以封装一个 TensorFlow SavedModel。它会加载 SavedModel 的计算图和权重,并将其包装成一个 Keras Layer 对象。这样,你就可以在 Keras 模型中像使用普通层一样使用这个加载进来的 SavedModel 了,但通常只适用于推理。它绕过了 load_model
的限制,专门处理 SavedModel。
操作步骤:
-
确定 SavedModel 路径: 确认你的路径
C:\Users\fedmor\Desktop\AI\resnet50_coco_best_v2.0.1 (1)
就是 SavedModel 文件夹的路径。 -
找到
call_endpoint
(或者叫 Signature): SavedModel 可以有多个入口点(signatures),用于不同的任务(比如serving_default
通常用于推理)。你需要指定用哪个入口点。- 常用默认值:
serving_default
是最常见的。你可以先试试这个。 - 查找方法: 如果
serving_default
不行,或者你想看看有哪些可用的,可以用 TensorFlow 提供的saved_model_cli
工具。在你的命令行(确保 TensorFlow 环境已激活)运行:
这个命令会列出 SavedModel 的详细信息,包括所有的 signatures (比如# 注意路径要换成你自己的 saved_model_cli show --dir "C:\Users\fedmor\Desktop\AI\resnet50_coco_best_v2.0.1 (1)" --all
signature_def['serving_default']
,signature_def['__saved_model_init_op']
等)。你需要找那个用于调用的 signature,通常名字里会带serving
或者predict
之类的。
- 常用默认值:
-
在 Keras 中使用
TFSMLayer
:import keras import tensorflow as tf # TFSMLayer 是和 TensorFlow 绑定的 saved_model_path = r'C:\Users\fedmor\Desktop\AI\resnet50_coco_best_v2.0.1 (1)' # 先尝试用默认的 'serving_default' call_endpoint = 'serving_default' try: # 将 SavedModel 加载为一个 Keras 层 tf_sm_layer = keras.layers.TFSMLayer(saved_model_path, call_endpoint=call_endpoint) # 你可以像使用普通 Keras 层一样使用它 # 假设模型输入是一个 (None, 224, 224, 3) 的张量 # 注意:输入形状需要和你加载的 SavedModel 的输入要求一致 input_shape = (224, 224, 3) # 根据你的模型修改 dummy_input = tf.random.normal((1,) + input_shape) # 创建一个假的输入 # 调用这个层进行推理 output = tf_sm_layer(dummy_input) print("成功加载 SavedModel 并通过 TFSMLayer 调用!") print("输出形状:", output.shape) # 如果需要,你可以把这个层嵌入到一个新的 Keras 模型中 # inputs = keras.Input(shape=input_shape) # outputs = tf_sm_layer(inputs) # inference_model = keras.Model(inputs, outputs) # inference_model.summary() except Exception as e: print(f"使用 TFSMLayer 加载 SavedModel 失败: {e}") print("可能的原因:路径错误、'call_endpoint' 名称不对、或者模型本身有问题。") print("尝试使用 'saved_model_cli show --dir <你的路径> --all' 查找正确的 endpoint。")
进阶使用技巧:
- 指定输入输出:
TFSMLayer
通常会自动推断输入输出,但如果 SavedModel 有多个输入或输出,或者你想更精确地控制,查阅TFSMLayer
的文档了解如何指定。 - 性能考量: 加载 SavedModel 可能比加载
.keras
或.h5
文件慢一些。TFSMLayer
主要设计用于推理,不适合用来继续训练。
安全建议:
同样,确保 SavedModel 文件夹来源可靠。
方案三:转换模型格式 (一劳永逸?)
如果你需要在 Keras 3 环境下对模型做更多操作(比如微调训练,或者想统一模型管理格式),可以考虑将这个 SavedModel 转换成 Keras 3 支持的 .keras
格式。
原理和作用:
找一个能够读取旧版 SavedModel 格式的环境(比如安装了较旧版本 TensorFlow 或 Keras 2 的环境),用那个环境的 load_model
功能把模型加载到内存中,然后再用 Keras 的 model.save()
方法,并明确指定 save_format='keras'
或文件名以 .keras
结尾,将其保存为新的 V3 格式。
操作步骤:
-
准备环境: 你可能需要一个还能识别 SavedModel 的 TensorFlow/Keras 环境。这可能是你原来的开发环境,或者你可以创建一个新的虚拟环境并安装 TensorFlow 2.x 的某个版本(比如
pip install tensorflow==2.10
)。
注意:Keras 3 本身理论上是应该能调用 TensorFlow 后端来处理的,但既然load_model
直接拒绝了 SavedModel,最稳妥的方式是先用 TensorFlow 自己的加载器。 -
加载 SavedModel 并另存为
.keras
:import tensorflow as tf # 这里我们直接用 TensorFlow 的 API 来加载 saved_model_path = r'C:\Users\fedmor\Desktop\AI\resnet50_coco_best_v2.0.1 (1)' new_keras_model_path = r'C:\Users\fedmor\Desktop\AI\resnet50_coco_best_v2.0.1.keras' # 指定新文件名和 .keras 扩展名 try: # 使用 TensorFlow 的 load_model 加载 SavedModel # 这一步需要在能识别 SavedModel 的 TensorFlow 版本下运行 print(f"尝试使用 TensorFlow 加载 SavedModel 从: {saved_model_path}") model = tf.keras.models.load_model(saved_model_path) print("SavedModel 加载成功!") # 将加载的模型保存为 Keras V3 (.keras) 格式 print(f"尝试将模型保存为 .keras 格式到: {new_keras_model_path}") # Keras 3 推荐使用 .keras 扩展名,它会自动选用 V3 格式 model.save(new_keras_model_path) # 或者更明确地指定格式 (如果你的 Keras 版本较老,推荐显式指定) # model.save(new_keras_model_path, save_format='keras') print(f"模型成功转换为 .keras 格式并保存!") # 转换完成后,你就可以在 Keras 3 环境下使用新的 .keras 文件了 # import keras # loaded_keras_model = keras.models.load_model(new_keras_model_path) # print("在 Keras 3 环境下成功加载转换后的 .keras 文件!") except Exception as e: print(f"模型转换失败: {e}") print("请确保当前 TensorFlow/Keras 环境能够加载原始 SavedModel。") print("检查 SavedModel 文件是否完整或损坏。")
进阶使用技巧:
- 自定义对象: 如果原始 SavedModel 包含了自定义层、自定义损失函数或激活函数,转换时需要确保这些自定义对象的代码在加载和保存环境中都可用。可能需要在加载时提供
custom_objects
参数给tf.keras.models.load_model
。 - 检查转换结果: 转换后,最好用 Keras 3 加载新的
.keras
文件,并跑一些简单的预测,检查模型的结构 (model.summary()
) 和输出是否和预期一致。
安全建议:
- 转换过程本身风险不高,但需要确保执行转换的环境是干净的。
- 转换可能会丢失一些 TensorFlow 特定的优化信息,但在 Keras 框架内使用通常问题不大。
方案四:检查 Keras 和 TensorFlow 版本
虽然错误信息指明了格式问题,但有时环境中的库版本冲突也会导致奇怪的行为。确保你的 Keras 3 和 TensorFlow 版本是兼容的。
原理和作用:
Keras 3 的核心是跨后端,但它与特定后端(如 TensorFlow)的交互依然需要版本匹配。版本不兼容可能导致各种难以预料的错误。
操作步骤:
-
检查版本: 在你的 Python 环境中运行:
import keras import tensorflow as tf print("Keras 版本:", keras.__version__) print("TensorFlow 版本:", tf.__version__)
或者在命令行:
pip show keras tensorflow
-
查阅兼容性: 查看 Keras 官方文档,了解你使用的 Keras 3 版本推荐搭配哪个范围的 TensorFlow 版本。
-
更新或调整: 如果发现版本不匹配,根据需要升级或降级库版本。使用虚拟环境(如
venv
或conda
)是管理不同项目依赖的最佳实践。# 例如,升级 Keras 和 TensorFlow 到最新兼容版本 pip install --upgrade keras tensorflow
进阶使用技巧:
- 虚拟环境大法: 为每个项目创建独立的虚拟环境,可以彻底避免不同项目间的库版本冲突。这是 Python 开发的标准操作。
处理 Keras 3 的这个 ValueError: File format not supported
通常就是上面这几种思路。最可能的情况是,你手里拿的是一个 TensorFlow SavedModel 文件夹,而不是 .h5
或 .keras
文件。根据你的需求(仅仅是推理还是需要更多操作),选择方案二 (TFSMLayer
) 或方案三(格式转换)通常能解决问题。当然,别忘了基础检查(方案一和四)也可能是关键。