ホーム » TensorFlow 2.0 » TensorFlow 2.0 Alpha : ガイド : サービングへの単純なパス

TensorFlow 2.0 Alpha : ガイド : サービングへの単純なパス

TensorFlow 2.0 Alpha : ガイド : サービングへの単純なパス (翻訳/解説)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 03/25/2019

* 本ページは、TensorFlow の本家サイトの TF 2.0 Alpha の以下のページを翻訳した上で適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

ガイド : サービングへの単純なパス

SavedModel は重みと計算を含む、完全な TensorFlow プログラムを含みます。それは実行するための元のモデル構築コードを必要としません、これはそれを (TFLite, TensorFlow.js や TensorFlow Serving そして (TFHub による) モデル共有で) 配備のために有用にします。

Python のモデルのためのコードを持ち重みをそれにロードすることを望む場合には、訓練チェックポイント・ガイド を見てください。

簡単な紹介のために、このセクションでは事前訓練された Keras モデルをエクスポートしてそれで画像分類リクエストにサービスを提供します。ガイドの残りは詳細を補足して SavedModels を作成する他の方法を議論します。

from __future__ import absolute_import, division, print_function
!pip install -q tensorflow==2.0.0-alpha0
import tensorflow as tf
from matplotlib import pyplot as plt
import numpy as np

file = tf.keras.utils.get_file(
    "grace_hopper.jpg",
    "https://storage.googleapis.com/download.tensorflow.org/example_images/grace_hopper.jpg")
img = tf.keras.preprocessing.image.load_img(file, target_size=[224, 224])
plt.imshow(img)
plt.axis('off')
x = tf.keras.preprocessing.image.img_to_array(img)
x = tf.keras.applications.mobilenet.preprocess_input(
    np.array(img)[tf.newaxis,...])
Downloading data from https://storage.googleapis.com/download.tensorflow.org/example_images/grace_hopper.jpg
65536/61306 [================================] - 0s 0us/step

実行サンプルとしてグレース・ホッパーの画像を、そして Keras 事前訓練された画像分類モデルを使用します、何故ならばそれは簡単に利用できるからです。カスタムモデルも動作します、そして詳細は後でカバーされます。

pretrained_model = tf.keras.applications.MobileNet()
result_before_save = pretrained_model(x)
print("Result before saving", 
      tf.keras.applications.mobilenet.decode_predictions(
          result_before_save.numpy())[0][0])
Downloading data from https://github.com/fchollet/deep-learning-models/releases/download/v0.6/mobilenet_1_0_224_tf.h5
17227776/17225924 [==============================] - 1s 0us/step
Downloading data from https://s3.amazonaws.com/deep-learning-models/image-models/imagenet_class_index.json
40960/35363 [==================================] - 0s 2us/step
Result before saving ('n03763968', 'military_uniform', 0.701243)

この画像のための top 予測は “military uniform” (軍服) です。

tf.saved_model.save(pretrained_model, "/tmp/mobilenet/1/")

最後のディレクトリ (ここでは /1/) は貴方のモデルのこのバージョンに関する数字です – それは TensorFlow Serving のようなツールに同じモデルの異なるバージョンの相対的な新鮮さについて推理することを可能にします。

SavedModels はシグネチャと呼ばれる名前付き関数を持ちます。Keras モデルは serving_default シグネチャ・キーの基で forward パスをエクスポートします。The SavedModel command line interface はディスク上の SavedModels を調査するために有用です :

!saved_model_cli show --dir /tmp/mobilenet/1 --tag_set serve --signature_def serving_default
The given SavedModel SignatureDef contains the following input(s):
  inputs['input_1'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1, 224, 224, 3)
      name: serving_default_input_1:0
The given SavedModel SignatureDef contains the following output(s):
  outputs['reshape_2'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1, 1000)
      name: StatefulPartitionedCall:0
Method name is: tensorflow/serving/predict

tf.saved_model.load で SavedModel を python にロードし戻して Admiral ホッパーの画像がどのように分類されるかを見ることができます。

loaded = tf.saved_model.load("/tmp/mobilenet/1/")
print(list(loaded.signatures.keys()))  # ["serving_default"]
['serving_default']

