我正在尝试将一个通过Keras训练的模型转换为Core ML格式(.mlmodel
(。我有模型的完整来源和权重,以及冻结的 Keras 图(.h5
文件(。我的模型(请参阅此处的体系结构(是使用 Keras 函数 API 定义的,并且有一个名为AttentionWeightedAverage
的自定义层。
运行以下转换代码时,我收到一个ValueError: Unknown layer: AttentionWeightedAverage
。
import coremltools
mlmodel = coremltools.converters.keras.convert('deepmoji_model.h5')
当然,由于这是一个自定义层(它也恰好有一个叫做return_attention
的布尔超参数(,我明白我需要告诉Core ML如何处理它,所以我根据Matthijs Hollemans的精彩博客文章实现了以下内容:
class AttentionWeightedAverage(Layer):
# class defined inline here ...
# https://github.com/bfelbo/DeepMoji/blob/master/deepmoji/attlayer.py
def convert_ATTN(layer):
params = NeuralNetwork_pb2.CustomLayerParams()
params.className = "AttentionWeightedAverage"
params.description = "A fancy new activation function"
params.parameters["return_attention"].boolValue = layer.return_attention
return params
mlmodel = coremltools.converters.keras.convert('deepmoji_model.h5',
add_custom_layers=True,
custom_conversion_functions={"AttentionWeightedAverage": convert_ATTN}
)
但是,在尝试运行转换时,我仍然收到与上述相同的"未知层"错误。什么可能导致转换脚本无法识别我提供的转换功能?
我正在使用keras == 2.3.1
运行coremltools == 3.3
(最新(。任何指导都非常感谢!
事实证明,Unknown layer
错误源于 Keras 本身,由于无法反序列化自定义层,因此无法成功load_model
。相反,如果我们将完全反序列化的模型(而不仅仅是文件路径(传递给转换器,则转换器运行不会有问题。
model = load_model('deepmoji_model.h5', custom_objects={'AttentionWeightedAverage': AttentionWeightedAverage()})
mlmodel = coremltools.converters.keras.convert(model,
add_custom_layers=True,
custom_conversion_functions={"AttentionWeightedAverage": convert_ATTN}
)
mlmodel.save('deepmoji_model.mlmodel')