如何使用张量流为保存的BERT SQuAD2.0模型建立输入以进行预测

时间:2019-08-13 16:09:36

标签: python tensorflow deep-learning nlp question-answering

鉴于我已经获得了输入的所有元素,因此我正在尝试从BERT-SQuAD构建用于保存的模型的输入。

我通过在Google bert中运行run_squad.py对问题回答模型进行了微调,然后使用export_saved_model导出了该模型。现在,当我有一个新的上下文和问题时,我无法构建可以从模型获得返回输出的正确输入。

导出模型的代码:

#export the model
    def serving_input_receiver_fn():
      feature_spec = {
            "unique_ids": tf.FixedLenFeature([], tf.int64),
            "input_ids": tf.FixedLenFeature([FLAGS.max_seq_length], tf.int64),
            "input_mask": tf.FixedLenFeature([FLAGS.max_seq_length], tf.int64),
            "segment_ids": tf.FixedLenFeature([FLAGS.max_seq_length], tf.int64),
      }

      serialized_tf_example = tf.placeholder(dtype=tf.string,
                               shape=FLAGS.predict_batch_size,
                               name='input_example_tensor')
      receiver_tensors = {'examples': serialized_tf_example}
      features = tf.parse_example(serialized_tf_example, feature_spec)
      return tf.estimator.export.ServingInputReceiver(features, receiver_tensors)

    estimator = tf.contrib.tpu.TPUEstimator(
      use_tpu=FLAGS.use_tpu,
      model_fn=model_fn,
      config=run_config,
      train_batch_size=FLAGS.train_batch_size,
      predict_batch_size=FLAGS.predict_batch_size)

    estimator._export_to_tpu = False  ## !!important to add this
    estimator.export_saved_model(
        export_dir_base ="C:/Users/ZitongZhou/Desktop/qa/bert_squad/servemodel",
        serving_input_receiver_fn = serving_input_receiver_fn)

我加载模型的方式:

export_dir = 'servemodel'
subdirs = [x for x in Path(export_dir).iterdir()
           if x.is_dir() and 'temp' not in str(x)]
latest = str(sorted(subdirs)[-1])

predict_fn = predictor.from_saved_model(latest)

我从run_squad.py获得了eval_features。 我尝试构建输入的方式:

feature_spec = {
        "unique_ids": np.asarray(eval_features[0].unique_id).tolist(),
        "input_ids": np.asarray(eval_features[0].input_ids).tolist(),
        "input_mask": np.asarray(eval_features[0].input_mask).tolist(),
        "segment_ids": np.asarray(eval_features[0].segment_ids).tolist()
    }
serialized_tf_example = tf.placeholder(dtype=tf.string,
                           shape=[1],
                           name='input_example_tensor')
receiver_tensors = {'examples': serialized_tf_example}
features = tf.parse_example(serialized_tf_example, feature_spec)
out = predict_fn({'examples':[str(feature_spec)]})

我希望得到一个预测“出来”,以便我可以从中提取问题的答案。

我得到的追溯:

Traceback (most recent call last):

  File "<ipython-input-51-0c3b618a8f48>", line 11, in <module>
    features = tf.parse_example(serialized_tf_example, feature_spec)

  File "C:\Users\ZitongZhou\Anaconda3\envs\nlp\lib\site-packages\tensorflow
\python\ops\parsing_ops.py", line 580, in parse_example
    return parse_example_v2(serialized, features, example_names, name)

  File "C:\Users\ZitongZhou\Anaconda3\envs\nlp\lib\site-packages\tensorflow
\python\ops\parsing_ops.py", line 803, in parse_example_v2
    [VarLenFeature, SparseFeature, FixedLenFeature, FixedLenSequenceFeature])

  File "C:\Users\ZitongZhou\Anaconda3\envs\nlp\lib\site-packages\tensorflow
\python\ops\parsing_ops.py", line 299, in _features_to_raw_params
    raise ValueError("Invalid feature %s:%s." % (key, feature))

ValueError: Invalid feature input_ids:[101, 1005, 2129, 2214, 2003, 19523, 
6562, 1005, 102, 1005, 19523, 11233, 2003, 2274, 2086, 2214, 1005, 102,
 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0].

1 个答案:

答案 0 :(得分:1)

我想通了,我需要使用tf.train.Example函数:

def create_int_feature(values):
    f = tf.train.Feature(int64_list=tf.train.Int64List(value=list(values)))
    return f

inputs = collections.OrderedDict()
inputs["input_ids"] = create_int_feature(features[0].input_ids)
inputs["input_mask"] = create_int_feature(features[0].input_mask)
inputs["segment_ids"] = create_int_feature(features[0].segment_ids)
inputs["unique_ids"] = create_int_feature([features[0].unique_id])

tf_example = tf.train.Example(features=tf.train.Features(feature=inputs))
out = predict_fn({'examples':[tf_example.SerializeToString()]})