インポートされたシグネチャは常に辞書を返します。

infer = loaded.signatures["serving_default"]
print(infer.structured_outputs)
{'reshape_2': TensorSpec(shape=(None, 1000), dtype=tf.float32, name='reshape_2')}

SavedModel からの推論の実行は元のモデルと同じ結果を与えます。

labeling = infer(tf.constant(x))["reshape_2"]
print("Result after saving and loading", 
      tf.keras.applications.mobilenet.decode_predictions(
          labeling.numpy())[0][0])
Result after saving and loading ('n03763968', 'military_uniform', 0.701243)

 

モデルをサーブする

SavedModels は Python から利用可能ですが、プロダクション環境は典型的には推論のために専用サービスを望みます。これは容易で TensorFlow Serving を使用して SavedModel からセットアップします。

ノートブックやローカルマシンに tensorflow_model_server をインストールするための手順を含む、serving の詳細については TensorFlow Serving REST チュートリアル を見てください。概観としては、上でエクスポートされた mobilenet モデルをサーブするために単に model server に SavedModel ディレクトリをポイントさせます :

nohup tensorflow_model_server \
  --rest_api_port=8501 \
  --model_name=mobilenet \
  --model_base_path="/tmp/mobilenet" >server.log 2>&1
  
  Then send a request.
  
>     ip install -q requests
>     port json
>     port numpy
>     port requests
>     ta = json.dumps({"signature_name": "serving_default", 
>                      "instances": x.tolist()})
>     aders = {"content-type": "application/json"}
>     on_response = requests.post('http://localhost:8501/v1/models/mobilenet:predict', 
>                                 data=data, headers=headers)
>     edictions = numpy.array(json.loads(json_response.text)["predictions"])

結果としての予測は Python からの結果と同一です。

 

SavedModel フォーマット

SavedModel はシリアライズされたシグネチャと変数値や語彙のようなそれらを実行するために必要な状態を含むディレクトリです。

!ls /tmp/mobilenet/1  # assets  saved_model.pb  variables
assets  saved_model.pb  variables

saved_model.pb は名前付けられたシグネチャのセットを含みます、それぞれが関数を識別します。SavedModels はシグネチャの複数のセット (saved_model_cli のために tag_set 引数で識別されるマルチ MetaGraphs) を含むかも知れませんが、これは稀です。シグネチャの複数セットを作成する API は tf.Estimator.experimental_export_all_saved_models と TensorFlow 1.x では tf.saved_model.Builder を含みます。

!saved_model_cli show --dir /tmp/mobilenet/1 --tag_set serve
The given SavedModel MetaGraphDef contains SignatureDefs with the following keys:
SignatureDef key: "__saved_model_init_op"
SignatureDef key: "serving_default"

variables ディレクトリは標準的な訓練チェックポイントを含みます (訓練チェックポイント・ガイド を見てください)。

!ls /tmp/mobilenet/1/variables
variables.data-00000-of-00001  variables.index

assets ディレクトリは TensorFlow グラフにより使用されるファイルを含みます、例えば語彙テーブルを初期化するために使用されるテキストファイルです。この例ではそれは未使用です。

SavedModels は TensorFlow グラフで使用されない任意のファイルのための assets.extra ディレクトリを持つかもしれません、例えば SavedModel で何をするかについての消費者のための情報です。TensorFlow 自身はこのディレクトリは使用しません。

 

カスタムモデルをエクスポートする

最初のセクションでは、tf.saved_model.save が tf.keras.Model オブジェクトのためのシグネチャを自動的に決定しました。これは、Keras モデルオブジェクトがエクスポートするための明確なメソッドと既知の入力 shape を持つために動作しました。tf.saved_model.save は単に低位モデル構築 API でも同様に動作しますが、モデルをサーブすることを計画しているのであれば、シグネチャとしてどの関数を使用するかを示す必要があるでしょう。

class CustomModule(tf.Module):

  def __init__(self):
    super(CustomModule, self).__init__()
    self.v = tf.Variable(1.)

  @tf.function
  def __call__(self, x):
    return x * self.v

  @tf.function(input_signature=[tf.TensorSpec([], tf.float32)])
  def mutate(self, new_v):
    self.v.assign(new_v)

