此页面由 Cloud Translation API 翻译。
Switch to English

使用SavedModel格式

查看上TensorFlow.org GitHub上查看源代码 下载笔记本

一个SavedModel包含完整TensorFlow方案,包括权重和计算。它不需要原来的建筑模型代码运行,这使得它成为共享或部署有用的(与TFLiteTensorFlow.jsTensorFlow服务 ,或TensorFlow集线器 )。

本文档潜入一些如何使用低级别的细节tf.saved_model API:

从创建一个Keras SavedModel

对于一个快速介绍,这部分出口预先训练Keras模型和它提供的图像分类请求。该指南的其余部分将填写详细信息并讨论其他的方法来创建SavedModels。

 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')
if physical_devices:
  tf.config.experimental.set_memory_growth(physical_devices[0], 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

PNG

我们将使用格雷斯料斗的图像作为一个正在运行的例子,和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 [==============================] - 1s 0us/step
Result before saving:
 ['military uniform' 'bow tie' 'suit' 'bearskin' 'pickelhaube']

此图像的顶部的预测是“军装”。

 mobilenet_save_path = os.path.join(tmpdir, "mobilenet/1/")
tf.saved_model.save(pretrained_model, mobilenet_save_path)
 
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/ops/resource_variable_ops.py:1817: calling BaseResourceVariable.__init__ (from tensorflow.python.ops.resource_variable_ops) with constraint is deprecated and will be removed in a future version.
Instructions for updating:
If using Keras pass *_constraint arguments to layers.
INFO:tensorflow:Assets written to: /tmp/tmpmjpd1j0o/mobilenet/1/assets

保存路径遵循TensorFlow使用的常规服务,其中最后一个路径组件( 1/这里)是你的模型版本号-它可以让工具,如Tensorflow服务,以推理的相对新鲜。

我们可以加载SavedModel回用Python tf.saved_model.load看看海军上将Hopper的形象是如何分类。

 loaded = tf.saved_model.load(mobilenet_save_path)
print(list(loaded.signatures.keys()))  # ["serving_default"]
 
['serving_default']

进口签名总是返回字典。要自定义签名的名称和输出字典键,请参阅导出过程中指定的签名

 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服SavedModel

SavedModels是可用在Python(更多的下面),但生产环境通常使用的专用服务用于推理不运行Python代码。这是很容易使用TensorFlow服务一个SavedModel成立。

TensorFlow服务REST教程有关的服务,包括安装说明的更多细节tensorflow_model_server在笔记本或在本地计算机上。作为一个速写,服务mobilenet上面导出只是点在SavedModel目录型号服务器型号:

 nohup tensorflow_model_server \
  --rest_api_port=8501 \
  --model_name=mobilenet \
  --model_base_path="/tmp/mobilenet" >server.log 2>&1
 

然后发送一个请求。

 !pip install -q requests
import json
import numpy
import requests
data = json.dumps({"signature_name": "serving_default",
                   "instances": x.tolist()})
headers = {"content-type": "application/json"}
json_response = requests.post('http://localhost:8501/v1/models/mobilenet:predict',
                              data=data, headers=headers)
predictions = numpy.array(json.loads(json_response.text)["predictions"])
 

将所得predictions是相同的在Python结果。

磁盘上的SavedModel格式

甲SavedModel是含有序列化签字和状态来运行它们所需的,包括可变值和词汇的目录。

ls {mobilenet_save_path}
assets  saved_model.pb  variables

所述saved_model.pb文件存储实际TensorFlow程序,或模型,以及一组命名的签名,每个识别接受张量输入,并产生张量输出的功能。

SavedModels可能包含模型的多个变体(多v1.MetaGraphDefs ,与识别--tag_set标志saved_model_cli ),但这是罕见的。其创建模型的多个变体的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-00002  variables.data-00001-of-00002  variables.index

assets目录包含TensorFlow图中使用文件,用来初始化词汇表例如文本文件。正是在这个例子中未被使用。

SavedModels可能有assets.extra对于不使用TensorFlow图中的任何文件的目录,对于消费者了解如何处理SavedModel做例子的信息。 TensorFlow本身不使用此目录。

保存自定义模型

tf.saved_model.save支持节能tf.Module对象和它的子类,像tf.keras.Layertf.keras.Model

让我们看一下保存和恢复的例子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 -decorated方法和tf.Module通过递归遍历发现s的保存。 (请参见检查点教程对于更多关于这个递归遍历。)但是,任何的Python属性,功能和数据都将丢失。这意味着,当一个tf.function保存,没有Python代码被保存。

如果没有Python代码保存,如何SavedModel知道如何恢复功能?

简言之, tf.function作品通过跟踪Python代码以产生ConcreteFunction(围绕一个可调用包装tf.Graph )。当保存tf.function ,你真的保存tf.function ConcreteFunctions的的缓存。

要了解更多有关之间的关系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/tmpmjpd1j0o/module_no_signatures/assets

加载和使用自定义模型

当加载SavedModel在Python中,所有tf.Variable属性, tf.function -decorated方法和tf.Module s的在同一个对象的结构恢复为原来保存的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'),), {})].

基本微调

可变对象是可用的,并且我们可以通过导入函数backprop。这足以微调(即重排序)在简单的情况下,SavedModel。

 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提供更多的细节比一个普通__call__解决微调的更加先进的案件。 TensorFlow集线器建议提供者的下面,如果适用的话,在用于微调的目的共享SavedModels:

  • 如果模型的用途脱落或另一技术,其中训练和推理(如批标准化)之间的直传不同的,那么__call__方法有一个可选的,Python的值training=论点,即默认为False但是可以被设置为True
  • 旁边的__call__属性,也有.variable.trainable_variable与变量对应的列表属性。这本来是训练的。应该是微调过程中被冻结的变量是从省略.trainable_variables
  • 对于像Keras表示重量regularizers为层或子模型的属性框架的缘故,还可以有一个.regularization_losses属性。它持有的零参数的功能,其值意味着除了总损失清单。

让我们回到最初的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工具服务和saved_model_cli可以SavedModels互动。为了帮助这些工具确定哪些ConcreteFunctions使用,我们需要指定服务的签名。 tf.keras.Model S也可以自动指定服务的签名,但我们必须显式声明的签名服务为我们的自定义模块。

默认情况下,没有签名的自定义声明tf.Module

 assert len(imported.signatures) == 0
 

要声明一个服务签名,指定使用一个ConcreteFunction signatures kwarg。当指定一个单一的签名,其签名密钥将是'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/tmpmjpd1j0o/module_with_signature/assets

 imported_with_signatures = tf.saved_model.load(module_with_signature_path)
list(imported_with_signatures.signatures.keys())

 
['serving_default']

要导出多个签名,通过签名密钥来ConcreteFunctions字典。每个签名密钥对应于一个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/tmpmjpd1j0o/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']

默认情况下,输出张名是相当通用的,像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/tmpmjpd1j0o/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')}

从估计SavedModels

估计通过出口SavedModels tf.Estimator.export_saved_model 。见指南估计为细节。

 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]))
