Выполнение логического вывода с сохраненной моделью BERT (TF 1.x)

Я застрял на одной строчке кода и в результате застрял в проекте на все выходные.

Я работаю над проектом, который использует BERT для классификации предложений. Я успешно обучил модель и могу протестировать результаты, используя пример кода из run_classifier.py.

Я могу экспортировать модель, используя этот пример кода (который неоднократно репостировался, поэтому я считаю, что он подходит для этой модели):

def export(self):
  def serving_input_fn():
    label_ids = tf.placeholder(tf.int32, [None], name='label_ids')
    input_ids = tf.placeholder(tf.int32, [None, self.max_seq_length], name='input_ids')
    input_mask = tf.placeholder(tf.int32, [None, self.max_seq_length], name='input_mask')
    segment_ids = tf.placeholder(tf.int32, [None, self.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
  self.estimator._export_to_tpu = False
  self.estimator.export_savedmodel(self.output_dir, serving_input_fn)

Я также могу загрузить экспортированный оценщик (где функция экспорта сохраняет экспортированную модель в подкаталог с меткой времени):

predict_fn = predictor.from_saved_model(self.output_dir + timestamp_number)

Однако, хоть убей, я не могу понять, что нужно предоставить в pred_fn в качестве входных данных для вывода. Вот мой лучший код на данный момент:

def predict(self):
  input = 'Test input'
  guid = 'predict-0'
  text_a = tokenization.convert_to_unicode(input)
  label = self.label_list[0]
  examples = [InputExample(guid=guid, text_a=text_a, text_b=None, label=label)]
  features = convert_examples_to_features(examples, self.label_list,
    self.max_seq_length, self.tokenizer)
  predict_input_fn = input_fn_builder(features, self.max_seq_length, False)
  predict_fn = predictor.from_saved_model(self.output_dir + timestamp_number)
  result = predict_fn(predict_input_fn)       # this generates an error
  print(result)

Кажется, не имеет значения, что я предоставляю для pred_fn: массив примеров, массив функций, функцию pred_input_fn. Ясно, что predic_fn нужен словарь какого-то типа, но каждая попытка, которую я пробовал, генерирует исключение из-за несоответствия тензора или других ошибок, которые обычно означают: неправильный ввод.

Я предположил, что функция from_saved_model требует того же типа ввода, что и функция тестирования модели - по-видимому, это не так.

Кажется, что многие люди задавали именно этот вопрос - "как мне использовать экспортированную модель BERT TensorFlow для вывода?" - и не получили ответов:

Тема № 1

Тема № 2 < / а>

Тема № 3

Тема № 4

Любая помощь? Заранее спасибо.


person David Stein    schedule 19.04.2020    source источник


Ответы (1)


Спасибо тебе за этот пост. Ваш serving_input_fn был тем, что мне не хватало! Ваша predict функция должна быть изменена, чтобы напрямую передавать функции dict, а не использовать pred_input_fn:

def predict(sentences):
    labels = [0, 1]
    input_examples = [
        run_classifier.InputExample(
            guid="",
            text_a = x,
            text_b = None,
            label = 0
        ) for x in sentences] # here, "" is just a dummy label
    input_features = run_classifier.convert_examples_to_features(
        input_examples, labels, MAX_SEQ_LEN, tokenizer
    )
    # this is where pred_input_fn is replaced
    all_input_ids = []
    all_input_mask = []
    all_segment_ids = []
    all_label_ids = []

    for feature in input_features:
        all_input_ids.append(feature.input_ids)
        all_input_mask.append(feature.input_mask)
        all_segment_ids.append(feature.segment_ids)
        all_label_ids.append(feature.label_id)
    pred_dict = {
        'input_ids': all_input_ids,
        'input_mask': all_input_mask,
        'segment_ids': all_segment_ids,
        'label_ids': all_label_ids
    }
    predict_fn = predictor.from_saved_model('../testing/1589418540')
    result = predict_fn(pred_dict)
    print(result)
pred_sentences = [
  "That movie was absolutely awful",
  "The acting was a bit lacking",
  "The film was creative and surprising",
  "Absolutely fantastic!",
]
predict(pred_sentences)
{'probabilities': array([[-0.3579178 , -1.2010787 ],
       [-0.36648935, -1.1814401 ],
       [-0.30407643, -1.3386648 ],
       [-0.45970002, -0.9982413 ],
       [-0.36113673, -1.1936386 ],
       [-0.36672896, -1.1808994 ]], dtype=float32), 'labels': array([0, 0, 0, 0, 0, 0])}

Однако вероятности, возвращаемые для предложений в pred_sentences, не совпадают с вероятностями, которые я использую estimator.predict(predict_input_fn), где estimator - это точно настроенная модель, используемая в том же сеансе (python). Например, [-0,27276006, -1,4324446] с использованием estimator против [-0,26713806, -1,4505868] с использованием predictor.

person jkm    schedule 14.05.2020