1

문자열 쉼표를 입력 텐서로 사용하는 savedModel을 내보내고 있습니다. 이 문자열 텐서를 전처리하여 모델에 전달할 그래프를 삽입했습니다. 그러나, 나는 py_func을 사용하여 텐서에서 파이썬 문자열 연산을 수행합니다.알 수 없음 : KeyError : 'pyfunc_0'

여기서 input_text은 savedModel 서명의 입력 텐서입니다. 기본 위치가 input_ints 인 다른 자리 표시자를 만들고 py_func을 수행 한 결과로 input_text에 초기화되었습니다. 처음에는 input_text를 연산 (input_ints =tf.py_func(preprocess, [input_text], tf.int64))으로 사용했지만 tf.nn.dynamic_rnn은 지정되지 않은 텐서를 받아들이지 않았습니다.

# Create the graph object 
with tf.name_scope('inputs'): 
    input_text = tf.placeholder(tf.string, name="input_text") 
    input_ints = tf.placeholder_with_default(
     tf.py_func(preprocess, [input_text], tf.int64), shape=[None, None]) 

def lstm_cell(): 
    # Your basic LSTM cell 
    lstm = tf.contrib.rnn.BasicLSTMCell(lstm_size, reuse=tf.get_variable_scope().reuse) 
    # Add dropout to the cell 
    return tf.contrib.rnn.DropoutWrapper(lstm, output_keep_prob=keep_prob) 


# def create_rnn(): 
with tf.name_scope("Embeddings"): 
    embedding = tf.Variable(tf.random_uniform((vocab_size, embed_size), -1, 1)) 
    embed = tf.nn.embedding_lookup(embedding, input_ints) 
with tf.name_scope("RNN_layers"): 
    cell = tf.contrib.rnn.MultiRNNCell([lstm_cell() for _ in range(lstm_layers)]) 
initial_state = cell.zero_state(batch_size, tf.float32) 
with tf.name_scope("RNN_forward"): 
    outputs, final_state = tf.nn.dynamic_rnn(cell, embed, initial_state=initial_state) 
with tf.name_scope('predictions'): 
    predictions = tf.contrib.layers.fully_connected(outputs[:, -1], 1, activation_fn=tf.sigmoid) 

이제 위의 구현을 사용

, 나는 제대로 모델을 내보낼 수 있지만 모델을 복원 할 때, 나는 다음과 같은 오류 얻을 : 내가 Github에서에 게시 된이 issue 살펴 보았다

2017-11-23 17:29:14.600184: W tensorflow/core/framework/op_kernel.cc:1192] Unknown: KeyError: 'pyfunc_0' 
Traceback (most recent call last): 
    File "/Users/sakibarrahman/anaconda/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1327, in _do_call 
    return fn(*args) 
    File "/Users/sakibarrahman/anaconda/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1306, in _run_fn 
    status, run_metadata) 
    File "/Users/sakibarrahman/anaconda/lib/python3.6/contextlib.py", line 89, in __exit__ 
    next(self.gen) 
    File "/Users/sakibarrahman/anaconda/lib/python3.6/site-packages/tensorflow/python/framework/errors_impl.py", line 466, in raise_exception_on_not_ok_status 
    pywrap_tensorflow.TF_GetCode(status)) 
tensorflow.python.framework.errors_impl.UnknownError: KeyError: 'pyfunc_0' 
    [[Node: inputs/PyFunc = PyFunc[Tin=[DT_STRING], Tout=[DT_INT64], token="pyfunc_0", _device="/job:localhost/replica:0/task:0/cpu:0"](_arg_inputs/input_text_0_0)]] 

During handling of the above exception, another exception occurred: 

Traceback (most recent call last): 
    File "neural_load_model.py", line 85, in <module> 
    result = sess.run(output_tensor, {input_tensor: "Charter Communications, Inc. (CHTR) Stock Rating Reaffirmed by Goldman Sachs Group, Inc. (The)"}) 
    File "/Users/sakibarrahman/anaconda/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 895, in run 
    run_metadata_ptr) 
    File "/Users/sakibarrahman/anaconda/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1124, in _run 
    feed_dict_tensor, options, run_metadata) 
    File "/Users/sakibarrahman/anaconda/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1321, in _do_run 
    options, run_metadata) 
    File "/Users/sakibarrahman/anaconda/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1340, in _do_call 
    raise type(e)(node_def, op, message) 
