tf.image.decode_jpeg文件内容必须是标量,获得形状[1]

2024-06-30 15:17:32 发布

您现在位置:Python中文网/ 问答频道 /正文

根据本教程,我已经构建了一个通过tensorflowservice进行图像分类的服务器/客户机演示 https://github.com/tmlabonte/tendies/blob/master/minimum_working_example/tendies-basic-tutorial.ipynb

客户

它接受一个图像作为输入,将其转换为Base64,并使用JSON将其传递给服务器

input_image = open(image, "rb").read()
print("Raw bitstring: " + str(input_image[:10]) + " ... " + str(input_image[-10:]))

# Encode image in b64
encoded_input_string = base64.b64encode(input_image)
input_string = encoded_input_string.decode("utf-8")
print("Base64 encoded string: " + input_string[:10] + " ... " + input_string[-10:])

# Wrap bitstring in JSON
instance = [{"images": input_string}]
data = json.dumps({"instances": instance})
print(data[:30] + " ... " + data[-10:])

r = requests.post('http://localhost:9000/v1/models/cnn:predict', data=data)
  #json.loads(r.content)
print(r.text)

服务器

一旦将模型加载为.h5,服务器必须另存为SavedModel。 映像必须作为Base64编码的字符串从客户端传递到服务器。在

^{pr2}$

然后输入的_字节成为SavedModel中predition_签名的输入

 tensor_info_x = tf.saved_model.utils.build_tensor_info(input_bytes)

最后,服务器的结果如下:

§ saved_model_cli show --dir ./ --all

signature_def['predict']:
  The given SavedModel SignatureDef contains the following input(s):
    inputs['images'] tensor_info:
        dtype: DT_STRING
        shape: ()
        name: input_bytes:0
  The given SavedModel SignatureDef contains the following output(s):
    outputs['scores'] tensor_info:
        dtype: DT_FLOAT
        shape: (1, 4)
        name: sequential_1/dense_2/Softmax:0
  Method name is: tensorflow/serving/predict

发送图像

当我发送映像base64时,我收到服务器关于输入形状的运行时错误,该错误似乎不是标量:

Using TensorFlow backend.
Raw bitstring: b'\xff\xd8\xff\xe0\x00\x10JFIF' ... b'0;s\xcfJ(\xa0h\xff\xd9'
Base64 encoded string: /9j/4AAQSk ... 9KKKBo/9k=
{"instances": [{"images": "/9j ... Bo/9k="}]}
{ "error": "contents must be scalar, got shape [1]\n\t [[{{node DecodeJpeg}} = DecodeJpeg[_output_shapes=[[?,?,3]], acceptable_fraction=1, channels=3, dct_method=\"\", fancy_upscaling=true, ratio=1, try_recover_truncated=false, _device=\"/job:localhost/replica:0/task:0/device:CPU:0\"](_arg_input_bytes_0_0)]]" }

正如您从服务器上看到的input_bytes是标量的shape=[],我也试图用tf.reshape(input_bytes, [])来重塑它,但是没有办法,我总是得到相同的错误。 我并没有找到任何解决办法在互联网和这里在Stackoverflow关于这个错误。你能建议一下怎么修吗? 谢谢!在


Tags: 图像imageinfo服务器inputdatastringbytes
1条回答
网友
1楼 · 发布于 2024-06-30 15:17:32

我解决了这个问题,我想谈谈如何让你受益的解决方案!在

当您发送这样的json时:

{"instances": [{"images": "/9j ... Bo/9k="}]}

实际上,您发送的是一个大小为1的数组 如果你想发送2个图像,你应该这样写

^{pr2}$

这里的大小是2(shape=[2])

所以解决方案是在占位符中声明接受shape=[None]的任何类型的大小

input_bytes = tf.placeholder(tf.string, shape=[None], name="input_bytes")

如果只发送1个图像,则矢量1可以通过以下方式转换为标量:

input_scalar = tf.reshape(input_bytes, [])

在我的代码中还有一个错误,我没有考虑到在tensorflow/serving中有一个通过在json中显式声明'b64'来解码base64的特性,请参考RESTful API Encoding binary values,因此如果您发送

{"instances": [{"images": {"b64": "/9j ... Bo/9k="}}]}

服务器将自动解码base64输入,正确的位流将到达tf.image.decode_jpeg文件在

相关问题 更多 >