首页 > 解决方案 > 如何使用 Tensorflow Serving 和 Docker 为 Tensorflow 保存的模型创建 Post API 调用?

问题描述

我运行了示例教程(下面的链接),以使用基于 iris 数据集的本机 keras 创建 tfx 管道。我能够创建并保存一个 Tensorflow 模型。

https://github.com/tensorflow/tfx/blob/master/tfx/examples/iris/iris_pipeline_native_keras.py

我正在尝试使用与 Docker 一起服务的预测 API Tensorflow 来查询经过训练的模型。我无法弄清楚它的发布 API 请求。

我尝试了以下命令,但没有奏效。

curl -d '{"instances": [7.7,3.0,6.1,2.3]}' \
    -X POST http://localhost:8501/v1/models/iris_example:predict

模型的元数据如下

{
    "model_spec": {
        "name": "iris_cpu",
        "signature_name": "",
        "version": "1595575737"
    },
    "metadata": {
        "signature_def": {
            "signature_def": {
                "serving_default": {
                    "inputs": {
                        "examples": {
                            "dtype": "DT_STRING",
                            "tensor_shape": {
                                "dim": [],
                                "unknown_rank": true
                            },
                            "name": "serving_default_examples:0"
                        }
                    },
                    "outputs": {
                        "output_0": {
                            "dtype": "DT_FLOAT",
                            "tensor_shape": {
                                "dim": [
                                    {
                                        "size": "-1",
                                        "name": ""
                                    },
                                    {
                                        "size": "3",
                                        "name": ""
                                    }
                                ],
                                "unknown_rank": false
                            },
                            "name": "StatefulPartitionedCall:0"
                        }
                    },
                    "method_name": "tensorflow/serving/predict"
                },
                "__saved_model_init_op": {
                    "inputs": {},
                    "outputs": {
                        "__saved_model_init_op": {
                            "dtype": "DT_INVALID",
                            "tensor_shape": {
                                "dim": [],
                                "unknown_rank": true
                            },
                            "name": "NoOp"
                        }
                    },
                    "method_name": ""
                }
            }
        }
    }
}

运行 saved_model_cli 命令的输出

!saved_model_cli show --dir {export_path} --all

输出:

MetaGraphDef with tag-set: 'serve' contains the following SignatureDefs:

signature_def['__saved_model_init_op']:
  The given SavedModel SignatureDef contains the following input(s):
  The given SavedModel SignatureDef contains the following output(s):
    outputs['__saved_model_init_op'] tensor_info:
        dtype: DT_INVALID
        shape: unknown_rank
        name: NoOp
  Method name is: 

signature_def['serving_default']:
  The given SavedModel SignatureDef contains the following input(s):
    inputs['examples'] tensor_info:
        dtype: DT_STRING
        shape: (-1)
        name: serving_default_examples:0
  The given SavedModel SignatureDef contains the following output(s):
    outputs['output_0'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, 3)
        name: StatefulPartitionedCall:0
  Method name is: tensorflow/serving/predict
WARNING:tensorflow:From /Library/Frameworks/Python.framework/Versions/3.6/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.
2020-07-24 13:41:05.819053: I tensorflow/core/platform/cpu_feature_guard.cc:143] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
2020-07-24 13:41:05.836906: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x7fac87ae5560 initialized for platform Host (this does not guarantee that XLA will be used). Devices:
2020-07-24 13:41:05.836934: I tensorflow/compiler/xla/service/service.cc:176]   StreamExecutor device (0): Host, Default Version