tensorflow.python.framework.errors_impl.UnknownError: KeyError: 'pyfunc_0' 
    [[Node: inputs/PyFunc = PyFunc[Tin=[DT_STRING], Tout=[DT_INT64], token="pyfunc_0", _device="/job:localhost/replica:0/task:0/cpu:0"](_arg_inputs/input_text_0_0)]] 

Caused by op 'inputs/PyFunc', defined at: 
    File "neural_load_model.py", line 74, in <module> 
    model = tf.saved_model.loader.load(sess, [tf.saved_model.tag_constants.SERVING], import_path) 
    File "/Users/sakibarrahman/anaconda/lib/python3.6/site-packages/tensorflow/python/saved_model/loader_impl.py", line 216, in load 
    saver = tf_saver.import_meta_graph(meta_graph_def_to_load, **saver_kwargs) 
    File "/Users/sakibarrahman/anaconda/lib/python3.6/site-packages/tensorflow/python/training/saver.py", line 1698, in import_meta_graph 
    **kwargs) 
    File "/Users/sakibarrahman/anaconda/lib/python3.6/site-packages/tensorflow/python/framework/meta_graph.py", line 656, in import_scoped_meta_graph 
    producer_op_list=producer_op_list) 
    File "/Users/sakibarrahman/anaconda/lib/python3.6/site-packages/tensorflow/python/framework/importer.py", line 313, in import_graph_def 
    op_def=op_def) 
    File "/Users/sakibarrahman/anaconda/lib/python3.6/site-packages/tensorflow/python/framework/ops.py", line 2630, in create_op 
    original_op=self._default_original_op, op_def=op_def) 
    File "/Users/sakibarrahman/anaconda/lib/python3.6/site-packages/tensorflow/python/framework/ops.py", line 1204, in __init__ 
    self._traceback = self._graph._extract_stack() # pylint: disable=protected-access 

UnknownError (see above for traceback): KeyError: 'pyfunc_0' 
    [[Node: inputs/PyFunc = PyFunc[Tin=[DT_STRING], Tout=[DT_INT64], token="pyfunc_0", _device="/job:localhost/replica:0/task:0/cpu:0"](_arg_inputs/input_text_0_0)]] 

을하지만, 나는 이 방법을 구현하는 방법에 대해서는 확실하지 않습니다. 또한 모델을로드하고 'freeze_graph'를 사용하지 않고 입력 용 문자열을 전달합니다. 모델을 저장하는

내 코드 : 모델을로드하기위한

saver = tf.train.Saver() 

#Define new functions 
def preprocess(text): 
. 
. 
. 
tf.reset_default_graph() 
. 
. 
. 
#Define new placeholder that was not in the original model graph 
#Define new placeholder with default value initialized with py_func that was not in the original model graph 
with tf.name_scope('inputs'): 
    input_text = tf.placeholder(tf.string, name="input_text") 
    input_ints = tf.placeholder_with_default(
     tf.py_func(preprocess, [input_text], tf.int64), shape=[None, None]) 
. 
. 
. 
#Define placeholders and ops that I need and were in the original graph 



saver = tf.train.Saver() 
#Serving the model 
with tf.Session() as sess: 


#Restore from old checkpoint 
saver.restore(sess, import_path) 

print ('Exporting trained model to %s'%(export_path)) 

builder = saved_model_builder.SavedModelBuilder(export_path) 

original_assets_directory = export_path + '/assets' 
original_assets_filename = "vocabulary.pickle" 
original_assets_filepath = write_vocab(original_assets_directory, 
             original_assets_filename) 

# Set up the assets collection. 
assets_filepath = tf.constant(original_assets_filepath) 
tf.add_to_collection(tf.GraphKeys.ASSET_FILEPATHS, assets_filepath) 
filename_tensor = tf.Variable(
    original_assets_filename, 
    name="vocab_tensor", 
    trainable=False, 
    collections=[]) 
assign_filename_op = filename_tensor.assign(original_assets_filename) 


