Tensorflow Serving: InvalidArgumentError: Expected image (JPEG, PNG, or GIF), got unknown format starting with 'AAAAAAAAAAAAAAAA'

Tensorflow Serving: InvalidArgumentError: Expected image (JPEG, PNG, or GIF), got unknown format starting with 'AAAAAAAAAAAAAAAA'

我正在尝试准备我的自定义 Keras 模型以进行部署以与 Tensorflow Serving 一起使用,但我 运行 遇到了预处理图像的问题。

当我训练我的模型时,我使用以下函数来预处理我的图像:

def process_image_from_tf_example(self, image_str_tensor, n_channels=3):
    image = tf.image.decode_image(image_str_tensor)
    image.set_shape([256, 256, n_channels])
    image = tf.cast(image, tf.float32) / 255.0
    return image

def read_and_decode(self, serialized):
    parsed_example = tf.parse_single_example(serialized=serialized, features=self.features)
    input_image = self.process_image_from_tf_example(parsed_example["image_raw"], 3)
    ground_truth_image = self.process_image_from_tf_example(parsed_example["gt_image_raw"], 1)
    return input_image, ground_truth_image

我的图像是本地保存的 PNG,当我将它们写入我使用的 .tfrecord 文件时 tf.gfile.GFile(str(image_path), 'rb').read()

这有效,我能够训练我的模型并将其用于本地预测。

现在我想部署我的模型以与 Tensorflow Serving 一起使用。我的 serving_input_receiver_fn 函数如下所示:

def serving_input_receiver_fn(self):
    input_ph = tf.placeholder(dtype=tf.string, shape=[None], name='image_bytes')
    images_tensor = tf.map_fn(self.process_image_from_tf_example, input_ph, back_prop=False, dtype=tf.float32)
    return tf.estimator.export.ServingInputReceiver({'input_1': images_tensor}, {'image_bytes': input_ph})

其中 process_image_from_tf_example 与上面的功能相同,但出现以下错误:

InvalidArgumentError (see above for traceback): assertion failed: [Unable to decode bytes as JPEG, PNG, GIF, or BMP]

阅读 here 看起来这个错误是因为我没有使用 tf.gfile.GFile(str(image_path), 'rb').read()

与我的 training/test 文件一样,但我无法使用它,因为我需要发送格式化为

的编码字节

{"image_bytes": {'b64': base64.b64encode(image).decode()}}

根据 TF Serving 的要求。

Examples online 发送 JPEG 编码字节并对以

开头的图像进行预处理

tf.image.decode_jpeg(image_buffer, channels=3)

但是如果我在 serving_input_receiver_fn 中使用以

开头的不同预处理函数(不同于用于训练的函数)

tf.image.decode_png(image_buffer, channels=3)

我收到以下错误:

InvalidArgumentError (see above for traceback): Expected image (JPEG, PNG, or GIF), got unknown format starting with 'AAAAAAAAAAAAAAAA'

(顺便说一句,decode_jpeg也是如此)

我做错了什么?您需要我提供更多代码来回答吗?非常感谢!

编辑!! 标题不够清楚,改了

好的我解决了

image 是一个 numpy 数组,但我必须执行以下操作:

buffer = cv2.imencode('.jpg', image)[1].tostring()
bytes_image = base64.b64encode(buffer).decode('ascii')
{"image_bytes": {"b64": bytes_image}}

此外,我的预处理和 serving_input_receiver_fn 功能发生了变化:

def process_image_from_buffer(self, image_buffer):
    image = tf.image.decode_jpeg(image_buffer, channels=3)
    image = tf.image.convert_image_dtype(image, dtype=tf.float32)
    image = tf.expand_dims(image, 0)
    image = tf.image.resize_bilinear(image, [256, 256], align_corners=False)
    image = tf.squeeze(image, [0])
    image = tf.cast(image, tf.float32) / 255.0
    return image

def serving_input_receiver_fn(self):
    input_ph = tf.placeholder(dtype=tf.string, shape=[None])
    images_tensor = tf.map_fn(self.process_image_from_buffer, input_ph, back_prop=False, dtype=tf.float32)
    return tf.estimator.export.ServingInputReceiver({'input_1': images_tensor}, {'image_bytes': input_ph})

process_image_from_buffer 与上面用于训练的 process_image_from_tf_example 不同。 我还从上面的 input_ph 中删除了 name='image_bytes'

希望它足够清楚以帮助其他人。

Excellent guide partially used for solving it