首页 > 解决方案 > 无法通过任何方式将 .h5 模型转换为 ONNX 进行推理

问题描述

我从Matterport 的 MaskRCNN implementation在 .h5 中构建了一个自定义模型。我设法保存了完整的模型,而不是单独使用权重model.keras_model.save(),并假设它工作正常。

我需要将此模型转换为 ONNX 以在 Unity Barracuda 中进行推理,并且在此过程中我遇到了几个错误。我试过了:

T1。.h5 到 ONNX 使用本教程和 keras2onnx 包,我在以下位置遇到错误:

model = load_model('model.h5')

Error:
ValueError: Unknown layer: BatchNorm

T2。使用此 GitHub 代码定义自定义层:

 model = keras.models.load_model(r'model.h5', custom_objects={'BatchNorm':BatchNorm, 
'tf':tf, 'ProposalLayer':ProposalLayer, 
'PyramidROIAlign1':PyramidROIAlign1, 'PyramidROIAlign2':PyramidROIAlign2,
'DetectionLayer':DetectionLayer}, compile=False)

Error:
ValueError: No model found in config file.
ValueError: Unknown layer: PyramidROIAlign

T3。.h5 到 .pb(冻结图)和 .pbtxt,然后在找到输入和输出节点后使用 tf2onnx 从 .pb 到 ONNX(似乎每个节点只有一个?):

assert d in name_to_node, "%s is not in graph" % d
AssertionError: output0 is not in graph

T4。.h5 使用 tf-serving 代码从此处转换为 SavedModel ,然后python -m tf2onnx.convert --saved-model exported_models\coco_mrcnn\3 --opset 15 --output "model.onnx"转换为 ONNX:

ValueError: make_sure failure: variable mrcnn_detection/map/while/Enter already exists as state variable.

TLDR:有没有办法通过任何直接/间接方式将我的 .h5 模型转换为 ONNX?我已经坚持了好几天了!

提前致谢。

编辑1:似乎keras.models.load_model()引发了前两个错误-想知道是否有一种方法可以使用 .pb/.pbtxt 模型,或者不使用load_model()的方法,或者解决load_model()问题的方法?

编辑2:

T1 的代码:从Matterport 的 MaskRCNN 实现修改的自定义数据集

T4 代码

标签: tensorflowkeraskeras-layertensorflow-servingonnx

解决方案


尝试将其转换为保存的模型格式,然后再转换为 onnx。

import numpy as np
import tensorflow as tf
from tensorflow import keras


def get_model():
    # Create a simple model.
    inputs = keras.Input(shape=(32,))
    outputs = keras.layers.Dense(1)(inputs)
    model = keras.Model(inputs, outputs)
    model.compile(optimizer="adam", loss="mean_squared_error")
    return model

model = get_model()
# Train the model.
test_input = np.random.random((128, 32))
test_target = np.random.random((128, 1))
model.fit(test_input, test_target)

# Calling `save('my_model.h5')` creates a h5 file `my_model.h5`.
model.save("my_h5_model.h5")

# It can be used to reconstruct the model identically.
model = keras.models.load_model("my_h5_model.h5")
tf.saved_model.save(model, "tmp_model")

然后使用 tf2onnx 进行转换。

python3 -m tf2onnx.convert --saved-model tmp_model --output "model.onnx"

推荐阅读