首页 > 解决方案 > 使用自定义层转换 Keras 到 Core ML 模型 - 忽略转换功能

问题描述

我正在尝试将通过 Keras 训练的模型(以 TensorFlow 1.x 作为后端)转换为 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}
                                              )

但是,在尝试运行转换时,我仍然收到与上述相同的“未知层”错误。什么可能导致转换脚本无法识别我提供的转换功能?

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

标签: kerascoremlcoremltools

解决方案


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

推荐阅读