首页 > 解决方案 > 使用 Tensorflow saved_model,得到 ValueError: Cannot feed value of shape () for Tensor 'Placeholder_1084:0', which has shape '(?,)'

问题描述

我正在使用 Tensorflow 1.14.0 并尝试编写一个 Python 脚本来加载使用 tf.compat.v1.saved_model.simple_save 保存的模型来处理磁盘中的图像。当我使用 Tensorflow Serving 和 GRPC 或 REST 客户端时,该模型运行良好。但是,当我尝试在单个脚本中使用它时,出现以下错误:

ValueError:无法为具有形状“(?,)”的张量“Placeholder_1084:0”提供形状()的值

我确定我有一些根本性的错误,但还没有弄清楚。我整理了一个简短的示例,说明了我要完成的工作:

#!/usr/bin/env python

import tensorflow as tf
from tensorflow.python.saved_model import tag_constants
from tensorflow.python.saved_model import signature_constants

savedModelPath = "./models/inception_v3/1/"
filename = "./imagenet/n02763714/image_0.jpg"

session = tf.compat.v1.Session(graph=tf.Graph())
with session.graph.as_default():
    model = tf.compat.v1.saved_model.load(export_dir=savedModelPath, sess=session, tags=[tag_constants.SERVING])

    model_def = model.signature_def[signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY]

    graph_def = tf.compat.v1.get_default_graph()
    input_tensor = graph_def.get_tensor_by_name(model_def.inputs["image_bytes"].name)
    output_tensor = graph_def.get_tensor_by_name(model_def.outputs["predictions"].name)

    image_data = tf.io.gfile.GFile(filename, 'rb').read()

    session.run(output_tensor, {input_tensor: image_data})

提前感谢您的帮助!

编辑:如果有帮助,这里是模型签名:

inputs {
  key: "image_bytes"
  value {
    name: "Placeholder_1084:0"
    dtype: DT_STRING
    tensor_shape {
      dim {
        size: -1
      }
    }
  }
}
outputs {
  key: "predictions"
  value {
    name: "inception_v3/predictions/Softmax:0"
    dtype: DT_FLOAT
    tensor_shape {
      dim {
        size: -1
      }
      dim {
        size: 1000
      }
    }
  }
}
method_name: "tensorflow/serving/predict"

标签: tensorflow

解决方案


您的模型需要一维输入,这就是形状的(?,)含义。据推测,在这个输入中,每个值都是编码图像的字节序列。在您的代码中,您似乎正在尝试使用该模型来获取单个图像的预测。当你这样做时:

image_data = tf.io.gfile.GFile(filename, 'rb').read()

您在 中得到一个bytesimage_data,从 TensorFlow 的角度来看,它是一个标量值(形状为 的值()),就像个人intfloat. 如果将该值作为具有该值的单元素列表提供,则可以使其工作,TensorFlow 将其解释为一维输入:

session.run(output_tensor, {input_tensor: [image_data]})

请注意,上面一行返回的值将(再次,大概)具有 shape (1, 1000)。然后可以将图像的预测输出向量提取为:

session.run(output_tensor, {input_tensor: [image_data]})[0]

推荐阅读