[従来] TensorFlow モデルから変換

危険

ここで説明されているコードは非推奨になりました。従来のソリューションの適用を避けるため使用しないでください。下位互換性を確保するためにしばらく保持されますが、最新のアプリケーションでは使用してはなりません

このガイドでは、非推奨となった変換方法について説明します。新しい推奨方法に関するガイドは、TensorFlow モデルから変換の記事に記載されています。

TensorFlow モデルはフロントエンド API 経由でサポートされます。IR への変換をスキップし、OpenVINO ランタイム API によってモデルを直接読み取ることもできます。詳細については、推論の例を参照してください。モデルのプルーニングにおける新しいカスタム入力/出力、前処理の追加、または Python 変換拡張機能など、より複雑な場合でも、convert_model の使用が必要になります。

変換手順は、モデルが TensorFlow v1.X で作成されたか TensorFlow v2.X で作成されたかにより異なります。

TensorFlow 1 モデルから変換

Frozen モデル形式から変換

TensorFlow モデルを変換するには、*mo* スクリプトを使用して、入力モデル .pb ファイルへのパスを持つモデルを単純に変換します。

mo --input_model <INPUT_MODEL>.pb

非 Frozen モデル形式から変換

非フリーズ TensorFlow モデルを保存し、モデル変換 API で変換するには 3 つの方法があります。

  1. Checkpoint。この場合、モデルは 2 つのファイルで構成されます: inference_graph.pb (または inference_graph.pbtxt) および checkpoint_file.ckpt。推論グラフファイルがない場合は、Python でのカスタムモデルのフリーズを参照してください。推論グラフを含むモデルを .pb 形式に変換するには、チェックポイント・ファイルへのパスを指定して mo スクリプトを実行します。

    mo --input_model <INFERENCE_GRAPH>.pb --input_checkpoint <INPUT_CHECKPOINT>
    

    推論グラフを含むモデルを .pbtxt 形式に変換するには、チェックポイント・ファイルへのパスを指定して mo スクリプトを実行します。

    mo --input_model <INFERENCE_GRAPH>.pbtxt --input_checkpoint <INPUT_CHECKPOINT> --input_model_is_text
    
  2. MetaGraph。この場合、モデルは同じディレクトリーに保存された 3 つまたは 4 つのファイルで構成されます: model_name.meta, model_name.indexmodel_name.data-00000-of-00001 (数値は異なる場合があります)、および checkpoint (オプション)。このような TensorFlow モデルを変換するには、MetaGraph .meta ファイルへのパスを指定して mo スクリプトを実行します。

    mo --input_meta_graph <INPUT_META_GRAPH>.meta
    
  3. SavedModel 形式。この場合、モデルは .pb ファイルを含む特別なディレクトリーとサブフォルダーで構成されます: variablesassets、および assets.extra。SavedModel ディレクトリーの詳細については、TensorFlow リポジトリーの README ファイルを参照してください。このような TensorFlow モデルを変換するには、SavedModel ディレクトリーへのパスを指定して mo スクリプトを実行します。

    mo --saved_model_dir <SAVED_MODEL_DIRECTORY>
    