Defined Functions:
  Function Name: '__call__'
    Option #1
      Callable with:
        Argument #1
          DType: list
          Value: [TensorSpec(shape=(None, 1), dtype=tf.float32, name='sepal_length_xf'), TensorSpec(shape=(None, 1), dtype=tf.float32, name='sepal_width_xf'), TensorSpec(shape=(None, 1), dtype=tf.float32, name='petal_length_xf'), TensorSpec(shape=(None, 1), dtype=tf.float32, name='petal_width_xf')]
        Argument #2
          DType: bool
          Value: False
        Argument #3
          DType: NoneType
          Value: None
    Option #2
      Callable with:
        Argument #1
          DType: list
          Value: [TensorSpec(shape=(None, 1), dtype=tf.float32, name='inputs/0'), TensorSpec(shape=(None, 1), dtype=tf.float32, name='inputs/1'), TensorSpec(shape=(None, 1), dtype=tf.float32, name='inputs/2'), TensorSpec(shape=(None, 1), dtype=tf.float32, name='inputs/3')]
        Argument #2
          DType: bool
          Value: False
        Argument #3
          DType: NoneType
          Value: None
    Option #3
      Callable with:
        Argument #1
          DType: list
          Value: [TensorSpec(shape=(None, 1), dtype=tf.float32, name='sepal_length_xf'), TensorSpec(shape=(None, 1), dtype=tf.float32, name='sepal_width_xf'), TensorSpec(shape=(None, 1), dtype=tf.float32, name='petal_length_xf'), TensorSpec(shape=(None, 1), dtype=tf.float32, name='petal_width_xf')]
        Argument #2
          DType: bool
          Value: True
        Argument #3
          DType: NoneType
          Value: None
    Option #4
      Callable with:
        Argument #1
          DType: list
          Value: [TensorSpec(shape=(None, 1), dtype=tf.float32, name='inputs/0'), TensorSpec(shape=(None, 1), dtype=tf.float32, name='inputs/1'), TensorSpec(shape=(None, 1), dtype=tf.float32, name='inputs/2'), TensorSpec(shape=(None, 1), dtype=tf.float32, name='inputs/3')]
        Argument #2
          DType: bool
          Value: True
        Argument #3
          DType: NoneType
          Value: None

  Function Name: '_default_save_signature'
    Option #1
      Callable with:
        Argument #1
          DType: list
          Value: [TensorSpec(shape=(None, 1), dtype=tf.float32, name='sepal_length_xf'), TensorSpec(shape=(None, 1), dtype=tf.float32, name='sepal_width_xf'), TensorSpec(shape=(None, 1), dtype=tf.float32, name='petal_length_xf'), TensorSpec(shape=(None, 1), dtype=tf.float32, name='petal_width_xf')]

  Function Name: 'call_and_return_all_conditional_losses'
    Option #1
      Callable with:
        Argument #1
          DType: list
          Value: [TensorSpec(shape=(None, 1), dtype=tf.float32, name='inputs/0'), TensorSpec(shape=(None, 1), dtype=tf.float32, name='inputs/1'), TensorSpec(shape=(None, 1), dtype=tf.float32, name='inputs/2'), TensorSpec(shape=(None, 1), dtype=tf.float32, name='inputs/3')]
        Argument #2
          DType: bool
          Value: True
        Argument #3
          DType: NoneType
          Value: None
    Option #2
      Callable with:
        Argument #1
          DType: list
          Value: [TensorSpec(shape=(None, 1), dtype=tf.float32, name='sepal_length_xf'), TensorSpec(shape=(None, 1), dtype=tf.float32, name='sepal_width_xf'), TensorSpec(shape=(None, 1), dtype=tf.float32, name='petal_length_xf'), TensorSpec(shape=(None, 1), dtype=tf.float32, name='petal_width_xf')]
        Argument #2
          DType: bool
          Value: False
        Argument #3
          DType: NoneType
          Value: None
    Option #3
      Callable with:
        Argument #1
          DType: list
          Value: [TensorSpec(shape=(None, 1), dtype=tf.float32, name='sepal_length_xf'), TensorSpec(shape=(None, 1), dtype=tf.float32, name='sepal_width_xf'), TensorSpec(shape=(None, 1), dtype=tf.float32, name='petal_length_xf'), TensorSpec(shape=(None, 1), dtype=tf.float32, name='petal_width_xf')]
        Argument #2
          DType: bool
          Value: True
        Argument #3
          DType: NoneType
          Value: None
    Option #4
      Callable with:
        Argument #1
          DType: list
          Value: [TensorSpec(shape=(None, 1), dtype=tf.float32, name='inputs/0'), TensorSpec(shape=(None, 1), dtype=tf.float32, name='inputs/1'), TensorSpec(shape=(None, 1), dtype=tf.float32, name='inputs/2'), TensorSpec(shape=(None, 1), dtype=tf.float32, name='inputs/3')]
        Argument #2
          DType: bool
          Value: False
        Argument #3
          DType: NoneType
          Value: None
!saved_model_cli show --dir {export_path} --tag_set serve --signature_def serving_default

输出:

The given SavedModel SignatureDef contains the following input(s):
  inputs['examples'] tensor_info:
      dtype: DT_STRING
      shape: (-1)
      name: serving_default_examples:0
The given SavedModel SignatureDef contains the following output(s):
  outputs['output_0'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1, 3)
      name: StatefulPartitionedCall:0
Method name is: tensorflow/serving/predict

从该模型中获取预测的正确 POST API 调用是什么?

先感谢您

标签: dockerkerastensorflow-servingtfx

解决方案


推荐阅读