TensorFlow モデルの変換#
このページでは、TensorFlow 形式から OpenVINO IR 形式へのモデル変換を行う一般的な手順を説明します。手順は、モデルが TensorFlow v1.X で作成されたか TensorFlow v2.X で作成されたかにより異なります。
TensorFlow モデルは、Kaggle または Hugging Face から入手できます。
注
TensorFlow モデルは、最初に OpenVINO IR を準備しなくても、OpenVINO ランタイム API による openvino.Core.read_model
メソッドまたは openvino.Core.compile_model
メソッドによってロードできます。詳細については、推論の例を参照してください。モデルの読み込みレイテンシーが推論アプリケーションにとって重要である場合は、引き続き openvino.convert_model
を使用することを推奨します。
注
openvino.convert_model
はデフォルトでモデルの重みの共有を使用します。つまり、OpenVINO モデルは、元の重みが配置されているプログラムのメモリー内の同じ領域を共有するため、OpenVINO モデルの存続期間中は元のモデルを変更できません (Python オブジェクトの割り当てを解除できず、元のモデルファイルを削除できません)。TensorFlow モデルのモデル推論はモデルの変更につながる可能性があるため、OpenVINO モデルの有効期間中は元の TF モデルを推論しないでください。これが望ましくない場合は、openvino.convert_model
を呼び出すときに share_weights=False
を設定します。
注
ファイルから TensorFlow モデルを変換する以下の例では、tensorflow
モジュールが明示的にインポートされる場合を除き、システムに TensorFlow をインストールする必要はありません。
TensorFlow 2 モデルの変換#
TensorFlow 2.X は、次の 2 つのモデル形式をサポートしています: SavedModel と Keras H5 (または HDF5)。以下にそれぞれの変換方法を示します。
SavedModel 形式#
SavedModel 形式のモデルは、saved_model.pb
ファイルを含むディレクトリーと 2 つのサブフォルダーで構成されます: 内部の variables
と assets
。モデルを変換するには、ディレクトリーをモデル引数として変換を行います:
import openvino as ov
ov_model = ov.convert_model('path_to_saved_model_dir')
ovc path_to_saved_model_dir
Keras H5 形式#
HDF5 形式のモデルは、TensorFlow 2 を使用してモデルをロードし、SavedModel 形式にシリアル化します。以下に方法を示します:
import tensorflow as tf
model = tf.keras.models.load_model('model.h5')
tf.saved_model.save(model,'model')
カスタムレイヤーを含む Keras H5 モデルを SavedModel 形式に変換するには、特別な考慮事項があります。例えば、custom_layer.py
のカスタムレイヤー CustomLayer
を含むモデルは次のように変換されます:
import tensorflow as tf
from custom_layer import CustomLayer
model = tf.keras.models.load_model('model.h5', custom_objects={'CustomLayer': CustomLayer})
tf.saved_model.save(model,'model')
次に、SavedModel 形式については上記の手順に従います。
注
TensorFlow 2 モデルを TensorFlow 1 形式に再保存する回避策やトリックは使用しないでください。
TensorFlow 1 モデルの変換#
Frozen モデル形式の変換#
TensorFlow モデルを変換するには、入力モデル *.pb*
ファイルへのパスを引数として変換を行います:
import openvino as ov
ov_model = ov.convert_model('your_model_file.pb')
ovc your_model_file.pb
非 Frozen モデル形式の変換#
非 Frozen TensorFlow モデルを保存するには 3 つの方法があります。
SavedModel 形式。この場合、モデルは
.pb
ファイルを含む特別なディレクトリーとサブフォルダーで構成されます。variables
、assets
、およびassets.extra
。SavedModel ディレクトリーの詳細については、TensorFlow リポジトリーの README ファイルを参照してください。このような TensorFlow モデルを変換するには、他のモデル形式と同様に変換を実行し、ディレクトリーへのパスをモデル引数として渡します。
import openvino as ov
ov_model = ov.convert_model('path_to_saved_model_dir')
ovc path_to_saved_model_dir
Checkpoint。この場合、モデルは 2 つのファイルで構成されます:
inference_graph.pb
(またはinference_graph.pbtxt
) とcheckpoint_file.ckpt
。推論グラフファイルがない場合は、Python でのカスタムモデルのフリーズを参照してください。推論グラフを含むモデルを.pb
形式に変換するには、両方のファイルへのパスをovc
またはopenvino.convert_model
の引数として指定します:
import openvino as ov
ov_model = ov.convert_model(['path_to_inference_graph.pb', 'path_to_checkpoint_file.ckpt'])
ovc path_to_inference_graph.pb path_to_checkpoint_file.ckpt
.pbtxt
形式で推論グラフを持つモデルを変換するには、.pb
ファイルではなく .pbtxt
ファイルへのパスを指定してください。トランスフォーメーション API は、提供されたファイルの形式を自動的に検出します。このドキュメントのすべての例で ovc
または openvino.convert_model
を呼び出す際に、モデルファイル形式を明示的に指定する必要はありません。
MetaGraph。この場合、モデルは同じディレクトリーに保存された 3 つまたは 4 つのファイルで構成されます:
model_name.meta
、model_name.index
,model_name.data-00000-of-00001
(数値は異なる場合があります)、およびcheckpoint
(オプション)。このような TensorFlow モデルを変換するには、引数として.meta
ファイルへのパスを指定して変換を実行します:
import openvino as ov
ov_model = ov.convert_model('path_to_meta_graph.meta')
ovc path_to_meta_graph.meta
Python でカスタムモデルをフリーズ#
モデルが Python コードで定義されている場合、推論グラフファイルを作成する必要があります。通常、グラフはモデルのトレーニングが可能な形式で構築されます。つまり、トレーニング可能なすべてのパラメーターがグラフ内の変数として表されます。このようなグラフをモデル・トランスフォーメーション API で使用するには、openvino.convert_model
関数に渡す前に、まずグラフをフリーズする必要があります:
import tensorflow as tf
from tensorflow.python.framework import graph_io
frozen = tf.compat.v1.graph_util.convert_variables_to_constants(sess, sess.graph_def, ["name_of_the_output_node"])
import openvino as ov
ov_model = ov.convert_model(frozen)
説明:
sess
は、ネットワーク・トポロジーが定義されている TensorFlow セッション・オブジェクトのインスタンスです。["name_of_the_output_node"]
は、グラフ内の出力ノード名のリストです。フリーズされたグラフには、特定の出力ノードを計算するため直接的または間接的に使用される、元のsess.graph_def
のノードのみが含まれます。'name_of_the_output_node'
は、出力可能なノード名の例です。独自のグラフに基づいて名前を決定する必要があります。
Python API を使用したメモリーからの TensorFlow モデル#
モデル・トランスフォーメーション API は、TensorFlow/TensorFlow 2 モデルをメモリーから直接渡すことをサポートしています。
Trackable
。hub.load()
によって返されたオブジェクトは、convert_model()
を使用してov.Model
に変換できます。import tensorflow_hub as hub import openvino as ov model = hub.load("https://tfhub.dev/google/movenet/singlepose/lightning/4") ov_model = ov.convert_model(model)
tf.function
@tf.function( input_signature=[tf.TensorSpec(shape=[1, 2, 3], dtype=tf.float32), tf.TensorSpec(shape=[1, 2, 3], dtype=tf.float32)]) def func(x, y): return tf.nn.sigmoid(tf.nn.relu(x + y)) import openvino as ov ov_model = ov.convert_model(func)
tf.keras.Model
import openvino as ov model = tf.keras.applications.ResNet50(weights="imagenet") ov_model = ov.convert_model(model)
tf.keras.layers.Layer
。tf.keras.layers.Layer
から変換されたov.Model
には、元の入力名と出力名が含まれません。そのため、変換前にモデルをtf.keras.Model
に変換するか、TensorFlow Hub モデルにはhub.load()
を使用することを推奨します。import tensorflow_hub as hub import openvino as ov model = hub.KerasLayer("https://tfhub.dev/google/imagenet/mobilenet_v1_100_224/classification/5") ov_model = ov.convert_model(model)
tf.Module
。input
パラメーターで形状を設定する必要があります。import tensorflow as tf import openvino as ov class MyModule(tf.Module): def __init__(self, name=None): super().__init__(name=name) self.constant1 = tf.constant(5.0, name="var1") self.constant2 = tf.constant(1.0, name="var2") def __call__(self, x): return self.constant1 * x + self.constant2 model = MyModule(name="simple_module") ov_model = ov.convert_model(model, input=[-1])
注
モデルグラフで tf.Variable
ノードを使用する場合、openvino.convert_model
には既知のバグが報告されています。このようなモデルの変換結果は予測できません。tf.Variable
を含むモデルを TensorFlow SavedModel 形式で保存し、openvino.convert_model
でロードすることを推奨します。
tf.compat.v1.Graph
with tf.compat.v1.Session() as sess: inp1 = tf.compat.v1.placeholder(tf.float32, [100], 'Input1') inp2 = tf.compat.v1.placeholder(tf.float32, [100], 'Input2') output = tf.nn.relu(inp1 + inp2, name='Relu') tf.compat.v1.global_variables_initializer() model = sess.graph import openvino as ov ov_model = ov.convert_model(model)
tf.compat.v1.GraphDef
with tf.compat.v1.Session() as sess: inp1 = tf.compat.v1.placeholder(tf.float32, [100], 'Input1') inp2 = tf.compat.v1.placeholder(tf.float32, [100], 'Input2') output = tf.nn.relu(inp1 + inp2, name='Relu') tf.compat.v1.global_variables_initializer() model = sess.graph_def import openvino as ov ov_model = ov.convert_model(model)
tf.compat.v1.session
with tf.compat.v1.Session() as sess: inp1 = tf.compat.v1.placeholder(tf.float32, [100], 'Input1') inp2 = tf.compat.v1.placeholder(tf.float32, [100], 'Input2') output = tf.nn.relu(inp1 + inp2, name='Relu') tf.compat.v1.global_variables_initializer() import openvino as ov ov_model = ov.convert_model(sess)
tf.train.checkpoint
model = tf.keras.Model(...) checkpoint = tf.train.Checkpoint(model) save_path = checkpoint.save(save_directory) # ... checkpoint.restore(save_path) import openvino as ov ov_model = ov.convert_model(checkpoint)
サポートされる TensorFlow および TensorFlow 2 Keras レイヤー#
サポートされる標準レイヤーのリストについては、サポートされる操作を参照してください。
まとめ#
このセッションでは、次のことを学びました:
モデル・トランスフォーメーション API が TensorFlow モデルでどのように動作するか理解する基本情報。
サポートされる TensorFlow モデル。
TensorFlow モデルをフリーズする方法。