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

尼克·格雷格

我试图将编码的字节字符串转换回张量流图中的原始数组(使用张量流操作),以便在张量流模型中进行预测。数组到字节的转换基于此答案,它是在Google Cloud的ml-engine上进行张量流模型预测的建议输入。

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,但均未返回原始值。

我尝试将原始解码的out_type设置为其他可能的数据类型,并尝试更改将原始数组转换为哪种数据类型。

那么,我将如何在tensorflow中读取字节数组?谢谢 :)

额外的信息

其背后的目的是为自定义估算器创建服务输入函数,以便使用gcloud ml-engine本地预测(用于测试)并对存储在云中的模型使用REST API进行预测。

估算器的服务输入函数为

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)

杰森的要求

我使用.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预测不会自动处理音频字节和base64转换?或我的估算器设置可能有问题。

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)]]")'}

这让我感到困惑,因为我将请求明确定义为float并在服务输入接收器中执行了同样的操作。

从请求中删除audio_bytes并对字节字符串进行utf-8编码可以使我得到预测,尽管在本地测试解码时,我认为音频是从字节字符串中错误转换的。

rhaertel80

假设您正在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)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何从bash将base64 utf-8编码的字符串转换为二进制文件?

如何将二进制字符串的字符串表示形式从文本文件转换回它来自的utf8编码文本?

如何解密以base64编码的shaX二进制字符串?

使用外部文件中的二进制数据(utf-8中的字符串)

如何测试二进制字符串是否有效的UTF8?

如何拆分(以特定的二进制值包含二进制的字符串?

减少用于二进制比较的 UTF-8 字符串

如何从二进制字符串创建PDF?

在字符串中翻转二进制

从字符串中获取二进制数据

从二进制字符串中获取模式

JavaScript中的二进制到字符串

Python中字符串的二进制移位

从字符串中写入二进制数据

替换二进制文件中的字符串

读取二进制字符串,用作二进制字符串python

如何在 Python 中读取二进制字符串

如何将我的json字符串进行avro二进制编码为字节数组?

NodeJS:如何将base64编码的字符串解码回二进制?

如何在Java中将二进制字符串转换为UTF-8字符串?

在Javascript中,如何解码字符串中包含二进制(例如非UTF-8)数据的字符串?

如何在 python 中将包含超出范围 utf-8 或 16 的字符的 unicode 字符串转换为二进制或十六进制?

如何将二进制字符串的文字字符串表示形式转换为二进制字符串?

如何将此二进制字符串转换为普通字符串?

将二进制字符串转换为JavaScript中的字符串

如何从二进制文件中读取以nul结尾的字符串

如何从Java中的标准输入读取python二进制字符串

关闭程序后如何从二进制文件中读取字符串

如何在Java中检查字符串是否为二进制