Keras 到 Core ML 模型的转换,自定义层 - 转换功能被忽略



我正在尝试将一个通过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')

最新更新