module = CustomModule()

このモジュールは tf.function で修飾される 2 つのメソッドを持ちます。SavedModel が tf.saved_model.load 経由で Python プログラムに再ロードされる場合、これらの関数が SAvedModel に含まれて利用可能である一方で、サービング・シグネチャを明示的に宣言することなしに、TensorFlow Serving と saved_model_cli のようなツールはそれらにアクセスできません。

module.mutate は input_signature を持ちますので、その計算グラフを SavedModel にセーブするために十分な情報が既にあります。__call__ はシグネチャを持ちませんのでこのメソッドはセーブする前に呼び出される必要があります。

module(tf.constant(0.))
tf.saved_model.save(module, "/tmp/module_no_signatures")

input_signature がない関数のためには、セーブする前に使用された任意の入力 shape がロードの後で利用可能です。__call__ を単なるスカラーで呼び出しましたので、それはスカラー値だけを受け取ります。

imported = tf.saved_model.load("/tmp/module_no_signatures")
assert 3. == imported(tf.constant(3.)).numpy()
imported.mutate(tf.constant(2.))
assert 6. == imported(tf.constant(3.)).numpy()

関数はベクトルのような新しい shape は受け取りません。

imported(tf.constant([3.]))
ValueError: Could not find matching function to call for canonicalized inputs ((,), {}). Only existing signatures are [((TensorSpec(shape=(), dtype=tf.float32, name=u'x'),), {})].

get_concrete_function は貴方にそれを呼び出すことなしに関数に入力 shape を追加させます。それは Tensor 引数の代わりに tf.TensorSpec オブジェクトを取り、入力の shape と dtype を示します。shape は任意の shape が受け取れることを示す None か、軸 size のリストです。軸 size が None の場合には、その軸に対して任意のサイズが受け取れます。tf.TensorSpecs はまた名前を持つことができて、これは関数の引数キーワードがデフォルトです (ここでは “x”)。

module.__call__.get_concrete_function(x=tf.TensorSpec([None], tf.float32))
tf.saved_model.save(module, "/tmp/module_no_signatures")
imported = tf.saved_model.load("/tmp/module_no_signatures")
assert [3.] == imported(tf.constant([3.])).numpy()

tf.keras.Model and tf.Module のようなオブジェクトにアタッチする関数と変数は imort で利用可能ですが、多くの Python 型と属性は失われます。Python プログラム自身は SavedModel にセーブされません。

シグネチャとしてエクスポートした任意の関数を識別しませんので、それは何も持ちません。

!saved_model_cli show --dir /tmp/module_no_signatures --tag_set serve
The given SavedModel MetaGraphDef contains SignatureDefs with the following keys:
SignatureDef key: "__saved_model_init_op"

 

エクスポートするシグネチャを識別する

関数がシグネチャであるべきであることを示すために、セーブするときに signatures 引数を指定します。

call = module.__call__.get_concrete_function(tf.TensorSpec(None, tf.float32))
tf.saved_model.save(module, "/tmp/module_with_signature", signatures=call)

tf.function を最初に get_concrete_function で ConcreteFunction に変換したことが分かるでしょう。これは必要です、何故ならば関数は固定された input_signature なしで作成されましたので、それに関連する Tensor 入力の明確なセットを持たなかったからです。

!saved_model_cli show --dir /tmp/module_with_signature --tag_set serve --signature_def serving_default
The given SavedModel SignatureDef contains the following input(s):
  inputs['x'] tensor_info:
      dtype: DT_FLOAT
      shape: unknown_rank
      name: serving_default_x:0
The given SavedModel SignatureDef contains the following output(s):
  outputs['output_0'] tensor_info:
      dtype: DT_FLOAT
      shape: unknown_rank
      name: StatefulPartitionedCall:0
Method name is: tensorflow/serving/predict
imported = tf.saved_model.load("/tmp/module_with_signature")
signature = imported.signatures["serving_default"]
assert [3.] == signature(x=tf.constant([3.]))["output_0"].numpy()
imported.mutate(tf.constant(2.))
assert [6.] == signature(x=tf.constant([3.]))["output_0"].numpy()
assert 2. == imported.v.numpy()

