tensorflow - 如何在 tensorflow 中读取 utf-8 编码的二进制字符串?

标签 tensorflow google-cloud-platform byte google-cloud-ml

我正在尝试将编码的字节字符串转换回 tensorflow 图中的原始数组(使用 tensorflow 操作),以便在 tensorflow 模型中进行预测。数组到字节的转换基于 this answer它是 google cloud 的 ml-engine 上 tensorflow 模型预测的建议输入。

def array_request_example(input_array):
    input_array = input_array.astype(np.float32)
    byte_string = input_array.tostring()
    string_encoded_contents = base64.b64encode(byte_string)
    return string_encoded_contents.decode('utf-8')}
Tensorflow 代码
byte_string = tf.placeholder(dtype=tf.string)
audio_samples = tf.decode_raw(byte_string, tf.float32)

audio_array = np.array([1, 2, 3, 4])
bstring = array_request_example(audio_array)
fdict = {byte_string: bstring}
with tf.Session() as sess:
    [tf_samples] = sess.run([audio_samples], feed_dict=fdict)
我试过使用 decode_rawdecode_base64但都不返回原始值。
我尝试将 decode raw 的 out_type 设置为不同的可能数据类型,并尝试更改我将原始数组转换为的数据类型。
那么,我将如何读取 tensorflow 中的字节数组?谢谢 :)
额外信息
这背后的目的是为自定义 Estimator 创建服务输入函数,以使用 gcloud ml-engine local predict(用于测试)并使用 REST API 对存储在云上的模型进行预测。
Estimator 的服务输入函数是
def serving_input_fn():
    feature_placeholders = {'b64': tf.placeholder(dtype=tf.string,
                                                  shape=[None],
                                                  name='source')}
    audio_samples = tf.decode_raw(feature_placeholders['b64'], tf.float32)
    # Dummy function to save space
    power_spectrogram = create_spectrogram_from_audio(audio_samples)
    inputs = {'spectrogram': power_spectrogram}
    return tf.estimator.export.ServingInputReceiver(inputs, feature_placeholders)
JSON 请求
我使用 .decode('utf-8') 因为在尝试 json 转储 base64 编码的字节字符串时,我收到此错误
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: b'longbytestring'
预测错误
使用 gcloud local 传递 json 请求 {'audio_bytes': 'b64': bytestring} 时出现错误
PredictionError: Invalid inputs: Expected tensor name: b64, got tensor name: [u'audio_bytes']
那么也许 google cloud local predict 不会自动处理音频字节和 base64 转换?或者我的 Estimator 设置可能有问题。
对 REST API 的请求 {'instances': [{'audio_bytes': 'b64': bytestring}]} 给出
{'error': 'Prediction failed: Error during model execution: AbortionError(code=StatusCode.INVALID_ARGUMENT, details="Input to DecodeRaw has length 793713 that is not a multiple of 4, the size of float\n\t [[Node: DecodeRaw = DecodeRaw[_output_shapes=[[?,?]], little_endian=true, out_type=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:CPU:0"](_arg_source_0_0)]]")'}
这让我感到困惑,因为我明确地将请求定义为浮点数并在服务输入接收器中执行相同操作。
从请求中删除 audio_bytes 和对字节字符串进行 utf-8 编码允许我获得预测,尽管在本地测试解码时,我认为音频是从字节字符串错误地转换的。

最佳答案

answer您引用的内容是假设您在 CloudML Engine 的服务上运行模型而编写的。该服务实际上负责处理 JSON(包括 UTF-8)和 base64 编码。

要让您的代码在本地或其他环境中工作,您需要进行以下更改:

def array_request_example(input_array):
    input_array = input_array.astype(np.float32)
    return input_array.tostring()

byte_string = tf.placeholder(dtype=tf.string)
audio_samples = tf.decode_raw(byte_string, tf.float32)

audio_array = np.array([1, 2, 3, 4])
bstring = array_request_example(audio_array)
fdict = {byte_string: bstring}
with tf.Session() as sess:
    tf_samples = sess.run([audio_samples], feed_dict=fdict)

也就是说,根据您的代码,我怀疑您希望将数据作为 JSON 发送;您可以使用 gcloud local predict模拟 CloudML Engine 的服务。或者,如果您更喜欢编写自己的代码,可能是这样的:
def array_request_examples,(input_arrays):
  """input_arrays is a list (batch) of np_arrays)"""
  input_arrays = (a.astype(np.float32) for a in input_arrays)
  # Convert each image to byte strings
  bytes_strings = (a.tostring() for a in input_arrays)
  # Base64 encode the data
  encoded = (base64.b64encode(b) for b in bytes_strings)
  # Create a list of images suitable to send to the service as JSON:
  instances = [{'audio_bytes': {'b64': e}} for e in encoded]
  # Create a JSON request
  return json.dumps({'instances': instances})

def parse_request(request):
  # non-TF to simulate the CloudML Service which does not expect
  # this to be in the submitted graphs.
  instances = json.loads(request)['instances']
  return [base64.b64decode(i['audio_bytes']['b64']) for i in instances]

byte_strings = tf.placeholder(dtype=tf.string, shape=[None])
decode = lambda raw_byte_str: tf.decode_raw(raw_byte_str, tf.float32)
audio_samples = tf.map_fn(decode, byte_strings, dtype=tf.float32)

audio_array = np.array([1, 2, 3, 4])
request = array_request_examples([audio_array])
fdict = {byte_strings: parse_request(request)}
with tf.Session() as sess:
  tf_samples = sess.run([audio_samples], feed_dict=fdict)

关于tensorflow - 如何在 tensorflow 中读取 utf-8 编码的二进制字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48911249/

相关文章:

python - 如何在 Tensorflow 中将小图像添加到大图像中?

docker - 无法将Docker镜像推送到gcr.io

nginx - Kubernetes pod 副本在同步内容方面的困惑

java - InputStream 读取源中不存在的额外字节

python - 不支持 ML Engine Runtime 版本和 Python 版本

python - 类型错误 : Variable to save is not a Variable

tensorflow - 名称 tf.Session 已弃用。请改用 tf.compat.v1.Session

google-cloud-datastore - Google Cloud 函数环境变量

c# - 在 C# 中将 ushort 值转换为两个字节值

c++ - 为什么 boolean 值是 1 字节而不是 1 位大小?