estimator_base_path = os.path.join(tmpdir, 'from_estimator')
estimator_path = estimator.export_saved_model(estimator_base_path, serving_input_fn)
 
INFO:tensorflow:Using default config.
WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmp65c02lsq
INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmp65c02lsq', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true
graph_options {
  rewrite_options {
    meta_optimizer_iterations: ONE
  }
}
, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_experimental_max_worker_delay_secs': None, '_session_creation_timeout_secs': 7200, '_service': None, '_cluster_spec': ClusterSpec({}), '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/training/training_util.py:236: 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.
INFO:tensorflow:Calling model_fn.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/feature_column/feature_column_v2.py:540: Layer.add_variable (from tensorflow.python.keras.engine.base_layer_v1) is deprecated and will be removed in a future version.
Instructions for updating:
Please use `layer.add_weight` method instead.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/optimizer_v2/ftrl.py:144: calling Constant.__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
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 0...
INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmp65c02lsq/model.ckpt.
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...
INFO:tensorflow:loss = 0.6931472, step = 0
INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 50...
INFO:tensorflow:Saving checkpoints for 50 into /tmp/tmp65c02lsq/model.ckpt.
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 50...
INFO:tensorflow:Loss for final step: 0.4131384.
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/saved_model/signature_def_utils_impl.py:145: 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.
INFO:tensorflow:Signatures INCLUDED in export for Classify: ['serving_default', 'classification']
INFO:tensorflow:Signatures INCLUDED in export for Regress: ['regression']
INFO:tensorflow:Signatures INCLUDED in export for Predict: ['predict']
INFO:tensorflow:Signatures INCLUDED in export for Train: None
INFO:tensorflow:Signatures INCLUDED in export for Eval: None
INFO:tensorflow:Restoring parameters from /tmp/tmp65c02lsq/model.ckpt-50
INFO:tensorflow:Assets added to graph.
INFO:tensorflow:No assets to write.
INFO:tensorflow:SavedModel written to: /tmp/tmpmjpd1j0o/from_estimator/temp-1594862628/saved_model.pb

此SavedModel接受序列tf.Example协议缓冲剂,其对于提供有用的。但是,我们也可以加载它tf.saved_model.load和Python的运行。

 imported = tf.saved_model.load(estimator_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))
 
