keras 和 tf.keras 模型之间的兼容性

Compatibility between keras and tf.keras models

我有兴趣在 tf.keras 中训练一个模型,然后用 keras 加载它。我知道这不是强烈建议,但我有兴趣使用 tf.keras 来训练模型,因为

  1. tf.keras更容易构建输入管道
  2. 我想利用 tf.dataset API

我有兴趣用 keras 加载它,因为

  1. 我想使用 coreml 将模型部署到 ios。
  2. 我想使用 coremltools 将我的模型转换为 ios,而 coreml 工具仅适用于 keras,不适用于 tf.keras。

我 运行 进入了几个路障,因为并非所有 tf.keras 层都可以作为 keras 层加载。例如,我在使用简单的 DNN 时没有遇到任何问题,因为 tf.keras 和 keras 之间的所有密集层参数都是相同的。但是,我在使用 RNN 层时遇到了麻烦,因为 tf.keras 有一个参数 time_major 而 keras 没有。我的 RNN 层有 time_major=False,这与 keras 的行为相同,但 keras 顺序层没有此参数。

我现在的解决方案是将tf.keras模型保存在json文件中(用于模型结构)并删除keras不支持的部分图层,并保存一个h5 文件(用于权重),如下所示:

model = # model trained with tf.keras

# save json
model_json = model.to_json()
with open('path_to_model_json.json', 'w') as json_file:
    json_ = json.loads(model_json)
    layers = json_['config']['layers']
    for layer in layers:
        if layer['class_name'] == 'SimpleRNN':
            del layer['config']['time_major']
    json.dump(json_, json_file)

# save weights
model.save_weights('path_to_my_weights.h5')

然后,我使用 coremlconverter 工具将 keras 转换为 coreml,如下所示:

with CustomObjectScope({'GlorotUniform': glorot_uniform()}):
    coreml_model = coremltools.converters.keras.convert(
        model=('path_to_model_json','path_to_my_weights.h5'),
        input_names=#inputs, 
        output_names=#outputs,
        class_labels = #labels, 
        custom_conversion_functions = { "GlorotUniform": tf.keras.initializers.glorot_uniform
                                            }
    )
    coreml_model.save('my_core_ml_model.mlmodel')

我的解决方案似乎有效,但我想知道是否有更好的方法?或者,这种做法是否存在迫在眉睫的危险?例如,是否有更好的方法将 tf.keras 模型转换为 coreml?还是有更好的方法将 tf.keras 模型转换为 keras?或者有没有我没有想到的更好的方法?

如有任何建议,我们将不胜感激:)

我觉得你的方法不错!

过去,当我不得不将 tf.keras 模型转换为 keras 模型时,我做了以下操作:

  • 训练模型 tf.keras
  • 只保存权重tf_model.save_weights("tf_model.hdf5")
  • 使用 keras 中的所有层制作 Keras 模型架构(与 tf keras 一样)
  • 在 keras 中按图层名称加载权重:keras_model.load_weights(by_name=True)

这似乎对我有用。因为,我使用的是开箱即​​用的架构 (DenseNet169),所以我只需很少的工作就可以将 tf.keras 网络复制到 keras。