TensorFlow モデルから変換

このページでは、TensorFlow 形式から OpenVINO IR 形式へのモデル変換を行う一般的な手順を説明します。手順は、モデルが TensorFlow v1.X で作成されたか TensorFlow v2.X で作成されたかにより異なります。

TensorFlow モデルは、最初に OpenVINO IR を準備しなくても、OpenVINO ランタイム API による openvino.Core.read_model メソッドまたは openvino.Core.compile_model メソッドによってロードできます。詳細については、推論の例を参照してください。モデルの読み込みレイテンシーが推論アプリケーションにとって重要である場合は、引き続き openvino.convert_model を使用することを推奨します。

ファイルから TensorFlow モデルを変換する以下の例では、tensorflow モジュールが明示的にインポートされる場合を除き、システムに TensorFlow をインストールする必要はありません。

TensorFlow 2 モデルから変換

TensorFlow 2.X は、次の 2 つのモデル形式をサポートしています: SavedModel と Keras H5 (または HDF5)。以下にそれぞれの変換方法を示します。

SavedModel 形式

SavedModel 形式のモデルは、saved_model.pb ファイルを含むディレクトリーと 2 つのサブフォルダーで構成されます: variablesassets 内部。モデルを変換するには、ディレクトリーをモデル引数として変換を行います。

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 つの方法があります。

1. SavedModel 形式。この場合、モデルは .pb ファイルを含む特別なディレクトリーとサブフォルダーで構成されます: variablesassets、および 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

2. 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 を呼び出す際に、モデルファイル形式を明示的に指定する必要はありません。

3. MetaGraph。この場合、モデルは同じディレクトリーに保存された 3 つまたは 4 つのファイルで構成されます: model_name.metamodel_name.indexmodel_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 モデルをメモリーから直接渡すことをサポートしています。

  • Trackablehub.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.Layertf.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.Moduleinput パラメーターで形状を設定する必要があります。

    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 モデルをフリーズする方法。