0

我试图从加载的张量流模型中做出预测。虽然我不确定我之前保存它的方式是否正确,但特别是我对serving_input_fn()函数内部的代码(MAX_SEQ_LENGTH=128)有疑问:

def serving_input_fn():   
    feature_spec = {   "input_ids" : tf.FixedLenFeature([None,MAX_SEQ_LENGTH], tf.int64),                
                     "input_mask" : tf.FixedLenFeature([None,MAX_SEQ_LENGTH], tf.int64),       
                   "segment_ids" : tf.FixedLenFeature([None,MAX_SEQ_LENGTH], tf.int64),       
                   "label_ids" :  tf.FixedLenFeature([None], tf.int64)    }   

    serialized_tf_example = tf.placeholder(dtype=tf.string,shape=[None],name='input_example_tensor')   
    receiver_tensors = {'example': serialized_tf_example}   
    features = tf.parse_example(serialized_tf_example, feature_spec) 

    return tf.estimator.export.ServingInputReceiver(features, receiver_tensors)  

estimator.export_saved_model('gs://bucket/trained_model', serving_input_receiver_fn=serving_input_fn)

当我尝试从加载的模型中进行预测时:

from tensorflow.contrib import predictor
predict_fn = predictor.from_saved_model(LOAD_PATH)
input_features_test = convert_examples_to_features( test_examples,label_list, MAX_SEQ_LENGTH, tokenizer)
predictions = predict_fn({'example':input_features_test[0]})

它返回此错误:

ValueError:无法为张量“input_example_tensor:0”提供形状()的值,其形状为“(?,)”

我应该如何更改 serving_input_fn() 方法?

如果你想重现它:github_repo (你应该从这里下载变量并将它放在trained_model/1608370941/文件夹中)

是我在谷歌云 TPU 上微调 BERT 模型的教程。

4

1 回答 1

0

我使用以下serving_input_fn()函数(在本教程中找到)保存了模型:

def serving_input_fn():
    label_ids = tf.placeholder(tf.int32, [None], name='label_ids')
    input_ids = tf.placeholder(tf.int32, [None, MAX_SEQ_LENGTH], name='input_ids')
    input_mask = tf.placeholder(tf.int32, [None, MAX_SEQ_LENGTH], name='input_mask')
    segment_ids = tf.placeholder(tf.int32, [None, MAX_SEQ_LENGTH], name='segment_ids')
    input_fn = tf.estimator.export.build_raw_serving_input_receiver_fn({
        'label_ids': label_ids,
        'input_ids': input_ids,
        'input_mask': input_mask,
        'segment_ids': segment_ids,
    })()
    return input_fn

然后我使用下面提到的代码加载它:

from tensorflow.contrib import predictor
predict_fn = predictor.from_saved_model(LOAD_PATH_GCP)

我使用以下方法将输入字符串转换为 BERT 模型输入特征:

def convert_single_string_to_input_dict(example_string_prep, vocab_file_path, max_seq_length):
  
  #Inizialize BERT tokenizer
  tokenizer = tokenization.FullTokenizer(vocab_file_path, do_lower_case=True)
  token_a = tokenizer.tokenize(example_string_prep)

  tokens = []
  segments_ids = []
  segment_ids = []

  tokens.append("[CLS]")
  segment_ids.append(0)
  for token in token_a:
    tokens.append(token)
    segment_ids.append(0)

  tokens.append('[SEP]')
  segment_ids.append(0)
    
  input_ids = tokenizer.convert_tokens_to_ids(tokens)
  input_mask = [1] * len(input_ids)

  while len(input_ids) < max_seq_length:
    input_ids.append(0)
    input_mask.append(0)
    segment_ids.append(0)

  label_id = [0]
  padding = [0] * max_seq_length

  print(len(input_ids),len(input_mask),len(segment_ids),len(label_id))

  return {"input_ids":[input_ids,padding], "input_mask":[input_mask,padding], "segment_ids":[segment_ids,padding], "label_ids":label_id}

最后,我使用加载的模型进行了预测:

MAX_SEQ_LENGTH = 128
VOCAB_FILE_PATH = 'path/to/vocab'

example_features = convert_single_string_to_input_dict(example_string, VOCAB_FILE_PATH, MAX_SEQ_LENGTH)

prediction = predict_fn(example_features)['probabilities'][0]
prediction_dict = {'POS': round(prediction[1],4), 'NEG': round(prediction[0],4)}
pprint(f"prediction: {prediction_dict}")
于 2020-12-23T13:44:29.703 回答