# Build the signature_def_map. 
classification_inputs = utils.build_tensor_info(input_text) 
classification_outputs_classes = utils.build_tensor_info(predictions) 
classification_signature = signature_def_utils.build_signature_def(
    inputs={signature_constants.CLASSIFY_INPUTS: classification_inputs}, 
    outputs={ 
     signature_constants.CLASSIFY_OUTPUT_CLASSES: 
      classification_outputs_classes, 
    }, 
    method_name=signature_constants.CLASSIFY_METHOD_NAME) 

legacy_init_op = tf.group(
    tf.tables_initializer(), name='legacy_init_op') 
#add the sigs to the servable 
builder.add_meta_graph_and_variables(
    sess, [tag_constants.SERVING], 
    signature_def_map={ 
     signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: 
      classification_signature 
    }, 
    assets_collection=tf.get_collection(tf.GraphKeys.ASSET_FILEPATHS), 
    legacy_init_op=tf.group(assign_filename_op)) 
print ("added meta graph and variables") 

builder.save() 
print("model saved") 

내 코드입니다. 아니 함수를 정의하거나 자리는 'pyfunc_0'오류로 연결 :

#Define preprocess function 
def preprocess(text_bin): 

#Define new placeholders 
with tf.name_scope('inputs'): 
    input_text = tf.placeholder(tf.string, name="input_text") 
    input_ints = tf.placeholder_with_default(
     tf.py_func(preprocess, [input_text], tf.int64), shape=[None, None]) 

with tf.Session(graph=tf.Graph()) as sess: 
    # restore save model 
    model = tf.saved_model.loader.load(sess, [tf.saved_model.tag_constants.SERVING], import_path) 
    print("model restored") 
    loaded_graph = tf.get_default_graph() 

    # get necessary tensors by name 
    input_tensor_name = model.signature_def[signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY].inputs[signature_constants.CLASSIFY_INPUTS].name 
    input_tensor = loaded_graph.get_tensor_by_name(input_tensor_name) 
    output_tensor_name = model.signature_def[signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY].outputs[signature_constants.CLASSIFY_OUTPUT_CLASSES].name 
    output_tensor = loaded_graph.get_tensor_by_name(output_tensor_name) 

    result = sess.run(output_tensor, {input_tensor: "Some String"}) 
    print (result) 

업데이트 :

을 savedModel가 작동하는 것 같다로드 할 때 기능과 자리를 정의. 그러나 모델을 저장하기 위해 빌더를 사용하기 전에 왜 그래프에 추가되지 않는지 모르겠습니다.

+0

'SavedModelBuilder'를 만들고 메타 데이터를 추가하는 데 사용한 코드를 보는 것이 도움이 될 것입니다. – MatthewScarpino

+0

''pyfunc_0 ''은 당신이 생각하는 곳에 존재하지 않습니다. 그것을 추적하고 그것이 존재하지 않는 이유를 알아보십시오. –

+0

@MatthewScarpino 모델을 저장하는 방법에 대한 자세한 내용을 추가했습니다. – skbrhmn

답변

0

사용 된 전처리 함수는 실제로 그래프의 일부가 아니므로 py_func()는 savedModel을로드 할 때 사용할 함수를 알지 못합니다. 현재 Tensorflow Serve 플로우 내에서 전처리를 수행하는 쉬운 방법은 없습니다. 모델을 사용하기 전에 클라이언트 측에서 수행되어야하며 모델의 일부가 될 수 있도록 사용자 지정 op를 만들어야 할 수도 있습니다. 다른 대안은 사용자 지정 서비스 가능 서비스를 작성하는 것일 수 있습니다.

0

모델에 사용자 정의 레이어가있는 것 같습니다. 모델 코드를 따라 가서 찾을 수 있습니다. 따라서 그래프로드 전에 해당 함수를 정의 할 수 있습니다. 또한 함수 정의 순서가 중요합니다.

+0

모델이 훈련되고 검사 점으로 저장되었습니다. 그래프를 다시 만들었지 만 py_func()를 사용하여 그 값을 얻는 새로운 placeholder를 추가했습니다.그런 다음 체크 포인트를로드 한 다음 savedModel 빌더를 사용하여 모델을 저장합니다. 그래서 나는 체크 포인트를로드하기 전에 함수를 정의하려고합니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까? – skbrhmn