forked from openvinotoolkit/openvino
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[TF Hub API][TF FE] Support TF Keras Model OOB without example_input (o…
…penvinotoolkit#19892) * [TF Hub] Cover TF Hub use cases with adoption to OpenVINO This is necessarily to demonstrate support of models programmed with TF Hub API through OV notebooks. Signed-off-by: Kazantsev, Roman <[email protected]> * Preserve original keras input and output tensor names * Add tests with TF Hub API models * No KerasLayer handling * Handle specific signature --------- Signed-off-by: Kazantsev, Roman <[email protected]>
- Loading branch information
Showing
5 changed files
with
206 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
63 changes: 63 additions & 0 deletions
63
tests/model_hub_tests/tf_hub_tests/test_tf_hub_api_notebooks.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# Copyright (C) 2018-2023 Intel Corporation | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
import pytest | ||
import tensorflow as tf | ||
import tensorflow_hub as hub | ||
from models_hub_common.test_convert_model import TestConvertModel | ||
from tf_hub_tests.utils import get_input_info | ||
|
||
|
||
class TestTFHubApiNotebooks(TestConvertModel): | ||
def load_model(self, model_name, model_link): | ||
if model_name == 'mobilenet_v2_100_224_dict': | ||
image = tf.keras.layers.Input(shape=(224, 224, 3), dtype=tf.float32, name="image") | ||
feature_vector = hub.KerasLayer("https://tfhub.dev/google/imagenet/mobilenet_v2_100_224/feature_vector/5", | ||
trainable=False)(image) | ||
softmax = tf.keras.layers.Dense(20, activation='softmax')(feature_vector) | ||
classification_model = tf.keras.Model(inputs={'image': image}, outputs={'softmax': softmax}) | ||
return classification_model | ||
elif model_name == 'mobilenet_v2_100_224_list': | ||
image = tf.keras.layers.Input(shape=(224, 224, 3), dtype=tf.float32, name="image") | ||
feature_vector = hub.KerasLayer("https://tfhub.dev/google/imagenet/mobilenet_v2_100_224/feature_vector/5", | ||
trainable=False)(image) | ||
softmax = tf.keras.layers.Dense(20, activation='softmax')(feature_vector) | ||
classification_model = tf.keras.Model(inputs=[image], outputs=[softmax]) | ||
return classification_model | ||
else: | ||
raise "Unknown input model: {}".format(model_name) | ||
|
||
def get_inputs_info(self, keras_model): | ||
inputs_info = [] | ||
if isinstance(keras_model.input, dict): | ||
for input_name, input_tensor in keras_model.input.items(): | ||
inputs_info.append(get_input_info(input_tensor, input_name)) | ||
elif isinstance(keras_model.input, list): | ||
inputs_info.append('list') | ||
for input_tensor in keras_model.input: | ||
inputs_info.append(get_input_info(input_tensor, input_tensor.name)) | ||
else: | ||
inputs_info.append('list') | ||
input_tensor = keras_model.input | ||
inputs_info.append(get_input_info(input_tensor, input_tensor.name)) | ||
return inputs_info | ||
|
||
def infer_fw_model(self, model_obj, inputs): | ||
outputs = model_obj(inputs) | ||
if isinstance(outputs, dict): | ||
post_outputs = {} | ||
for out_name, out_value in outputs.items(): | ||
post_outputs[out_name] = out_value.numpy() | ||
elif isinstance(outputs, list): | ||
post_outputs = [] | ||
for out_value in outputs: | ||
post_outputs.append(out_value.numpy()) | ||
else: | ||
post_outputs = [outputs.numpy()] | ||
|
||
return post_outputs | ||
|
||
@pytest.mark.precommit | ||
@pytest.mark.parametrize("model_name", ['mobilenet_v2_100_224_dict', 'mobilenet_v2_100_224_list']) | ||
def test_tf_hub_api_notebook1(self, model_name, ie_device): | ||
self.run(model_name, '', ie_device) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Copyright (C) 2018-2023 Intel Corporation | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
import numpy as np | ||
import tensorflow as tf | ||
|
||
type_map = { | ||
tf.float64: np.float64, | ||
tf.float32: np.float32, | ||
tf.int8: np.int8, | ||
tf.int16: np.int16, | ||
tf.int32: np.int32, | ||
tf.int64: np.int64, | ||
tf.uint8: np.uint8, | ||
tf.uint16: np.uint16, | ||
tf.string: str, | ||
tf.bool: bool, | ||
} | ||
|
||
|
||
def get_input_info(input_tensor, input_name): | ||
input_shape = [] | ||
try: | ||
for dim in input_tensor.shape.as_list(): | ||
if dim is None: | ||
input_shape.append(1) | ||
else: | ||
input_shape.append(dim) | ||
except ValueError: | ||
# unknown rank case | ||
pass | ||
assert input_tensor.dtype in type_map, "Unsupported input type: {}".format(input_tensor.dtype) | ||
return input_name, input_shape, type_map[input_tensor.dtype] |