我试图将编码的字节字符串转换回张量流图中的原始数组(使用张量流操作),以便在张量流模型中进行预测。数组到字节的转换基于此答案,它是在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_raw和decode_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编码可以使我得到预测,尽管在本地测试解码时,我认为音频是从字节字符串中错误转换的。
假设您正在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] 删除。
我来说两句