単一のシグネチャをエクスポートして、そのキーは “serving_default” にデフォルト設定されました。複数シグネチャをエクスポートするためには、辞書を渡します。

@tf.function(input_signature=[tf.TensorSpec([], tf.string)])
def parse_string(string_input):
  return imported(tf.strings.to_number(string_input))

signatures = {"serving_default": parse_string, 
              "from_float": imported.signatures["serving_default"]}

tf.saved_model.save(imported, "/tmp/module_with_multiple_signatures", signatures)
!saved_model_cli show --dir /tmp/module_with_multiple_signatures --tag_set serve
The given SavedModel MetaGraphDef contains SignatureDefs with the following keys:
SignatureDef key: "__saved_model_init_op"
SignatureDef key: "from_float"
SignatureDef key: "serving_default"

saved_model_cli はまたコマンドラインから直接 SavedModels を実行できます。

!saved_model_cli run --dir /tmp/module_with_multiple_signatures --tag_set serve\
 --signature_def serving_default --input_exprs="string_input='3.'"
!saved_model_cli run --dir /tmp/module_with_multiple_signatures --tag_set serve\
 --signature_def from_float --input_exprs="x=3."
2019-03-07 18:09:11.694255: I tensorflow/core/platform/cpu_feature_guard.cc:142] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
2019-03-07 18:09:11.717052: I tensorflow/core/platform/profile_utils/cpu_utils.cc:94] CPU Frequency: 3491755000 Hz
2019-03-07 18:09:11.718329: I tensorflow/compiler/xla/service/service.cc:162] XLA service 0x5a156e0 executing computations on platform Host. Devices:
2019-03-07 18:09:11.718391: I tensorflow/compiler/xla/service/service.cc:169]   StreamExecutor device (0): , 
WARNING: Logging before flag parsing goes to stderr.
W0307 18:09:11.720156 139736676427520 deprecation.py:323] From /usr/local/lib/python3.5/dist-packages/tensorflow/python/tools/saved_model_cli.py:339: load (from tensorflow.python.saved_model.loader_impl) is deprecated and will be removed in a future version.
Instructions for updating:
This function will only be available through the v1 compatibility library as tf.compat.v1.saved_model.loader.load or tf.compat.v1.saved_model.load. There will be a new function for importing SavedModels in Tensorflow 2.0.
W0307 18:09:11.738183 139736676427520 deprecation.py:323] From /usr/local/lib/python3.5/dist-packages/tensorflow/python/training/saver.py:1276: checkpoint_exists (from tensorflow.python.training.checkpoint_management) is deprecated and will be removed in a future version.
Instructions for updating:
Use standard file APIs to check for files with this prefix.
Result for output key output_0:
6.0
2019-03-07 18:09:14.695447: I tensorflow/core/platform/cpu_feature_guard.cc:142] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
2019-03-07 18:09:14.716983: I tensorflow/core/platform/profile_utils/cpu_utils.cc:94] CPU Frequency: 3491755000 Hz
2019-03-07 18:09:14.718031: I tensorflow/compiler/xla/service/service.cc:162] XLA service 0x470b890 executing computations on platform Host. Devices:
2019-03-07 18:09:14.718085: I tensorflow/compiler/xla/service/service.cc:169]   StreamExecutor device (0): , 
WARNING: Logging before flag parsing goes to stderr.
W0307 18:09:14.719855 140115307210496 deprecation.py:323] From /usr/local/lib/python3.5/dist-packages/tensorflow/python/tools/saved_model_cli.py:339: load (from tensorflow.python.saved_model.loader_impl) is deprecated and will be removed in a future version.
Instructions for updating:
This function will only be available through the v1 compatibility library as tf.compat.v1.saved_model.loader.load or tf.compat.v1.saved_model.load. There will be a new function for importing SavedModels in Tensorflow 2.0.
W0307 18:09:14.737620 140115307210496 deprecation.py:323] From /usr/local/lib/python3.5/dist-packages/tensorflow/python/training/saver.py:1276: checkpoint_exists (from tensorflow.python.training.checkpoint_management) is deprecated and will be removed in a future version.
Instructions for updating:
Use standard file APIs to check for files with this prefix.
Result for output key output_0:
6.0

 

