Hi,
model.export(os.path.join(MODEL_PATH, "model.onnx"), format="onnx", input_signature=[keras.InputSpec(shape=(None, 256, 256, 3), dtype="float32")])
Export a model to ONNX format but with a lot of error and warnings. Such as:
ERROR:tf2onnx.tfonnx:Tensorflow op [sequential_2_1/sequential_1_1/random_brightness_1_1/stateless_random_uniform/StatelessRandomUniformV2: StatelessRandomUniformV2] is not supported
ERROR:tf2onnx.tfonnx:Tensorflow op [sequential_2_1/sequential_1_1/random_contrast_1_1/stateless_random_uniform/StatelessRandomUniformV2: StatelessRandomUniformV2] is not supported
ERROR:tf2onnx.tfonnx:Tensorflow op [sequential_2_1/sequential_1_1/random_flip_1_1/stateless_random_uniform/StatelessRandomUniformV2: StatelessRandomUniformV2] is not supported
ERROR:tf2onnx.tfonnx:Tensorflow op [sequential_2_1/sequential_1_1/random_rotation_1_1/stateless_random_uniform/StatelessRandomUniformV2: StatelessRandomUniformV2] is not supported
ERROR:tf2onnx.tfonnx:Tensorflow op [sequential_2_1/sequential_1_1/random_rotation_1_1/ImageProjectiveTransformV3: ImageProjectiveTransformV3] is not supported
ERROR:tf2onnx.tfonnx:Tensorflow op [sequential_2_1/sequential_1_1/random_zoom_1_1/stateless_random_uniform_1/StatelessRandomUniformV2: StatelessRandomUniformV2] is not supported
ERROR:tf2onnx.tfonnx:Tensorflow op [sequential_2_1/sequential_1_1/random_zoom_1_1/stateless_random_uniform/StatelessRandomUniformV2: StatelessRandomUniformV2] is not supported
ERROR:tf2onnx.tfonnx:Tensorflow op [sequential_2_1/sequential_1_1/random_zoom_1_1/ImageProjectiveTransformV3: ImageProjectiveTransformV3] is not supported
ERROR:tf2onnx.tfonnx:Tensorflow op [sequential_2_1/sequential_1_1/random_translation_1_1/stateless_random_uniform_1/StatelessRandomUniformV2: StatelessRandomUniformV2] is not supported
ERROR:tf2onnx.tfonnx:Tensorflow op [sequential_2_1/sequential_1_1/random_translation_1_1/stateless_random_uniform/StatelessRandomUniformV2: StatelessRandomUniformV2] is not supported
ERROR:tf2onnx.tfonnx:Tensorflow op [sequential_2_1/sequential_1_1/random_translation_1_1/ImageProjectiveTransformV3: ImageProjectiveTransformV3] is not supported
ERROR:tf2onnx.tfonnx:Unsupported ops: Counter({'StatelessRandomUniformV2': 8, 'ImageProjectiveTransformV3': 3})
And then when I try to import it in ONNX runtime I get the following erros:
InvalidGraph: [ONNXRuntimeError] : 10 : INVALID_GRAPH : Load model from model.onnx failed:This is an invalid model. In Node,
("sequential_2_1/sequential_1_1/random_brightness_1_1/stateless_random_uniform/StatelessRandomUniformV2", StatelessRandomUniformV2, "", -1) :
("sequential_2_1/sequential_1_1/random_brightness_1_1/stateless_random_uniform/shape_Concat__88:0": tensor(int32),"ConstantFolding/sequential_2_1/sequential_1_1/random_brightness_1_1/stateless_random_uniform/StatelessRandomGetKeyCounter-folded-0:0":
tensor(uint64),"ConstantFolding/sequential_2_1/sequential_1_1/random_brightness_1_1/stateless_random_uniform/StatelessRandomGetKeyCounter-folded-1:0":
tensor(uint64),"sequential_2_1/sequential_1_1/random_translation_1_1/stateless_random_uniform_1/StatelessRandomUniformV2/alg:0": tensor(int32),) ->
("sequential_2_1/sequential_1_1/random_brightness_1_1/stateless_random_uniform/StatelessRandomUniformV2:0",) , Error No Op registered for StatelessRandomUniformV2 with domain_version of 15
My model code is something like
data_augmentation = keras.Sequential([
keras.layers.RandomBrightness(factor=0.2, input_shape=(None, None, 3)),
keras.layers.RandomContrast(factor=0.2),
keras.layers.RandomFlip("horizontal_and_vertical"),
keras.layers.RandomRotation(0.3, fill_mode="constant"),
keras.layers.RandomZoom(.2, .2, fill_mode="constant"),
keras.layers.RandomTranslation(0.2, .2, fill_mode="constant"),
keras.layers.Resizing(256, 256, interpolation="bilinear", crop_to_aspect_ratio=True),
keras.layers.Rescaling(scale=1. / 127.5, offset=-1), # For [-1, 1] scaling
])
# My ResNet50V2
model = keras.models.Sequential()
model.add(data_augmentation)
model.add(
ResNet50V2(
include_top=False,
input_shape=(256, 256, 3),
pooling="avg",
)
)
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(len(config.SUB_FOLDERS), activation='softmax'))
model.summary()
model.compile(
optimizer=keras.optimizers.Adam(learning_rate=config.MAX_LR),
loss=keras.losses.SparseCategoricalCrossentropy(from_logits=False),
metrics=[config.METRIC]
)
My environement informations: - MacOS
[[package]]
name = "tensorflow"
version = "2.19.0"
[[package]]
name = "tensorflow-metal"
version = "1.2.0"
[[package]]
name = "keras"
version = "3.10.0"
[[package]]
name = "numpy"
version = "2.1.3"
[[package]]
name = "tf2onnx"
version = "1.16.1"
[[package]]
name = "onnx"
version = "1.17.0"
Comment From: lambda-science
Update: I removed the data augmentation layers so it works but I get widly different results between the model in ONNX version or Keras version.
import keras
import numpy as np
import datasets
import onnxruntime as ort
import tensorflow as tf
model = keras.models.load_model("model.keras")
# Load image from HuggingFace
ds = datasets.load_dataset("corentinm7/MyoQuant-SDH-Data")
# Load ONNX model
session = ort.InferenceSession("model.onnx")
input_name = session.get_inputs()[0].name
# TensorFlow SavedModel inference
saved_model = tf.saved_model.load("tf_saved_format")
infer = saved_model.signatures["serving_default"] # Default inference signature
image = ds["test"][3]["image"]
image_batch = np.expand_dims(np.array(image, dtype="float32"), axis=0)
# Shape: (1, H, W, 3)# PIL image
# Inference
outputs = session.run(None, {input_name: image_batch})
# Get softmax output
probs = outputs[0][0] # shape: (2,)
# Predicted class index
predicted_class = np.argmax(probs)
# Confidence score
confidence = probs[predicted_class]
print(f"ONNX Predicted class: {predicted_class}, confidence: {confidence:.2f}")
test_proba = model.predict(image_batch)
test_classes = test_proba.argmax(axis=-1)
print(f"KERAS Predicted class: {test_classes}, confidence: {max(test_proba)}")
# Convert numpy to tf.Tensor
image_tensor = tf.convert_to_tensor(image_batch, dtype=tf.float32)
tf_output = infer(image_tensor)
# Get output tensor name (usually only one output)
output_tensor = list(tf_output.values())[0].numpy()[0]
tf_pred = np.argmax(output_tensor)
tf_conf = output_tensor[tf_pred]
print(f"TF SavedModel Predicted class: {tf_pred}, confidence: {tf_conf:.2f}")
ONNX Predicted class: 0, confidence: 0.69
1/1 ━━━━━━━━━━━━━━━━━━━━ 2s 2s/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 2s 2s/step
KERAS Predicted class: [1], confidence: [0.002476 0.99752396]
TF SavedModel Predicted class: 0, confidence: 0.72
Keras prediction is right. ONNX and TF SavedModel are wrong.
Comment From: sonali-kumari1
Hi @lambda-science -
I have tested your code in this gist file with the latest version of keras(3.10.0). I encountered several warnings and errors during onnx
export. It appears that tf2onnx
does not fully support some data augmentation layers, specifically having issues with StatelessRandomUniformV2
and ImageProjectiveTransformV3
. These operations are internally used by layers like RandomBrightness
, RandomContrast
, RandomFlip
, RandomRotation
, RandomZoom
and RandomTranslation
. You can find a list of supported TensorFlow ops and their mapping to onnx here.
Additionally, I have also tested your code with model.keras
without onnx
conversion here and it seems to works fine. This indicates that the issue is specifically related to tf2onnx. Thanks!