【问题标题】:TensorFlow Serving: Pass image to classifierTensorFlow Serving:将图像传递给分类器
【发布时间】:2018-07-31 08:05:25
【问题描述】:

我在 Tensorflow(Python、tensorflow 1.9.0 和 tensorflow-serving 1.9.0)中构建了一个简单的分类器,它将对象分类为 5 个类之一。现在,我想为那个模型服务。我已经导出它并给它一个分类签名(并且只有一个分类签名):

classification_signature = tf.saved_model.signature_def_utils.build_signature_def(
    inputs={signature_constants.CLASSIFY_INPUTS: classification_inputs},
    outputs={
        signature_constants.CLASSIFY_OUTPUT_CLASSES:
            classification_outputs_classes
    },
    method_name=signature_constants.CLASSIFY_METHOD_NAME)

接下来会变成:

builder.add_meta_graph_and_variables(
            sess, [tag_constants.SERVING],
            signature_def_map={
                'classification_results':
                    classification_signature
            },
            clear_devices=True, legacy_init_op=legacy_init_op)

当我启动 TF 服务器时,我可以看到正在为模型提供服务。我的问题是如何将图像传递给来自客户端的图像。代码如下:

request = classification_pb2.ClassificationRequest()
request.model_spec.name = model
request.model_spec.signature_name = 'classification_results' 

这就是我有点迷茫和困惑的地方。对于 PredictionRequest,代码为:

request.inputs['inputs'].CopyFrom(
    tf.contrib.util.make_tensor_proto(image.astype(dtype=np.uint8), shape=[1, height, width, 3]))

但这不适用于分类请求。错误是:

File "TestServices.py", line 99, in make_request
  request.inputs['inputs'].CopyFrom(
     AttributeError: 'ClassificationRequest' object has no attribute 'inputs'

也没有:

request.input.CopyFrom(input_pb2.Input(
    tf.contrib.util.make_tensor_proto(image.astype(dtype=np.uint8), shape=[1, height, width, 3])
    )
)

给出错误:

File "TestServices.py", line 102, in make_request
  tf.contrib.util.make_tensor_proto(image.astype(dtype=np.uint8), shape=[1,height, width, 3])
    TypeError: Parameter to CopyFrom() must be instance of same class: 
    expected tensorflow.serving.Input got tensorflow.TensorProto.

因此,我的问题是:我需要做什么才能使用 ClassificationRequest 将图像传递给分类器?

【问题讨论】:

  • 你有错误信息吗?
  • 更新了帖子。将事物传递给预测和分类的方式似乎存在一些根本区别。

标签: python tensorflow tensorflow-serving


【解决方案1】:

我不确定这是否符合最佳做法,但这似乎可行。作为一个纯 python 用户,我不得不说这感觉就像是骗人的。我花了一段时间,但我通过查看 protobuf 文件的 definition 和这个 documentation 弄清楚了。

import tensorflow as tf
import numpy as np
from tensorflow_serving.apis import classification_pb2, input_pb2
image = np.random.rand(1, 32,32,3)

def _bytes_feature(value):
    return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))

request = classification_pb2.ClassificationRequest()
request.model_spec.name = 'model'
request.model_spec.signature_name = 'classification_results' 

# Wrap numpy image in an example protobuf
example = tf.train.Example(features=tf.train.Features(feature={'image': _bytes_feature(image.tostring())}))

inp = input_pb2.Input()
inp.example_list.examples.extend([example])

request.input.CopyFrom(inp)

【讨论】:

  • 我希望避免上述情况(已经在几个地方看到过),就像你说的那样,这(对我来说)是黑箱废话。但我会试一试,然后再回来检查答案。
  • 我会说它有效 - 大多数情况下。问题是“字节”调用将所有内容都转换为字符串,并且模型需要浮点数。你找到解决方法了吗?
  • 这取决于你如何训练你的模型。我的猜测是将tf.train.BytesListtf.train.FloatList 交换并通过image 而不是image.tostring()
  • 是的,我试过了,但现在 TF serve 抱怨它得到的是字符串输入而不是浮点数。我不明白,但这并不能改变您的回答有很大帮助的事实。谢谢。
  • 我喜欢 saved_model_cli 快速检查已保存模型的输入和输出规格。也许你可以试试:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多