インポートされたモデルを再調整する

変数オブジェクトが利用可能で、インポートされた関数を通して backprop できます。

optimizer = tf.optimizers.SGD(0.05)

def train_step():
  with tf.GradientTape() as tape:
    loss = (10. - imported(tf.constant(2.))) ** 2
  variables = tape.watched_variables()
  grads = tape.gradient(loss, variables)
  optimizer.apply_gradients(zip(grads, variables))
  return loss
for _ in range(10):
  # "v" approaches 5, "loss" approaches 0
  print("loss={:.2f} v={:.2f}".format(train_step(), imported.v.numpy()))
loss=36.00 v=3.20
loss=12.96 v=3.92
loss=4.67 v=4.35
loss=1.68 v=4.61
loss=0.60 v=4.77
loss=0.22 v=4.86
loss=0.08 v=4.92
loss=0.03 v=4.95
loss=0.01 v=4.97
loss=0.00 v=4.98

 

SavedModels の制御フロー

tf.function に入るものは何でも SavedModel に入ることができます。AutoGraph ではこれは通常の Python 制御フローで指定される、Tensor に依拠する条件付きロジックを含みます。

@tf.function(input_signature=[tf.TensorSpec([], tf.int32)])
def control_flow(x):
  if x < 0:
    tf.print("Invalid!")
  else:
    tf.print(x % 3)

to_export = tf.Module()
to_export.control_flow = control_flow
tf.saved_model.save(to_export, "/tmp/control_flow")
imported = tf.saved_model.load("/tmp/control_flow")
imported.control_flow(tf.constant(-1))  # Invalid!
imported.control_flow(tf.constant(2))   # 2
imported.control_flow(tf.constant(3))   # 0
Invalid!
2
0

 

Estimators からの SavedModels

Estimator は tf.Estimator.export_saved_model を通して SavedModels をエクスポートします。詳細は guide to Estimator を見てください。

input_column = tf.feature_column.numeric_column("x")
estimator = tf.estimator.LinearClassifier(feature_columns=[input_column])

def input_fn():
  return tf.data.Dataset.from_tensor_slices(
    ({"x": [1., 2., 3., 4.]}, [1, 1, 0, 0])).repeat(200).shuffle(64).batch(16)
estimator.train(input_fn)

serving_input_fn = tf.estimator.export.build_parsing_serving_input_receiver_fn(
  tf.feature_column.make_parse_example_spec([input_column]))
export_path = estimator.export_saved_model(
  "/tmp/from_estimator/", serving_input_fn)
WARNING: Logging before flag parsing goes to stderr.
W0307 18:09:15.471116 140431406638848 estimator.py:1799] Using temporary folder as model directory: /tmp/tmptkhkl2j8
W0307 18:09:15.482192 140431406638848 deprecation.py:323] From /usr/local/lib/python3.5/dist-packages/tensorflow/python/training/training_util.py:238: Variable.initialized_value (from tensorflow.python.ops.variables) is deprecated and will be removed in a future version.
Instructions for updating:
Use Variable.read_value. Variables in 2.X are initialized automatically both in eager and graph (inside tf.defun) contexts.
W0307 18:09:15.530143 140431406638848 deprecation.py:323] From /usr/local/lib/python3.5/dist-packages/tensorflow/python/feature_column/feature_column_v2.py:2758: to_float (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use `tf.cast` instead.
W0307 18:09:15.894593 140431406638848 deprecation.py:506] From /usr/local/lib/python3.5/dist-packages/tensorflow/python/training/slot_creator.py:187: calling Zeros.__init__ (from tensorflow.python.ops.init_ops) with dtype is deprecated and will be removed in a future version.
Instructions for updating:
Call initializer instance with the dtype argument instead of passing it to the constructor
W0307 18:09:16.674963 140431406638848 deprecation.py:323] From /usr/local/lib/python3.5/dist-packages/tensorflow/python/saved_model/signature_def_utils_impl.py:201: build_tensor_info (from tensorflow.python.saved_model.utils_impl) is deprecated and will be removed in a future version.
Instructions for updating:
This function will only be available through the v1 compatibility library as tf.compat.v1.saved_model.utils.build_tensor_info or tf.compat.v1.saved_model.build_tensor_info.
W0307 18:09:16.716552 140431406638848 deprecation.py:323] From /usr/local/lib/python3.5/dist-packages/tensorflow/python/training/saver.py:1276: checkpoint_exists (from tensorflow.python.training.checkpoint_management) is deprecated and will be removed in a future version.
Instructions for updating:
Use standard file APIs to check for files with this prefix.

