keras 和 tf.keras 模型之间的兼容性
Compatibility between keras and tf.keras models
我有兴趣在 tf.keras 中训练一个模型,然后用 keras 加载它。我知道这不是强烈建议,但我有兴趣使用 tf.keras 来训练模型,因为
- tf.keras更容易构建输入管道
- 我想利用 tf.dataset API
我有兴趣用 keras 加载它,因为
- 我想使用 coreml 将模型部署到 ios。
- 我想使用 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。
我有兴趣在 tf.keras 中训练一个模型,然后用 keras 加载它。我知道这不是强烈建议,但我有兴趣使用 tf.keras 来训练模型,因为
- tf.keras更容易构建输入管道
- 我想利用 tf.dataset API
我有兴趣用 keras 加载它,因为
- 我想使用 coreml 将模型部署到 ios。
- 我想使用 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。