{'all_classes': <tf.Tensor: shape=(1, 2), dtype=string, numpy=array([[b'0', b'1']], dtype=object)>, 'logistic': <tf.Tensor: shape=(1, 1), dtype=float32, numpy=array([[0.5451435]], dtype=float32)>, 'probabilities': <tf.Tensor: shape=(1, 2), dtype=float32, numpy=array([[0.45485654, 0.5451435 ]], dtype=float32)>, 'logits': <tf.Tensor: shape=(1, 1), dtype=float32, numpy=array([[0.18106687]], dtype=float32)>, 'class_ids': <tf.Tensor: shape=(1, 1), dtype=int64, numpy=array([[1]])>, 'classes': <tf.Tensor: shape=(1, 1), dtype=string, numpy=array([[b'1']], dtype=object)>, 'all_class_ids': <tf.Tensor: shape=(1, 2), dtype=int32, numpy=array([[0, 1]], dtype=int32)>}
{'all_classes': <tf.Tensor: shape=(1, 2), dtype=string, numpy=array([[b'0', b'1']], dtype=object)>, 'logistic': <tf.Tensor: shape=(1, 1), dtype=float32, numpy=array([[0.21604054]], dtype=float32)>, 'probabilities': <tf.Tensor: shape=(1, 2), dtype=float32, numpy=array([[0.7839595 , 0.21604055]], dtype=float32)>, 'logits': <tf.Tensor: shape=(1, 1), dtype=float32, numpy=array([[-1.2888912]], dtype=float32)>, 'class_ids': <tf.Tensor: shape=(1, 1), dtype=int64, numpy=array([[0]])>, 'classes': <tf.Tensor: shape=(1, 1), dtype=string, numpy=array([[b'0']], dtype=object)>, 'all_class_ids': <tf.Tensor: shape=(1, 2), dtype=int32, numpy=array([[0, 1]], dtype=int32)>}

tf.estimator.export.build_raw_serving_input_receiver_fn允许您创建其采取原张量,而不是输入功能tf.train.Example秒。

加载SavedModel在C ++中

所述SavedModel的C ++版本加载器提供了一个API以从路径加载SavedModel,同时允许SessionOptions和RunOptions。你必须用指定要加载的图形相关联的标签。 SavedModel的负载版本被称为SavedModelBundle并包含MetaGraphDef和在其中它被加载的会话。

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

在SavedModel命令行界面的详细信息

您可以使用SavedModel命令行界面(CLI)检查和执行SavedModel。例如,你可以使用命令行来检查模型的SignatureDef秒。 CLI允许您快速确认输入张量D型和形状匹配模型。此外,如果你想测试你的模型,你可以使用CLI通过在各种格式样本通过输入(例如,Python表达式),然后获取输出做了仔细的检查。

安装SavedModel CLI

从广义上讲,您可以在以下任一两种方式安装TensorFlow:

  • 通过安装预建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以下两个命令:

  • show ,可从一个SavedModel其示出了计算。
  • run ,运行从SavedModel计算。

show命令

一个SavedModel包含一个或多个模型变量(在技术上, v1.MetaGraphDef S),由他们的标签集标识。为了服务模型,你可能想知道什么样的SignatureDef s在每一模型变的,什么是他们的投入和产出。该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

要显示所有的输入和输出TensorInfo特定SignatureDef ,通过在SignatureDef关键signature_def选项。当你想知道输入张量的张量键值,D类和形状后执行计算图,这是非常有用的。例如:

 $ 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命令提供了以下三种方式输入传递给模型:

  • --inputs选项可以通过numpy的ndarray在文件中。
  • --input_exprs选项,可以通过Python表达式。
  • --input_examples选项,可以通过tf.train.Example

--inputs

在文件传递的输入数据,指定--inputs选项,这需要的一般格式如下:

 --inputs <INPUTS>
 

其中INPUTS是以下格式之一:

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

您可以通过多种输入 。如果你通过多个输入,用分号来分隔各个输入

saved_model_cli用途numpy.load加载的文件名 。的文件名可以是任何的格式如下:

  • .npy
  • .npz
  • 咸菜格式

一个.npy文件总是包含一个numpy的ndarray。因此,当装载从.npy文件,内容将被直接分配给指定的输入张量。如果与指定变量名 .npy文件时, 变量名会被忽略,并且将发出警告。

当从装载.npz (ZIP)文件,则可以任选地指定变量名识别的zip文件内的变量加载用于将输入张量键。如果不指定变量名 ,将SavedModel CLI将检查只有一个文件包含在压缩文件并加载它指定的输入按键张。

当从泡菜文件加载,如果没有variable_name在方括号中指定,不管它是什么咸菜文件中会被传递到指定的输入键张。否则,SavedModel CLI将假定一个词典存储在泡菜文件和将被用于对应于该变量名的值。

--input_exprs

通过Python表达式输入,指定--input_exprs选项。这可能是因为当你没有数据文件躺在身边有用的,但还是要理智检查模型匹配的模型的D型和形状一些简单的输入SignatureDef秒。例如:

 `<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输出写入到标准输出。如果一个目录被传递给--outdir选项,输出将被保存为.npy指定目录下的输出张键命名的文件。

使用--overwrite覆盖现有的输出文件。