Невозможно преобразовать в тензорное прото: 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