TensorFlow 2.4 : ガイド : モデルのセーブ :- SavedModel 形式を使用する (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 01/30/2021
* 本ページは、TensorFlow org サイトの Guide – Save a model の以下のページを翻訳した上で
適宜、補足説明したものです:
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
- お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
- Windows PC のブラウザからご参加が可能です。スマートデバイスもご利用可能です。
人工知能研究開発支援 | 人工知能研修サービス | テレワーク & オンライン授業を支援 |
PoC(概念実証)を失敗させないための支援 (本支援はセミナーに参加しアンケートに回答した方を対象としています。) |
◆ お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。
株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション |
E-Mail:sales-info@classcat.com ; WebSite: https://www.classcat.com/ |
Facebook: https://www.facebook.com/ClassCatJP/ |
ガイド : モデルのセーブ :- SavedModel 形式を使用する
SavedModel は訓練パラメータ (i.e, tf.Variables) と計算を含む、完全な TensorFlow プログラムを含みます。それは実行するためのオリジナルのモデル構築コードを必要としません、それは TFLite, TensorFlow.js, TensorFlow Serving や TensorFlow Hub で共有あるいは配備するために有用にします。
以下の API を使用して SavedModel 形式のモデルをセーブしてロードできます :
- 低位 tf.saved_model API。このドキュメントはこの API をどのように使用するかを詳細に記述します。
- セーブ: tf.saved_model.save(model, path_to_dir)
- ロード: model = tf.saved_model.load(path_to_dir)
- 高位 tf.keras.Model API。keras セーブとシリアライズ・ガイド 参照。
- 訓練の間に重みをセーブ/ロードすることを単に望む場合、チェックポイント・ガイド 参照。
Keras から SavedModel を作成する
素早いイントロダクションとして、このセクションは事前訓練 Keras モデルをエクスポートしてそれで画像分類リクエストに役立てます。ガイドの残りは詳細を補足説明して SavedModel を作成するための他の方法を議論します。
import os import tempfile from matplotlib import pyplot as plt import numpy as np import tensorflow as tf tmpdir = tempfile.mkdtemp()
physical_devices = tf.config.experimental.list_physical_devices('GPU') for device in physical_devices: tf.config.experimental.set_memory_growth(device, True)
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( x[tf.newaxis,...])
Downloading data from https://storage.googleapis.com/download.tensorflow.org/example_images/grace_hopper.jpg 65536/61306 [================================] - 0s 0us/step
Grace Hopper の画像を動作するサンプルとして、そして Keras の事前訓練された画像分類モデルを使用します、何故ならばそれは簡単に利用できるからです。カスタム・モデルもまた動作します、そして後で詳細にカバーされます。
labels_path = tf.keras.utils.get_file( 'ImageNetLabels.txt', 'https://storage.googleapis.com/download.tensorflow.org/data/ImageNetLabels.txt') imagenet_labels = np.array(open(labels_path).read().splitlines())
Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/ImageNetLabels.txt 16384/10484 [==============================================] - 0s 0us/step
pretrained_model = tf.keras.applications.MobileNet() result_before_save = pretrained_model(x) decoded = imagenet_labels[np.argsort(result_before_save)[0,::-1][:5]+1] print("Result before saving:\n", decoded)
Downloading data from https://storage.googleapis.com/tensorflow/keras-applications/mobilenet/mobilenet_1_0_224_tf.h5 17227776/17225924 [==============================] - 0s 0us/step Result before saving: ['military uniform' 'bow tie' 'suit' 'bearskin' 'pickelhaube']
この画像に対する top 予測は「military uniform (軍服)」です。
mobilenet_save_path = os.path.join(tmpdir, "mobilenet/1/") tf.saved_model.save(pretrained_model, mobilenet_save_path)
INFO:tensorflow:Assets written to: /tmp/tmpeu7g2o56/mobilenet/1/assets
save-path は TensorFlow Serving により使用される慣習に従います、そこでは最後のパス成分 (ここでは 1/) は貴方のモデルのためのバージョン番号です – それは TensorFlow Serving のようなツールに相対的な鮮度 (= freshness) について推論することを可能にします。tf.saved_model.load で SavedModel を Python にロードし戻して、そして Admiral Hopper の画像がどのように分類されるかを見ることができます。
loaded = tf.saved_model.load(mobilenet_save_path) print(list(loaded.signatures.keys())) # ["serving_default"]
['serving_default']
インポートされたシグネチャは常に辞書を返します。シグネチャ名と出力辞書キーをカスタマイズするためには、Specifying signatures during export を見てください。
infer = loaded.signatures["serving_default"] print(infer.structured_outputs)
{'predictions': TensorSpec(shape=(None, 1000), dtype=tf.float32, name='predictions')}
SavedModel からの推論の実行はオリジナル・モデルと同じ結果を与えます。
labeling = infer(tf.constant(x))[pretrained_model.output_names[0]] decoded = imagenet_labels[np.argsort(labeling)[0,::-1][:5]+1] print("Result after saving and loading:\n", decoded)
Result after saving and loading: ['military uniform' 'bow tie' 'suit' 'bearskin' 'pickelhaube']
TensorFlow Serving で SavedModel を実行する
SavedModel は Python から利用可能ですが (それについてのより多くは下で)、プロダクション環境は典型的には Python コードを実行することなしに推論のために専用サービスを利用します。TensorFlow Serving を使用して SavedModel からセットアップすることは容易です。
end-to-end な tensorflow-serving サンプルについては TensorFlow Serving REST チュートリアル を見てください。
ディスク上の SavedModel 形式
SavedModel は、変数値とボキャブラリを含む、シリアライズされたシグネチャとそれらを実行するために必要な状態を含む辞書です。
ls {mobilenet_save_path}
assets/ saved_model.pb variables/
saved_model.pb は実際の TensorFlow プログラム、あるいはモデル、そしてそれぞれ (tensor 入力を受け取り tensor 出力を生成する) 関数を識別する、名前付けられたシグネチャのセットをストアします。
SavedModel はモデルの複数のバージョン (= variants) を含むかも知れませんが (saved_model_cli への –tag_set フラグで識別される、複数の v1.MetaGraphDefs)、これは稀です。モデルの複数のバージョンを作成する API は tf.Estimator.experimental_export_all_saved_models、そして TensorFlow 1.x tf.saved_model.Builder を含みます。
saved_model_cli show --dir {mobilenet_save_path} --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 {mobilenet_save_path}/variables
variables.data-00000-of-00001 variables.index
assets ディレクトリは TensorFlow グラフにより使用されるファイルを含みます、例えば語彙テーブルを初期化するために使用されるテキストファイルです。それはこのサンプルでは使用されません。
SavedModel は TensorFlow グラフで使用されない任意のファイルのために assets.extra を持つかもしれません、例えば SavedModel で何を行なうかについての消費者のための情報です。TensorFlow 自身はこのディレクトリを使用しません。
カスタム・モデルをセーブする
tf.saved_model.save は tf.keras.Layer と tf.keras.Model のような、tf.Module とそのサブクラスのセーブをサポートします。
tf.Module をセーブしてリストアするサンプルを見ましょう。
class CustomModule(tf.Module): def __init__(self): super(CustomModule, self).__init__() self.v = tf.Variable(1.) @tf.function def __call__(self, x): print('Tracing with', 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.Module をセーブするとき、任意の tf.Variable 属性、tf.function でデコレートされたメソッド、そして再帰的な traversal (辿ること) を通して tf.Module がセーブされます (この再帰的 traversal についてのより多くは チェックポイント・チュートリアル 参照)。けれども、任意の Python 属性、関数とデータは失われます。これは tf.function がセーブされるとき、Python コードはセーブされないことを意味します。
Python コードがセーブされないのであれば、SavedModel は関数をどのようにリストアするかをどのように知るのでしょう?
簡潔に言えば、tf.function は ConcreteFunction (tf.Graph 回りの callable なラッパー) を生成するために Python コードをトレースすることにより動作します。tf.function をセーブするとき、実際には ConcreteFunction の tf.function のキャッシュをセーブしています。
tf.function と ConcreteFunctions の間の関係について更に学習するには、tf.function ガイド を見てください。
module_no_signatures_path = os.path.join(tmpdir, 'module_no_signatures') module(tf.constant(0.)) print('Saving model...') tf.saved_model.save(module, module_no_signatures_path)
Tracing with Tensor("x:0", shape=(), dtype=float32) Saving model... Tracing with Tensor("x:0", shape=(), dtype=float32) INFO:tensorflow:Assets written to: /tmp/tmpxskcqu8t/module_no_signatures/assets
カスタム・モデルをロードして使用する
Python で SavedModel をロードするとき、総ての tf.Variable 属性、tf.function-decorated メソッド、と tf.Module はオリジナルのセーブされた tf.Module と同じオブジェクト構造でリストアされます。
imported = tf.saved_model.load(module_no_signatures_path) assert imported(tf.constant(3.)).numpy() == 3 imported.mutate(tf.constant(2.)) assert imported(tf.constant(3.)).numpy() == 6
Python コードはセーブされていませんので、新しい入力シグネチャを伴う tf.function の呼び出しは失敗します :
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'),), {})].
基本的な再調整
変数オブジェクトは利用可能で、インポートされた関数を通して逆伝播できます。これは単純なケースでは SavedModel を再調整 (i.e. 再訓練) するためには十分です。
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
一般的な再調整
Keras からの SavedModel は再調整のより進んだケースに対応するために plain __call__ よりも 多くの詳細 を提供します。TensorFlow は再調整の目的のために共有される SavedModel で、もし適用可能であれば、それらの以下を提供することを推奨します :
- モデルが (バッチ正規化のように) forward パスが訓練と推論で異なるような dropout か他のテクニックを利用する場合、__call__ メソッドはオプションの、Python-値の training= 引数を取ります、これは False がデフォルトですが True に設定できます。
- __call__ 属性の次に、対応する変数のリストを持つ .variable と .trainable_variable 属性があります。元々は訓練可能で再調整の間には凍結されることを意図した変数は .trainable_variables から除外されます。
- 重み regularizer を層かサブモジュールの属性として表す Keras のようなフレームワークのために、.regularization_losses 属性もあり得ます。それは zero-argument 関数 (訳注: 引数を持たない関数) のリストを保持し、その後は合計損失への加算を意図しています。
最初の MobileNet サンプルに戻って、それらの幾つかを実際に見ることができます :
loaded = tf.saved_model.load(mobilenet_save_path) print("MobileNet has {} trainable variables: {}, ...".format( len(loaded.trainable_variables), ", ".join([v.name for v in loaded.trainable_variables[:5]])))
MobileNet has 83 trainable variables: conv1/kernel:0, conv1_bn/gamma:0, conv1_bn/beta:0, conv_dw_1/depthwise_kernel:0, conv_dw_1_bn/gamma:0, ...
trainable_variable_ids = {id(v) for v in loaded.trainable_variables} non_trainable_variables = [v for v in loaded.variables if id(v) not in trainable_variable_ids] print("MobileNet also has {} non-trainable variables: {}, ...".format( len(non_trainable_variables), ", ".join([v.name for v in non_trainable_variables[:3]])))
MobileNet also has 54 non-trainable variables: conv1_bn/moving_mean:0, conv1_bn/moving_variance:0, conv_dw_1_bn/moving_mean:0, ...
エクスポートの間にシグネチャを指定する
TensorFlow Serving と saved_model_cli のようなツールは SavedModel と相互作用できます。これらのツールがどの ConcreteFunction を使用するかを決定することを助けるために、サービング・シグネチャを指定する必要があります。 tf.keras.Model はシグネチャを自動的に指定しますが、私達のカスタム・モジュールのためにサービング・シグネチャを明示的に宣言しなければなりません。
デフォルトでは、シグネチャはカスタム tf.Module 内では宣言されません。
assert len(imported.signatures) == 0
サービング・シグネチャを宣言するため、signatures kwarg を使用して ConcreteFunction を指定します。単一のシグネチャを指定するとき、そのシグネチャ・キーは ‘serving_default’ です、これは定数 tf.saved_model.DEFAULT_SERVING_SIGNATURE_DEF_KEY としてセーブされます。
module_with_signature_path = os.path.join(tmpdir, 'module_with_signature') call = module.__call__.get_concrete_function(tf.TensorSpec(None, tf.float32)) tf.saved_model.save(module, module_with_signature_path, signatures=call)
Tracing with Tensor("x:0", dtype=float32) Tracing with Tensor("x:0", dtype=float32) INFO:tensorflow:Assets written to: /tmp/tmpineuv5tu/module_with_signature/assets
imported_with_signatures = tf.saved_model.load(module_with_signature_path) list(imported_with_signatures.signatures.keys())
['serving_default']
複数のシグネチャをエクスポートするには、シグネチャ・キーの辞書を ConcreteFunction に渡します。各シグネチャ・キーは一つの ConcreteFunction に対応します。
module_multiple_signatures_path = os.path.join(tmpdir, 'module_with_multiple_signatures') signatures = {"serving_default": call, "array_input": module.__call__.get_concrete_function(tf.TensorSpec([None], tf.float32))} tf.saved_model.save(module, module_multiple_signatures_path, signatures=signatures)
Tracing with Tensor("x:0", shape=(None,), dtype=float32) Tracing with Tensor("x:0", shape=(None,), dtype=float32) INFO:tensorflow:Assets written to: /tmp/tmpineuv5tu/module_with_multiple_signatures/assets
imported_with_multiple_signatures = tf.saved_model.load(module_multiple_signatures_path) list(imported_with_multiple_signatures.signatures.keys())
['serving_default', 'array_input']
デフォルトでは、出力 tensor 名は output_0 のように、正しく包括的です。出力名を制御するには、貴方の tf.function を出力名を出力にマップする辞書を返すように変更します。入力名は Python 関数 arg 名に由来します。
class CustomModuleWithOutputName(tf.Module): def __init__(self): super(CustomModuleWithOutputName, self).__init__() self.v = tf.Variable(1.) @tf.function(input_signature=[tf.TensorSpec([], tf.float32)]) def __call__(self, x): return {'custom_output_name': x * self.v} module_output = CustomModuleWithOutputName() call_output = module_output.__call__.get_concrete_function(tf.TensorSpec(None, tf.float32)) module_output_path = os.path.join(tmpdir, 'module_with_output_name') tf.saved_model.save(module_output, module_output_path, signatures={'serving_default': call_output})
INFO:tensorflow:Assets written to: /tmp/tmpineuv5tu/module_with_output_name/assets
imported_with_output_name = tf.saved_model.load(module_output_path) imported_with_output_name.signatures['serving_default'].structured_outputs
{'custom_output_name': TensorSpec(shape=(), dtype=tf.float32, name='custom_output_name')}
C++ で SavedModel をロードする
SavedModel ローダ の C++ バージョンは SessionOptions と RunOptions を許容しながら、パスから SavedModel をロードするための API を提供します。ロードされるグラフに関連するタグを指定しなければなりません。SavedModel のロードされたバージョンは SavedModelBundle として参照されてそれがロードされたものの内で MetaGraphDef とセッションを含みます。
const string export_dir = ... SavedModelBundle bundle; ... LoadSavedModel(session_options, run_options, export_dir, {kSavedModelTagTrain}, &bundle);
SavedModel コマンドライン・インターフェイスの詳細
SavedModel を調査して実行するために SavedModel コマンドライン・インターフェイス (CLI) を利用できます。例えば、モデルの SignatureDef を調べるために 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 上で以下の 2 つのコマンドをサポートします :
- show, これは SavedModel から利用可能な計算を示します。
- run, これは SavedModel から計算を実行します。
show コマンド
SavedModel は一つまたはそれ以上のモデル・バージョン (= variants) (技術的には、v1.MetaGraphDef) を含みます、(それらは) それらのタグ・セットで識別されます。モデルをサーブするため、各モデルバージョンにどの種類の SignatureDef がありそしてそれらの入力と出力が何かを知りたいと思うかもしれません。show コマンドは階層順序にある SavedModel の内容を貴方に調べさせます。ここにシンタックスがあります :
usage: saved_model_cli show [-h] --dir DIR [--all] [--tag_set TAG_SET] [--signature_def SIGNATURE_DEF_KEY]
例えば、次のコマンドは SavedModel の総ての利用可能なタグセットを示します :
$ saved_model_cli show --dir /tmp/saved_model_dir The given SavedModel contains the following tag-sets: serve serve, gpu
次のコマンドはタグセットのための総ての利用可能な 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"
タグセットに複数のタグがある場合、総てのタグを指定しなければなりません、各タグはカンマで分離されます。例えば :
$ 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 オプションを指定します。これは手近にデータファイルを持たないときに、依然として (モデルの SignatureDef の dtype と shape に一致する) 幾つかの単純な入力でモデルをサニティ・チェックすることを望むときのために有用であり得ます。例えば :
`<input_key>=[[1],[2],[3]]`
Python 式に加えて、numpy 関数を渡しても良いです。例えば :
`<input_key>=np.ones((32,32,3))`
–input_examples
入力として tf.train.Example を渡すためには、–input_examples オプションを指定します。各入力キーについて、それは辞書のリストを取ります、そこでは各辞書は tf.train.Examples のインスタンスです。辞書キーは特徴で値は各特徴に対する値リストです。例えば :
`<input_key>=[{"age":[22,24],"education":["BS","MS"]}]`
Save output
デフォルトでは、SavedModel CLI は出力を stdout に書きます。ディレクトリが –outdir オプションに渡される場合、出力は与えられたディレクトリ下で出力 tensor キーにちなんで名前付けられた .npy ファイルとしてセーブされます。
既存の出力ファイルに上書きするためには –overwrite を使用します。
以上