TensorFlow 1.x または 2.x バージョンがある環境では、TensorFlow 1.x SavedModel 形式を変換できます。ただし、TensorFlow 2.x SavedModel 形式には、厳密な TensorFlow の 2.x バージョンが必要です。モデルに現在 OpenVINO でサポートされていない操作が含まれている場合、--input オプションを使用して入力ノードを明示的に指定することで、これらの操作をプルーニングします。カスタム入力ノードを決定するには、TensorBoard でモデルのグラフを表示します。グラフの TensorBoard ログを生成するには、--tensorboard_logs オプションを使用します。TensorFlow 2.x SavedModel 形式には、積極的な実行により特定のグラフが含まれます。プルーニングの場合、TensorFlow 2.x SavedModel 形式の StatefulPartitionedCall/* サブグラフでカスタム入力ノードを見つけます。

Python でのカスタムモデルのフリーズ

Python コードでネットワークを定義する場合は、推論グラフファイルを作成する必要があります。通常、グラフはモデルのトレーニングが可能な形式で構築されます。つまり、トレーニング可能なすべてのパラメーターがグラフ内の変数として表されます。このようなグラフをモデル変換 API で使用できるようにするには、次のコードを使用してグラフをフリーズし、ファイルにダンプする必要があります。

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"])
graph_io.write_graph(frozen, './', 'inference_graph.pb', as_text=False)

説明:

  • sess は、ネットワーク・トポロジーが定義されている TensorFlow セッション・オブジェクトのインスタンスです。

  • ["name_of_the_output_node"] は、グラフ内の出力ノード名のリストです。フリーズされたグラフには、特定の出力ノードを計算するため直接的または間接的に使用される、元の sess.graph_def のノードのみが含まれます。'name_of_the_output_node' は、出力可能なノード名の例です。独自のグラフに基づいて名前を決定する必要があります。

  • ./ は、推論グラフファイルが生成されるディレクトリーです。

  • inference_graph.pb は、生成された推論グラフファイルの名前です。

  • as_text は、生成されるファイルを人間が判読できるテキスト形式にするかバイナリーにするかを指定します。

TensorFlow 2 モデルから変換

TensorFlow 2 モデルを変換するには、openvino-dev[tensorflow2]pip 経由でインストールされていることを確認してください。TensorFlow 2.X は、次の 2 つのモデル形式をサポートしています: SavedModel と Keras H5 (または HDF5)。以下にそれぞれの変換方法を示します。

SavedModel 形式

SavedModel 形式のモデルは、saved_model.pb ファイルを含むディレクトリーと 2 つのサブフォルダーで構成されます: variablesassets。このようなモデルを変換するには、SavedModel ディレクトリーへのパスを指定して mo スクリプトを実行します。

mo --saved_model_dir <SAVED_MODEL_DIRECTORY>

TensorFlow 2 SavedModel 形式では、中間表現 (IR) に変換するため環境に TensorFlow の 2.x バージョンがインストールされていることが必須です。

モデルに現在 OpenVINO™ でサポートされていない操作が含まれている場合、--input または --output オプションを使用して入力ノードを明示的に指定することで、これらの操作をプルーニングします。カスタム入力ノードを決定するには、TensorBoard でモデルグラフを視覚化します。

TensorFlow 2 SavedModel 形式は、即時実行により特定のグラフ構造を持ちます。プルーニングの場合、StatefulPartitionedCall/* サブグラフでカスタム入力ノードを見つけます。

2023.0 リリース以降、SavedModel 形式のモデルの直接プルーニングはサポートされません。プルーニングする前にモデルをフリーズすることが必要です。モデルをフリーズするには、次のコードを使用します。

import tensorflow as tf
from tensorflow.python.framework.convert_to_constants import convert_variables_to_constants_v2
saved_model_dir = "./saved_model"
imported = tf.saved_model.load(saved_model_dir)
# retrieve the concrete function and freeze
concrete_func = imported.signatures[tf.saved_model.DEFAULT_SERVING_SIGNATURE_DEF_KEY]
frozen_func = convert_variables_to_constants_v2(concrete_func,
                                        lower_control_flow=False,
                                        aggressive_inlining=True)
# retrieve GraphDef and save it into .pb format
graph_def = frozen_func.graph.as_graph_def(add_shapes=True)
tf.io.write_graph(graph_def, '.', 'model.pb', as_text=False)

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 固有のパラメーターを使用したコマンドライン・インターフェイス (CLI) の例

  • モデルファイルがプレーンテキストの protobuf である場合、Inception V1 の凍結されたモデルの変換を開始します。

    mo --input_model inception_v1.pbtxt --input_model_is_text -b 1
    
  • Inception V1 のフリーズされたモデルの変換を開始し、グラフに関する情報を TensorBoard ログ・ディレクトリー /tmp/log_dir にダンプします。

    mo --input_model inception_v1.pb -b 1 --tensorboard_logdir /tmp/log_dir
    
  • 3 つの入力を使用して、SavedModel 形式の BERT モデルのモデル変換を開始します。バッチサイズとシーケンス長がそれぞれ 2 と 30 に等しい入力形状を明示的に指定します。

    mo --saved_model_dir BERT --input mask,word_ids,type_ids --input_shape [2,30],[2,30],[2,30]
    

Python API を使用したメモリーからの TensorFlow モデル変換

モデル変換 API は、TensorFlow/TensorFlow 2 モデルをメモリーから直接渡すことをサポートしています。

  • tf.keras.Model

    model = tf.keras.applications.ResNet50(weights="imagenet")
    ov_model = convert_model(model)
    
  • tf.keras.layers.Layer。“input_shape” の設定が必要です。

    import tensorflow_hub as hub
    
    model = hub.KerasLayer("https://tfhub.dev/google/imagenet/mobilenet_v1_100_224/classification/5")
    ov_model = convert_model(model, input_shape=[-1, 224, 224, 3])
    
  • tf.Module。“input_shape” の設定が必要です。

    class MyModule(tf.Module):
                                                def __init__(self, name=None):
                                                super().__init__(name=name)
                                                self.variable1 = tf.Variable(5.0, name="var1")
                                                self.variable2 = tf.Variable(1.0, name="var2")
                                                def __call__(self, x):
                                                return self.variable1 * x + self.variable2
    
    model = MyModule(name="simple_module")
    ov_model = convert_model(model, input_shape=[-1])
    
  • 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
    
    ov_model = 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
    
    ov_model = 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))
    
    ov_model = convert_model(func)
    
  • 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()
    
                                                ov_model = 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)
    ov_model = convert_model(checkpoint)
    

重要

convert_model() メソッドは、後で使用するため最適化、コンパイル、またはファイルに保存できる ov.Model を返します。

サポートされる TensorFlow および TensorFlow 2 Keras レイヤー

サポートされる標準レイヤーのリストについては、サポートされる操作を参照してください。

よくある問い合わせ (FAQ)

モデル変換 API は、タイプミス、誤って使用されたオプション、またはその他の問題により最後まで実行できない場合の説明メッセージを提供します。メッセージには問題の潜在的な原因と、モデル・オプティマイザーの FAQ へのリンクが示されます。FAQ には、ほとんどの問題の解決方法が記載されています。FAQ には、問題を理解するのに役立つ、モデルの変換の関連セクションへのリンクも含まれています。

まとめ

このセッションでは、次のことを学びました。

  • モデル変換 API が TensorFlow モデルでどのように動作するか理解する基本情報。

  • サポートされる TensorFlow モデル。

  • TensorFlow モデルをフリーズする方法。

  • フレームワークに依存しないコマンドライン・パラメーターと TensorFlow 固有のコマンドライン・パラメーターの両方を備えたモデル変換 API を使用して、トレーニングされた TensorFlow モデルを変換する方法。

関連情報

特定の TensorFlow モデルを変換するための段階的な手順を提供するチュートリアルについては、モデル変換チュートリアルのページを参照してください。いくつかの例を示します。