如何将imagenet/mobilenet_v2_130_224/classification转为MLModel?求解报错
TensorFlow Hub模型转CoreML报错及解决方法
问题描述
我是该领域新手,正尝试解决模型转换问题。以下是我的convert.py文件:
import numpy as n import tensorflow as tf import coremltools as ct print(n.__version__) print(tf.__version__) print(ct.__version__) loaded_model = tf.saved_model.load("mobilenet_v2_130_224.h5") mlmodel = ct.convert(loaded_model, inputs=[ct.ImageType()], classifier_config=ct.ClassifierConfig("labels.txt"), source='tensorflow') mlmodel.short_description = "My Classifier" mlmodel.license = "Apache 2.0" spec = mlmodel.get_spec() ct.utils.rename_feature(spec, "input_1", "imageInput") ct.utils.rename_feature(spec, "Identity", "classResult") mlmodel = ct.models.MLModel(spec) print(mlmodel) mlmodel.save("model_299x299.mlmodel")
我下载了Mobilenet V2 130_224分类模型并解压到桌面,设备为M1 iMac。运行脚本时出现如下错误:
Traceback (most recent call last): File "/Users/asduskun/Desktop/convert.py", line 20, in <module> mlmodel = ct.convert(loaded_model, inputs=[ct.ImageType()], classifier_config=ct.ClassifierConfig("labels.txt"), source='tensorflow') File "/Users/asduskun/miniconda3/lib/python3.10/site-packages/coremltools/converters/_converters_entry.py", line 444, in convert mlmodel = mil_convert( File "/Users/asduskun/miniconda3/lib/python3.10/site-packages/coremltools/converters/mil/converter.py", line 187, in mil_convert return _mil_convert(model, convert_from, convert_to, ConverterRegistry, MLModel, compute_units, **kwargs) File "/Users/asduskun/miniconda3/lib/python3.10/site-packages/coremltools/converters/mil/converter.py", line 211, in _mil_convert proto, mil_program = mil_convert_to_proto( File "/Users/asduskun/miniconda3/lib/python3.10/site-packages/coremltools/converters/mil/converter.py", line 281, in mil_convert_to_proto prog = frontend_converter(model, **kwargs) File "/Users/asduskun/miniconda3/lib/python3.10/site-packages/coremltools/converters/mil/converter.py", line 99, in __call__ return tf2_loader.load() File "/Users/asduskun/miniconda3/lib/python3.10/site-packages/coremltools/converters/mil/frontend/tensorflow/load.py", line 61, in load self._graph_def = self._graph_def_from_model(output_names) File "/Users/asduskun/miniconda3/lib/python3.10/site-packages/coremltools/converters/mil/frontend/tensorflow2/load.py", line 133, in _graph_def_from_model cfs, graph_def = self._get_concrete_functions_and_graph_def() File "/Users/asduskun/miniconda3/lib/python3.10/site-packages/coremltools/converters/mil/frontend/tensorflow2/load.py", line 125, in _get_concrete_functions_and_graph_def raise NotImplementedError(msg.format(self.model)) NotImplementedError: Expected model format: [SavedModel | [concrete_function] | tf.keras.Model | .h5 | GraphDef], got <tensorflow.python.saved_model.load.Loader._recreate_base_user_object.<locals>._UserObject object at 0x1676455a0>
想知道:
- 为何会出现该错误?
- 如何将此特定模型转为MLModel?
- 若我的转换脚本写法有误,正确规范的写法是什么?
错误原因
- 模型加载方式与格式不匹配:
tf.saved_model.load()是用来加载TensorFlow SavedModel格式(文件夹形式)的工具,但你却用它加载.h5后缀的文件;而.h5属于Keras单文件模型,应该用tf.keras.models.load_model()加载。 - 模型实际格式误解:从TensorFlow Hub下载的模型解压后是SavedModel格式的文件夹,不是
.h5文件,你误将文件夹当成.h5文件加载,导致生成的对象无法被CoreMLTools识别。
解决方法与正确脚本
针对TensorFlow Hub的SavedModel格式模型,正确转换步骤如下:
修正后的完整脚本
import numpy as np import tensorflow as tf import coremltools as ct # 打印版本信息用于排查问题 print(np.__version__) print(tf.__version__) print(ct.__version__) # 指向解压后的SavedModel文件夹路径 model_path = "./mobilenet_v2_130_224_classification_5" # 定义输入图像规格:匹配模型要求的224x224尺寸,同时设置归一化参数 input_image = ct.ImageType(shape=(1, 224, 224, 3), bias=[-1,-1,-1], scale=1/127.5) # 转换模型 mlmodel = ct.convert( model_path, inputs=[input_image], classifier_config=ct.ClassifierConfig("labels.txt"), source="tensorflow" ) # 设置模型元数据 mlmodel.short_description = "Mobilenet V2 130_224 Image Classifier" mlmodel.license = "Apache 2.0" # 重命名输入输出特征(TF Hub模型默认名称需调整) spec = mlmodel.get_spec() ct.utils.rename_feature(spec, "serving_default_input_1:0", "imageInput") ct.utils.rename_feature(spec, "StatefulPartitionedCall:0", "classResult") # 重新生成MLModel对象 mlmodel = ct.models.MLModel(spec) # 查看模型信息并保存 print(mlmodel) mlmodel.save("mobilenet_v2_130_224.mlmodel")
关键修正点说明
- 模型路径正确设置:确保传入的是SavedModel文件夹的路径,而非
.h5文件。 - 输入规格匹配:模型要求输入尺寸为224x224,需在
ct.ImageType中明确指定;同时设置scale和bias参数,匹配TF Hub模型的图像预处理要求。 - 特征名称修正:TF Hub的SavedModel默认输入输出名称为
serving_default_input_1:0和StatefulPartitionedCall:0,需根据实际情况重命名(可通过打印加载后的模型签名确认名称)。 - 直接传入路径转换:CoreMLTools支持直接传入SavedModel文件夹路径,无需提前用
tf.saved_model.load()加载,避免格式识别问题。
额外注意事项
- 确保
labels.txt与脚本在同一目录下,文件每行对应一个类别名称,顺序需与模型输出的类别索引一致。 - M1设备上运行时,建议使用TensorFlow >=2.8、CoreMLTools >=6.0的版本,保证兼容性。
内容的提问来源于stack exchange,提问作者asduskun
相关产品推荐
相关产品推荐