この SavedModel はシリアライズされた tf.Example protocol buffer を受け取ります、これはサービングのために有用です。しかしそれを tf.saved_model.load でロードしてそれを Python から実行することもできます。

imported = tf.saved_model.load(export_path)

def predict(x):
  example = tf.train.Example()
  example.features.feature["x"].float_list.value.extend([x])
  return imported.signatures["predict"](
    examples=tf.constant([example.SerializeToString()]))
print(predict(1.5))
print(predict(3.5))
{'classes': <tf.Tensor: id=12044, shape=(1, 1), dtype=string, numpy=array([[b'1']], dtype=object)>, '<tf.Tensor: id=12047, shape=(1, 2), dtype=float32, numpy=array([[0.40853757, 0.59146243]], dtype=float32)>, 'class_ids': <tf.Tensor: id=12043, shape=(1, 1), dtype=int64, numpy=array([[1]])>, 'logistic': <tf.Tensor: id=12045, shape=(1, 1), dtype=float32, numpy=array([[0.59146243]], dtype=float32)>, 'logits': <tf.Tensor: id=12046, shape=(1, 1), dtype=float32, numpy=array([[0.3700143]], dtype=float32)>}
{'classes': <tf.Tensor: id=12055, shape=(1, 1), dtype=string, numpy=array([[b'0']], dtype=object)>, 'probabilities': <tf.Tensor: id=12058, shape=(1, 2), dtype=float32, numpy=array([[0.76074064, 0.23925935]], dtype=float32)>, 'class_ids': <tf.Tensor: id=12054, shape=(1, 1), dtype=int64, numpy=array([[0]])>, 'logistic': <tf.Tensor: id=12056, shape=(1, 1), dtype=float32, numpy=array([[0.23925935]], dtype=float32)>, '<tf.Tensor: id=12057, shape=(1, 1), dtype=float32, numpy=array([[-1.1567444]], dtype=float32)>}

tf.estimator.export.build_raw_serving_input_receiver_fn は、tf.train.Examples ではなく生 tensor を取る入力関数を作成することを可能にします。

 

C++ で SavedModel をロードする

SavedModel loader の C++ バージョンは、SessionOptions と RunOptions を可能にしながら、SavedModel をパスからロードする API を提供します。ロードされるグラフに関連するタグを指定しなければなりません。SavedModel のロードされたバージョンは SavedModelBundle として参照されて MetaGraphDef とそれがロードされた session を含みます。

const string export_dir = ...
SavedModelBundle bundle;
...
LoadSavedModel(session_options, run_options, export_dir, {kSavedModelTagTrain},
               &bundle);

 

SavedModel コマンドライン・インターフェイスの詳細

SavedModel を調査して実行するために SavedModel コマンドライン・インターフェイス (CLI) を利用できます。例えば、モデルの SignatureDefs を調べるために CLI を使用できます。CLI は入力 Tensor dtype と shape がモデルにマッチしていることを簡単に確かめることを可能にします。更に、貴方のモデルをテストすることを望むのであれば、サンプル入力を様々なフォーマット (例えば、Python 式) で渡して出力を取得することによりサニティチェックを行なうために CLI を使用できます。

 

SavedModel CLI をインストールする

大まかに言って、TensorFlow を次の 2 つの方法のどちらかでインストールできます :

  • 事前ビルドされた TensorFlow バイナリをインストールすることによって。
  • ソースコードから TensorFlow をビルドすることによって。

事前ビルドされた TensorFlow バイナリを通して TensorFlow をインストールした場合、SavedModel CLI は貴方のシステム上にパス名 bin\saved_model_cli で既にインストールされています。

TensorFlow をソースコードからビルドした場合、saved_model_cli をビルドするために次の追加のコマンドを実行しなければなりません :

$ bazel build tensorflow/python/tools:saved_model_cli

 

コマンドの概要

SavedModel CLI は SavedModel の MetaGraphDef 上で次の 2 つのコマンドをサポートします :

  • show, これは SavedModel の MetaGraphDef 上の計算を示します。
  • run, これは MetaGraphDef 上の計算を実行します。

 

show コマンド

SavedModel は一つまたはそれ以上の MetaGraphDefs を含み、それらのタグセットによって識別されます。モデルをサーブするために、貴方は各モデルにどのような種類の SignatureDefs があり、それらの入力と出力が何かを思案するかもしれません。show コマンドは貴方に SavedModel の内容を階層的順序で調べさせます。ここにシンタックスがあります :

usage: saved_model_cli show [-h] --dir DIR [--all]
[--tag_set TAG_SET] [--signature_def SIGNATURE_DEF_KEY]

例えば、次のコマンドは SavedModel の総ての利用可能な MetaGraphDef タグセットを表示します :

$ saved_model_cli show --dir /tmp/saved_model_dir
The given SavedModel contains the following tag-sets:
serve
serve, gpu

次のコマンドは MetaGraphDef の総ての利用可能な SignatureDef キーを表示します :

$ saved_model_cli show --dir /tmp/saved_model_dir --tag_set serve
The given SavedModel `MetaGraphDef` contains `SignatureDefs` with the
following keys:
SignatureDef key: "classify_x2_to_y3"
SignatureDef key: "classify_x_to_y"
SignatureDef key: "regress_x2_to_y3"
SignatureDef key: "regress_x_to_y"
SignatureDef key: "regress_x_to_y2"
SignatureDef key: "serving_default"

MetaGraphDef がタグセットで複数のタグを持つ場合、総てのタグを指定しなければなりません、各タグはカンマで分離されます。例えば :

$ saved_model_cli show --dir /tmp/saved_model_dir --tag_set serve,gpu

特定の SignatureDef のための総ての入力と出力 TensorInfo を表示するには、signature_def オプションに SignatureDef キーを渡します。貴方が計算グラフを後で実行するために tensor キー値、入力 tensor の dtype と shape を知ることを望むときこれは非常に有用です。例えば :

$ saved_model_cli show --dir \
/tmp/saved_model_dir --tag_set serve --signature_def serving_default
The given SavedModel SignatureDef contains the following input(s):
  inputs['x'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1, 1)
      name: x:0
The given SavedModel SignatureDef contains the following output(s):
  outputs['y'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1, 1)
      name: y:0
Method name is: tensorflow/serving/predict

SavedModel の総ての利用可能な情報を表示するには、--all オプションを使用します。例えば :

$ saved_model_cli show --dir /tmp/saved_model_dir --all
MetaGraphDef with tag-set: 'serve' contains the following SignatureDefs:

signature_def['classify_x2_to_y3']:
  The given SavedModel SignatureDef contains the following input(s):
    inputs['inputs'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, 1)
        name: x2:0
  The given SavedModel SignatureDef contains the following output(s):
    outputs['scores'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, 1)
        name: y3:0
  Method name is: tensorflow/serving/classify

...

signature_def['serving_default']:
  The given SavedModel SignatureDef contains the following input(s):
    inputs['x'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, 1)
        name: x:0
  The given SavedModel SignatureDef contains the following output(s):
    outputs['y'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, 1)
        name: y:0
  Method name is: tensorflow/serving/predict

 

run コマンド

グラフ計算を実行するために run コマンドを起動します、入力を渡して出力を表示します (そしてオプションでセーブします)。ここにシンタックスがあります :

usage: saved_model_cli run [-h] --dir DIR --tag_set TAG_SET --signature_def
                           SIGNATURE_DEF_KEY [--inputs INPUTS]
                           [--input_exprs INPUT_EXPRS]
                           [--input_examples INPUT_EXAMPLES] [--outdir OUTDIR]
                           [--overwrite] [--tf_debug]

run コマンドは入力をモデルに渡す次の 3 つの方法を提供します。

  • --inputs オプションは ファイルの numpy ndarray を渡すことを可能にします。
  • --input_exprs オプションは Python 式を渡すことを可能にします。
  • --input_examples オプションは tf.train.Example を渡すことを可能にします。

 
--inputs

ファイルの入力データを渡すために、--inputs オプションを指定します、これは次の一般的な形式を取ります :

--inputs <INPUTS>

ここで INPUTS は次の形式のいずれかです :

  • <input_key>=<filename>
  • <input_key>=<filename>[<variable_name>]

複数の INPUTS を渡すかもしれません。複数の入力を渡す場合には、INPUTS の各々を分離するためにセミコロンを使用します。

saved_model_cli は filename をロードするために numpy.load を使用します。filename は次の形式の任意の一つにあります :

  • .npy
  • .npz
  • pickle 形式

.npy ファイルは常に numpy ndarray を含みます。従って、.npy ファイルからロードするとき、内容な指定された入力 tensor に直接割り当てられます。その .npy ファイルで variable_name を指定する場合、variable_name は無視されて警告が発せられます。

.npz (zip) ファイルからロードするとき、入力 tensor キーのためにロードする zip ファイル内の変数を識別するためにオプションで variable_name を指定することもできます。variable_name を指定しない場合は、SavedModel CLI は zip ファイルに一つのファイルだけが含まれていることを確認してそれを指定された入力 tensor キーのためにロードします。

pickle ファイルからロードするときは、variable_name が角括弧で指定されない場合は、pickle ファイルの内側にあるものは何でも指定された入力 tensor キーに渡されます。そうでなければ、SavedModel CLI は pickle ファイルに辞書がストアされていることを想定して variable_name に対応する値が使用されるでしょう。

 
--input_exprs

入力を Python 式を通して渡すためには、--input_exprs オプションを指定します。これは貴方が転がっているデータファイルを持たないけれども、モデルの SignatureDefs の dtype と shape にマッチする何某かの単純な入力でモデルをサニティチェックすることを依然として望むときに有用です。例えば :

`<input_key>=[[1],[2],[3]]`

Python 式に加えて、numpy 関数を渡しても良いです。例えば :

`<input_key>=np.ones((32,32,3))`

(numpy モジュールは np として既に利用可能であることに注意してください。)

 
--input_examples

入力として tf.train.Example を渡すには、--input_examples オプションを指定します。各入力キーについて、それは辞書のリストを取り、そこでは各辞書は tf.train.Example のインスタンスです。辞書キーは特徴で値は各特徴のための値リストです。例えば :

`<input_key>=[{"age":[22,24],"education":["BS","MS"]}]`

 
出力をセーブする

デフォルトでは、SavedModel CLI は出力を stdout に書きます。

ディレクトリが --outdir オプションで渡される場合、出力は出力 tensor キーの名前を取って与えられたディレクトリ下に npy ファイルとしてセーブされます。

既存の出力ファイルに上書きするためには --overwrite を使用します。

 

以上



AI導入支援 #2 ウェビナー

スモールスタートを可能としたAI導入支援   Vol.2
[無料 WEB セミナー] [詳細]
「画像認識 AI PoC スターターパック」の紹介
既に AI 技術を実ビジネスで活用し、成果を上げている日本企業も多く存在しており、競争優位なビジネスを展開しております。
しかしながら AI を導入したくとも PoC (概念実証) だけでも高額な費用がかかり取組めていない企業も少なくないようです。A I導入時には欠かせない PoC を手軽にしかも短期間で認知度を確認可能とするサービの紹介と共に、AI 技術の特性と具体的な導入プロセスに加え運用時のポイントについても解説いたします。
日時:2021年10月13日(水)
会場:WEBセミナー
共催:クラスキャット、日本FLOW(株)
後援:働き方改革推進コンソーシアム
参加費: 無料 (事前登録制)
人工知能開発支援
◆ クラスキャットは 人工知能研究開発支援 サービスを提供しています :
  • テクニカルコンサルティングサービス
  • 実証実験 (プロトタイプ構築)
  • アプリケーションへの実装
  • 人工知能研修サービス
◆ お問合せ先 ◆
(株)クラスキャット
セールス・インフォメーション
E-Mail:sales-info@classcat.com