Невозможно преобразовать в тензорное прото: TypeError для tf.contrib.util.make_tensor_proto при отправке входного файла

1) Я написал простую программу, использующую тензорный поток для чтения текстового файла, и хотел развернуть ее на сервере с использованием тензорного потока. Это программа

tf.app.flags.DEFINE_integer('model_version', 2, 'version number of the model.')
tf.app.flags.DEFINE_string('work_dir', '', 'Working directory.')
FLAGS = tf.app.flags.FLAGS

sess = tf.InteractiveSession()
# define the tensorflow network and do some trains
x = tf.placeholder("string", name="x")

sess.run(tf.global_variables_initializer())
y = tf.read_file(x, name="y")


export_path_base = FLAGS.work_dir
export_path = os.path.join(tf.compat.as_bytes(export_path_base),
  tf.compat.as_bytes(str(FLAGS.model_version)))
print('Exporting trained model to', export_path)
builder = tf.saved_model.builder.SavedModelBuilder(export_path)

tensor_info_x = tf.saved_model.utils.build_tensor_info(x)
tensor_info_y = tf.saved_model.utils.build_tensor_info(y)

prediction_signature = (
  tf.saved_model.signature_def_utils.build_signature_def(
  inputs={'input': tensor_info_x},
  outputs={'output': tensor_info_y},
  method_name=tf.saved_model.signature_constants.PREDICT_METHOD_NAME))

legacy_init_op = tf.group(tf.tables_initializer(), name='legacy_init_op')

builder.add_meta_graph_and_variables(
  sess, [tf.saved_model.tag_constants.SERVING],
  signature_def_map={
  'prediction':
  prediction_signature,
  },
  legacy_init_op=legacy_init_op)

builder.save()

2) Я создал протобуф этой модели и заставил работать на сервере. Теперь я написал клиентскую программу для отправки входного текстового файла и производит вывод. Это простой клиентский файл для чтения

tf.app.flags.DEFINE_string('server', 'localhost:9000', 'PredictionService host:port')
tf.app.flags.DEFINE_string('input','','input for the model')
FLAGS = tf.app.flags.FLAGS

def do_inference(hostport,no):

  # create connection
  host, port = hostport.split(':')
  channel = implementations.insecure_channel(host, int(port))
  stub = prediction_service_pb2.beta_create_PredictionService_stub(channel)

  # initialize a request
  data = no
  request = predict_pb2.PredictRequest()
  request.model_spec.name = 'modelX'
  request.model_spec.signature_name = 'prediction'

  request.inputs['input'].CopyFrom(tf.contrib.util.make_tensor_proto(data))
  # predict
  result = stub.Predict(request, 5.0) # 5 seconds
  return result

def main(_):
    result = do_inference(FLAGS.server,FLAGS.input)
    print('Result is: ', result)


if __name__ == '__main__':
  tf.app.run()

Поэтому, когда я запускаю этот код,

python client.py --server = 172.17.0.2: 9000 --input = hello.txt

это производит вывод

*Hello!*

3) Теперь я написал файл клиента с фреймворком для создания REST API:

tf.app.flags.DEFINE_string('server', 'localhost:9000', 'PredictionService host:port')
FLAGS = tf.app.flags.FLAGS

app = Flask(__name__)

class mainSessRunning():

    def __init__(self):
        host, port = FLAGS.server.split(':')
        channel = implementations.insecure_channel(host, int(port))
        self.stub = prediction_service_pb2.beta_create_PredictionService_stub(channel)

        self.request = predict_pb2.PredictRequest()
        self.request.model_spec.name = 'modelX'
        self.request.model_spec.signature_name = 'prediction'

    def inference(self, val_x):
        data = val_x
        self.request.inputs['input'].CopyFrom(tf.contrib.util.make_tensor_proto(data))
        result = self.stub.Predict(self.request, 5.0)
        return result

run = mainSessRunning()

# Define a route for the default URL, which loads the form
@app.route('/pred', methods=['POST'])
def pred():
    request_data = request.files['file']
    result = run.inference(request_data)
    rs = json_format.MessageToJson(result)
    return jsonify({'result':rs})

Используя почтальон, когда я даю тот же входной файл 'hello.txt', он выдает ошибку:

Ошибка типа: не удалось преобразовать объект типа (class'werkzeug.datastructures.File.Storage') в тензор. Содержание: (Filestorage: u'hello.txt' ('text/plain')). Рассмотрим приведение элементов к поддерживаемому типу

Я уже разместил это здесь. Он работает нормально с обычным файлом client.py, но не работает client.py с фреймворком фляги. Я следовал за этим официальным документом в tenorflow. И найдено, что make_tensor_proto принимает "значения" скаляра Python, списка Python, Numpy ndarray или NumPy скаляра.

Итак, мой вопрос, как мне отправить это хранилище файлов werkzeug, которое будет принято в тензорном протоколе? или это ошибка?

1 ответ

Посмотрите на этот URL http://werkzeug.pocoo.org/docs/0.14/datastructures/

если я взгляну на "def inference", локальная переменная "data" будет содержать ссылку на объект типа "werkzeug.datastructures.FileStorage"

когда вы получаете какой-то файл из поста [посредством фляги], этот файл фактически оборачивается в объект "werkzeug.datastructures.FileStorage", поэтому "request.file" является не файлом, а объектом типа "werkzeug.datastructures".FileStorage "вы должны найти способ отследить основной файл.

если вы посмотрите на URL провайдера, мы можем сделать это:

request_data = request.files['file']
request_data.save(destination_file_path)
#adapt your "inference" to get a file path instead
result = run.inference(destination_file_path)

в заключении

def inference(destination_file_path):
    with open(destination_file_path) as f:
         #here handle "f" content like you want...hope that it will help you
Другие вопросы по тегам