¿Cómo leer una cadena binaria codificada utf-8 en tensorflow?
Estoy tratando de convertir una cadena de bytes codificada en la matriz original en el gráfico de tensorflow (usando operaciones de tensorflow) para hacer una predicción en un modelo de tensorflow. La conversión de matriz a byte se basa enesta respuesta y es la entrada sugerida para la predicción del modelo de tensorflow en el motor ml de google cloud.
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')}
Código de 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)
He intentado usardecode_raw ydecode_base64 pero ninguno devuelve los valores originales.
Intenté establecer el out_type de decodificación sin formato a los diferentes tipos de datos posibles y traté de alterar a qué tipo de datos estoy convirtiendo la matriz original.
Entonces, ¿cómo leería la matriz de bytes en Tensorflow? Gracias :)
Información extraEl objetivo detrás de esto es crear la función de entrada de servicio para un Estimador personalizado para hacer predicciones usando gcloud ml-engine local predict (para pruebas) y usando la API REST para el modelo almacenado en la nube.
La función de entrada de servicio para el Estimador es
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)
Solicitud de JsonUso .decode ('utf-8') porque cuando intento volcar json las cadenas de bytes codificadas en base64 recibo este error
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: b'longbytestring'
Errores de predicciónAl pasar la solicitud json {'audio_bytes': 'b64': bytestring} con gcloud local me sale el error
PredictionError: Invalid inputs: Expected tensor name: b64, got tensor name: [u'audio_bytes']
Entonces, ¿quizás la predicción local de Google Cloud no maneja automáticamente los bytes de audio y la conversión de base64? O probablemente hay algo mal con mi configuración de Estimator.
Y la solicitud {'instancias': [{'audio_bytes': 'b64': bytestring}]} a REST API da
{'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)]]")'}
lo que me confunde cuando defino explícitamente la solicitud para que sea flotante y haga lo mismo en el receptor de entrada de servicio.
La eliminación de audio_bytes de la solicitud y la codificación utf-8 de las cadenas de bytes me permite obtener predicciones, aunque al probar la decodificación localmente, creo que el audio se está convirtiendo incorrectamente desde la cadena de bytes.