Keras 到带有自定义层的 Core ML 模型转换 - 转换函数被忽略

Keras to Core ML model conversion with custom layer - conversion function ignored

我正在尝试将以 TensorFlow 1.x 作为后端通过 Keras 训练的模型转换为 Core ML 格式 (.mlmodel)。我有模型的完整源代码和权重,以及冻结的 Keras 图(.h5 文件)。 My model (see architecture here) 是使用 Keras 函数 API 定义的,并且有一个名为 AttentionWeightedAverage.

的自定义层

当运行使用以下转换代码时,我收到一个ValueError: Unknown layer: AttentionWeightedAverage.

import coremltools
mlmodel = coremltools.converters.keras.convert('deepmoji_model.h5')

自然地,因为这是一个自定义层(它也恰好有一个名为 return_attention 的布尔超参数),我知道我需要告诉 Core ML 如何处理它,所以我实现了以下, 基于 Matthijs Hollemans' great blog post:

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}
                                              )

但是,在尝试 运行 转换时,我仍然收到与上述相同的 "Unknown Layer" 错误。是什么导致转换脚本无法识别我提供的转换函数?

我 运行宁 coremltools == 3.3(最新)与 keras == 2.3.1。非常感谢任何指导!

事实证明,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')