Convert a TensorFlow Model to OpenVINO™¶
This tutorial is also available as a Jupyter notebook that can be cloned directly from GitHub. See the installation guide for instructions to run this tutorial locally on Windows, Linux or macOS. To run without installing anything, click the launch binder button.
This short tutorial shows how to convert a TensorFlow MobileNetV3 image classification model to OpenVINO Intermediate Representation (OpenVINO IR) format, using Model Optimizer. After creating the OpenVINO IR, load the model in OpenVINO Runtime and do inference with a sample image.
Imports¶
import time
from pathlib import Path
import cv2
import matplotlib.pyplot as plt
import numpy as np
from IPython.display import Markdown
from openvino.runtime import Core
Settings¶
# The paths of the source and converted models.
model_path = Path("model/v3-small_224_1.0_float.pb")
ir_path = Path(model_path).with_suffix(".xml")
Convert a Model to OpenVINO IR Format¶
Convert a TensorFlow Model to OpenVINO IR Format¶
Use Model Optimizer to convert a TensorFlow model to OpenVINO IR with
FP16
precision. The models are saved to the current directory. Add
mean values to the model and scale the output with the standard
deviation with --scale_values
. With these options, it is not
necessary to normalize input data before propagating it through the
network. The original model expects input images in RGB
format. The
converted model also expects images in RGB
format. If you want the
converted model to work with BGR
images, use the
--reverse-input-channels
option. For more information about Model
Optimizer, including a description of the command-line options, see the
Model Optimizer Developer
Guide.
For information about the model, including input shape, expected color
order and mean values, refer to the model
documentation.
First construct the command for Model Optimizer, and then execute this
command in the notebook by prepending the command with an !
. There
may be some errors or warnings in the output. When model optimization is
successful, the last lines of the output will include
[ SUCCESS ] Generated IR version 11 model.
# Construct the command for Model Optimizer.
mo_command = f"""mo
--input_model "{model_path}"
--input_shape "[1,224,224,3]"
--mean_values="[127.5,127.5,127.5]"
--scale_values="[127.5]"
--data_type FP16
--output_dir "{model_path.parent}"
"""
mo_command = " ".join(mo_command.split())
print("Model Optimizer command to convert TensorFlow to OpenVINO:")
display(Markdown(f"`{mo_command}`"))
Model Optimizer command to convert TensorFlow to OpenVINO:
mo --input_model "model/v3-small_224_1.0_float.pb" --input_shape "[1,224,224,3]" --mean_values="[127.5,127.5,127.5]" --scale_values="[127.5]" --data_type FP16 --output_dir "model"
# Run Model Optimizer if the IR model file does not exist
if not ir_path.exists():
print("Exporting TensorFlow model to IR... This may take a few minutes.")
! $mo_command
else:
print(f"IR model {ir_path} already exists.")
Exporting TensorFlow model to IR... This may take a few minutes.
Model Optimizer arguments:
Common parameters:
- Path to the Input Model: /opt/home/k8sworker/cibuilds/ov-notebook/OVNotebookOps-275/.workspace/scm/ov-notebook/notebooks/101-tensorflow-to-openvino/model/v3-small_224_1.0_float.pb
- Path for generated IR: /opt/home/k8sworker/cibuilds/ov-notebook/OVNotebookOps-275/.workspace/scm/ov-notebook/notebooks/101-tensorflow-to-openvino/model
- IR output name: v3-small_224_1.0_float
- Log level: ERROR
- Batch: Not specified, inherited from the model
- Input layers: Not specified, inherited from the model
- Output layers: Not specified, inherited from the model
- Input shapes: [1,224,224,3]
- Source layout: Not specified
- Target layout: Not specified
- Layout: Not specified
- Mean values: [127.5,127.5,127.5]
- Scale values: [127.5]
- Scale factor: Not specified
- Precision of IR: FP16
- Enable fusing: True
- User transformations: Not specified
- Reverse input channels: False
- Enable IR generation for fixed input shape: False
- Use the transformations config file: None
Advanced parameters:
- Force the usage of legacy Frontend of Model Optimizer for model conversion into IR: False
- Force the usage of new Frontend of Model Optimizer for model conversion into IR: False
TensorFlow specific parameters:
- Input model in text protobuf format: False
- Path to model dump for TensorBoard: None
- List of shared libraries with TensorFlow custom layers implementation: None
- Update the configuration file with input/output node names: None
- Use configuration file used to generate the model with Object Detection API: None
- Use the config file: None
OpenVINO runtime found in: /opt/home/k8sworker/cibuilds/ov-notebook/OVNotebookOps-275/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages/openvino
OpenVINO runtime version: 2022.2.0-7713-af16ea1d79a-releases/2022/2
Model Optimizer version: 2022.2.0-7713-af16ea1d79a-releases/2022/2
/opt/home/k8sworker/cibuilds/ov-notebook/OVNotebookOps-275/.workspace/scm/ov-notebook/.venv/lib/python3.8/site-packages/numpy/lib/function_base.py:959: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
return array(a, order=order, subok=subok, copy=True)
[ SUCCESS ] Generated IR version 11 model.
[ SUCCESS ] XML file: /opt/home/k8sworker/cibuilds/ov-notebook/OVNotebookOps-275/.workspace/scm/ov-notebook/notebooks/101-tensorflow-to-openvino/model/v3-small_224_1.0_float.xml
[ SUCCESS ] BIN file: /opt/home/k8sworker/cibuilds/ov-notebook/OVNotebookOps-275/.workspace/scm/ov-notebook/notebooks/101-tensorflow-to-openvino/model/v3-small_224_1.0_float.bin
[ SUCCESS ] Total execution time: 11.02 seconds.
[ SUCCESS ] Memory consumed: 441 MB.
[ INFO ] The model was converted to IR v11, the latest model format that corresponds to the source DL framework input/output format. While IR v11 is backwards compatible with OpenVINO Inference Engine API v1.0, please use API v2.0 (as of 2022.1) to take advantage of the latest improvements in IR v11.
Find more information about API v2.0 and IR v11 at https://docs.openvino.ai
Test Inference on the Converted Model¶
Load the Model¶
ie = Core()
model = ie.read_model(model=ir_path, weights=ir_path.with_suffix(".bin"))
compiled_model = ie.compile_model(model=model, device_name="CPU")
Get Model Information¶
input_key = compiled_model.input(0)
output_key = compiled_model.output(0)
network_input_shape = input_key.shape
Load an Image¶
Load an image, resize it, and convert it to the input shape of the network.
# The MobileNet network expects images in RGB format.
image = cv2.cvtColor(cv2.imread(filename="data/coco.jpg"), code=cv2.COLOR_BGR2RGB)
# Resize the image to the network input shape.
resized_image = cv2.resize(src=image, dsize=(224, 224))
# Transpose the image to the network input shape.
input_image = np.expand_dims(resized_image, 0)
plt.imshow(image);

Do Inference¶
result = compiled_model([input_image])[output_key]
result_index = np.argmax(result)
# Convert the inference result to a class name.
imagenet_classes = open("utils/imagenet_2012.txt").read().splitlines()
# The model description states that for this model, class 0 is background.
# Therefore, add background at the beginning of imagenet_classes
imagenet_classes = ['background'] + imagenet_classes
imagenet_classes[result_index]
'n02099267 flat-coated retriever'
Timing¶
Measure the time it takes to do inference on thousand images. This gives an indication of performance. For more accurate benchmarking, use the Benchmark Tool in OpenVINO. Note that many optimizations are possible to improve the performance.
num_images = 1000
start = time.perf_counter()
for _ in range(num_images):
compiled_model([input_image])
end = time.perf_counter()
time_ir = end - start
print(
f"IR model in OpenVINO Runtime/CPU: {time_ir/num_images:.4f} "
f"seconds per image, FPS: {num_images/time_ir:.2f}"
)
IR model in OpenVINO Runtime/CPU: 0.0010 seconds per image, FPS: 1044.47