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 つのサブフォルダーで構成されます: 内部の 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
  1. 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 を呼び出す際に、モデルファイル形式を明示的に指定する必要はありません。

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

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