Watch keynotes, product sessions, workshops, and more from Google I/O See playlist

Решайте задачи GLUE с помощью BERT на TPU

Посмотреть на TensorFlow.org Запускаем в Google Colab Посмотреть на GitHub Скачать блокнот См. Модель TF Hub

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

  1. CoLA (Corpus of Linguistic Acceptance): является ли предложение грамматически правильным?

  2. SST-2 (Stanford Sentiment Treebank): задача состоит в том, чтобы предсказать тональность данного предложения.

  3. MRPC (Microsoft Research Paraphrase Corpus): определяет, являются ли пары предложений семантически эквивалентными.

  4. QQP (Quora Question Pairs2): Определите, являются ли пары вопросов семантически эквивалентными.

  5. MNLI (Multi- genre Natural Language Inference): для заданного предложения предпосылки и предложения гипотезы задача состоит в том, чтобы предсказать, влечет ли предпосылка гипотезу (следствие), противоречит гипотезе (противоречие) или нет (нейтрально).

  6. QNLI ( вопросно-ответный вывод на естественном языке): задача состоит в том, чтобы определить, содержит ли контекстное предложение ответ на вопрос.

  7. RTE (Распознавание текстового образования): Определите, влечет ли предложение данную гипотезу или нет.

  8. WNLI (Winograd Natural Language Inference): задача состоит в том, чтобы предсказать, следует ли предложение с замененным местоимением исходным предложением.

Это руководство содержит полный код для обучения этих моделей на TPU. Вы также можете запустить этот ноутбук на графическом процессоре, изменив одну строку (описано ниже).

В этом блокноте вы:

  • Загрузите модель BERT из TensorFlow Hub
  • Выберите одну из задач GLUE и загрузите набор данных
  • Предварительно обработать текст
  • Точная настройка BERT (примеры приведены для наборов данных с одним и несколькими предложениями)
  • Сохраните обученную модель и используйте ее

Настраивать

Вы будете использовать отдельную модель для предварительной обработки текста, прежде чем использовать ее для точной настройки BERT. Эта модель зависит от тензорного потока / текста , который вы установите ниже.

pip install -q -U tensorflow-text

Вы будете использовать оптимизатор AdamW из tensorflow / models для точной настройки BERT, который вы также установите.

pip install -q -U tf-models-official
pip install -U tfds-nightly
import os
import tensorflow as tf
import tensorflow_hub as hub
import tensorflow_datasets as tfds
import tensorflow_text as text  # A dependency of the preprocessing model
import tensorflow_addons as tfa
from official.nlp import optimization
import numpy as np

tf.get_logger().setLevel('ERROR')

Затем настройте TFHub для чтения контрольных точек непосредственно из сегментов облачного хранилища TFHub. Это рекомендуется только при запуске моделей TFHub на TPU.

Без этого параметра TFHub загрузит сжатый файл и извлечет контрольную точку локально. Попытка загрузки из этих локальных файлов завершится ошибкой со следующей ошибкой:

InvalidArgumentError: Unimplemented: File system scheme '[local]' not implemented

Это связано с тем, что TPU может читать только непосредственно из сегментов Cloud Storage .

os.environ["TFHUB_MODEL_LOAD_FORMAT"]="UNCOMPRESSED"

Подключиться к работнику ТПУ

Следующий код подключается к рабочему процессору TPU и изменяет устройство по умолчанию TensorFlow на устройство ЦП на рабочем сервере TPU. Он также определяет стратегию распределения TPU, которую вы будете использовать для распределения обучения модели по 8 отдельным ядрам TPU, доступным для этого одного рабочего TPU. См. Руководство TensorFlow по TPU для получения дополнительной информации.

import os

if os.environ['COLAB_TPU_ADDR']:
  cluster_resolver = tf.distribute.cluster_resolver.TPUClusterResolver(tpu='')
  tf.config.experimental_connect_to_cluster(cluster_resolver)
  tf.tpu.experimental.initialize_tpu_system(cluster_resolver)
  strategy = tf.distribute.TPUStrategy(cluster_resolver)
  print('Using TPU')
elif tf.test.is_gpu_available():
  strategy = tf.distribute.MirroredStrategy()
  print('Using GPU')
else:
  raise ValueError('Running on CPU is not recommended.')
Using TPU

Загрузка моделей из TensorFlow Hub

Здесь вы можете выбрать, какую модель BERT загрузить из TensorFlow Hub и выполнить точную настройку. На выбор доступно несколько моделей BERT.

  • BERT-Base , Uncased и еще семь моделей с обученными весами, выпущенные авторами оригинального BERT.
  • Маленькие BERT имеют ту же общую архитектуру, но меньше и / или меньше блоков Transformer, что позволяет исследовать компромиссы между скоростью, размером и качеством.
  • АЛЬБЕРТ : четыре разных размера «облегченного BERT», который уменьшает размер модели (но не время вычислений) за счет разделения параметров между слоями.
  • Эксперты BERT : восемь моделей, каждая из которых имеет базовую архитектуру BERT, но предлагает выбор между различными доменами предварительного обучения, чтобы более точно согласовать с целевой задачей.
  • Electra имеет ту же архитектуру, что и BERT (в трех разных размерах), но предварительно обучается в качестве дискриминатора в настройке, напоминающей Generative Adversarial Network (GAN).
  • BERT с Talking-Heads Attention и Gated GELU [ base , large ] имеет два улучшения ядра архитектуры Transformer.

Дополнительную информацию см. В документации к модели, указанной выше.

В этом руководстве вы начнете с BERT-базы. Вы можете использовать более крупные и более свежие модели для более высокой точности или модели меньшего размера для более быстрого обучения. Чтобы изменить модель, вам нужно всего лишь переключить одну строку кода (как показано ниже). Все различия заключены в SavedModel, которую вы загрузите с TensorFlow Hub.

Выберите модель BERT для точной настройки

BERT model selected           : https://tfhub.dev/tensorflow/bert_en_uncased_L-12_H-768_A-12/3
Preprocessing model auto-selected: https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3

Предварительно обработать текст

В тексте Classify with BERT colab используется модель предварительной обработки, встроенная непосредственно в кодировщик BERT.

В этом руководстве показано, как выполнить предварительную обработку как часть входного конвейера для обучения с использованием Dataset.map, а затем объединить его с моделью, которая экспортируется для вывода. Таким образом, как обучение, так и логический вывод могут работать с исходными текстовыми входами, хотя сам TPU требует числовых входных данных.

Помимо требований TPU, он может повысить производительность за счет асинхронной предварительной обработки во входном конвейере (вы можете узнать больше в руководстве по производительности tf.data ).

В этом руководстве также показано, как создавать модели с несколькими входами и как настроить длину последовательности входных данных для BERT.

Продемонстрируем модель предварительной обработки.

bert_preprocess = hub.load(tfhub_handle_preprocess)
tok = bert_preprocess.tokenize(tf.constant(['Hello TensorFlow!']))
print(tok)
<tf.RaggedTensor [[[7592], [23435, 12314], [999]]]>

Каждая модель предварительной обработки также предоставляет метод .bert_pack_inputs(tensors, seq_length) , который принимает список токенов (как вышеупомянутый tok ) и аргумент длины последовательности. Это упаковывает входные данные для создания словаря тензоров в формате, ожидаемом моделью BERT.

text_preprocessed = bert_preprocess.bert_pack_inputs([tok, tok], tf.constant(20))

print('Shape Word Ids : ', text_preprocessed['input_word_ids'].shape)
print('Word Ids       : ', text_preprocessed['input_word_ids'][0, :16])
print('Shape Mask     : ', text_preprocessed['input_mask'].shape)
print('Input Mask     : ', text_preprocessed['input_mask'][0, :16])
print('Shape Type Ids : ', text_preprocessed['input_type_ids'].shape)
print('Type Ids       : ', text_preprocessed['input_type_ids'][0, :16])
Shape Word Ids :  (1, 20)
Word Ids       :  tf.Tensor(
[  101  7592 23435 12314   999   102  7592 23435 12314   999   102     0
     0     0     0     0], shape=(16,), dtype=int32)
Shape Mask     :  (1, 20)
Input Mask     :  tf.Tensor([1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0], shape=(16,), dtype=int32)
Shape Type Ids :  (1, 20)
Type Ids       :  tf.Tensor([0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0], shape=(16,), dtype=int32)

Вот некоторые детали, на которые следует обратить внимание:

  • input_mask Маска позволяет модели четко различать содержимое и отступ. Маска имеет ту же форму, что и input_word_ids , и содержит 1 везде, где input_word_ids не является input_word_ids .
  • input_type_ids имеет ту же форму, что и input_mask , но внутри области без дополнений содержит 0 или 1, указывающие, частью какого предложения является токен.

Затем вы создадите модель предварительной обработки, которая инкапсулирует всю эту логику. Ваша модель будет принимать строки в качестве входных данных и возвращать должным образом отформатированные объекты, которые могут быть переданы в BERT.

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

def make_bert_preprocess_model(sentence_features, seq_length=128):
  """Returns Model mapping string features to BERT inputs.

  Args:
    sentence_features: a list with the names of string-valued features.
    seq_length: an integer that defines the sequence length of BERT inputs.

  Returns:
    A Keras Model that can be called on a list or dict of string Tensors
    (with the order or names, resp., given by sentence_features) and
    returns a dict of tensors for input to BERT.
  """

  input_segments = [
      tf.keras.layers.Input(shape=(), dtype=tf.string, name=ft)
      for ft in sentence_features]

  # Tokenize the text to word pieces.
  bert_preprocess = hub.load(tfhub_handle_preprocess)
  tokenizer = hub.KerasLayer(bert_preprocess.tokenize, name='tokenizer')
  segments = [tokenizer(s) for s in input_segments]

  # Optional: Trim segments in a smart way to fit seq_length.
  # Simple cases (like this example) can skip this step and let
  # the next step apply a default truncation to approximately equal lengths.
  truncated_segments = segments

  # Pack inputs. The details (start/end token ids, dict of output tensors)
  # are model-dependent, so this gets loaded from the SavedModel.
  packer = hub.KerasLayer(bert_preprocess.bert_pack_inputs,
                          arguments=dict(seq_length=seq_length),
                          name='packer')
  model_inputs = packer(truncated_segments)
  return tf.keras.Model(input_segments, model_inputs)

Продемонстрируем модель предварительной обработки. Вы создадите тест с вводом двух предложений (input1 и input2). Результатом является то, что модель BERT ожидала бы в качестве входных данных: input_word_ids , input_masks и input_type_ids .

test_preprocess_model = make_bert_preprocess_model(['my_input1', 'my_input2'])
test_text = [np.array(['some random test sentence']),
             np.array(['another sentence'])]
text_preprocessed = test_preprocess_model(test_text)

print('Keys           : ', list(text_preprocessed.keys()))
print('Shape Word Ids : ', text_preprocessed['input_word_ids'].shape)
print('Word Ids       : ', text_preprocessed['input_word_ids'][0, :16])
print('Shape Mask     : ', text_preprocessed['input_mask'].shape)
print('Input Mask     : ', text_preprocessed['input_mask'][0, :16])
print('Shape Type Ids : ', text_preprocessed['input_type_ids'].shape)
print('Type Ids       : ', text_preprocessed['input_type_ids'][0, :16])
Keys           :  ['input_type_ids', 'input_word_ids', 'input_mask']
Shape Word Ids :  (1, 128)
Word Ids       :  tf.Tensor(
[ 101 2070 6721 3231 6251  102 2178 6251  102    0    0    0    0    0
    0    0], shape=(16,), dtype=int32)
Shape Mask     :  (1, 128)
Input Mask     :  tf.Tensor([1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0], shape=(16,), dtype=int32)
Shape Type Ids :  (1, 128)
Type Ids       :  tf.Tensor([0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0], shape=(16,), dtype=int32)

Давайте посмотрим на структуру модели, обратив внимание на два только что определенных вами входа.

tf.keras.utils.plot_model(test_preprocess_model)
('You must install pydot (`pip install pydot`) and install graphviz (see instructions at https://graphviz.gitlab.io/download/) ', 'for plot_model/model_to_dot to work.')

Чтобы применить предварительную обработку ко всем входным данным из набора данных, вы будете использовать функцию map из набора данных. Затем результат кешируется для повышения производительности .

AUTOTUNE = tf.data.AUTOTUNE


def load_dataset_from_tfds(in_memory_ds, info, split, batch_size,
                           bert_preprocess_model):
  is_training = split.startswith('train')
  dataset = tf.data.Dataset.from_tensor_slices(in_memory_ds[split])
  num_examples = info.splits[split].num_examples

  if is_training:
    dataset = dataset.shuffle(num_examples)
    dataset = dataset.repeat()
  dataset = dataset.batch(batch_size)
  dataset = dataset.map(lambda ex: (bert_preprocess_model(ex), ex['label']))
  dataset = dataset.cache().prefetch(buffer_size=AUTOTUNE)
  return dataset, num_examples

Определите вашу модель

Теперь вы готовы определить свою модель для классификации предложений или пар предложений, подав предварительно обработанные входные данные через кодировщик BERT и поместив сверху линейный классификатор (или другое расположение слоев по своему усмотрению) и используя выпадение для регуляризации.

def build_classifier_model(num_classes):
  inputs = dict(
      input_word_ids=tf.keras.layers.Input(shape=(None,), dtype=tf.int32),
      input_mask=tf.keras.layers.Input(shape=(None,), dtype=tf.int32),
      input_type_ids=tf.keras.layers.Input(shape=(None,), dtype=tf.int32),
  )

  encoder = hub.KerasLayer(tfhub_handle_encoder, trainable=True, name='encoder')
  net = encoder(inputs)['pooled_output']
  net = tf.keras.layers.Dropout(rate=0.1)(net)
  net = tf.keras.layers.Dense(num_classes, activation=None, name='classifier')(net)
  return tf.keras.Model(inputs, net, name='prediction')

Давайте попробуем запустить модель на некоторых предварительно обработанных входных данных.

test_classifier_model = build_classifier_model(2)
bert_raw_result = test_classifier_model(text_preprocessed)
print(tf.sigmoid(bert_raw_result))
tf.Tensor([[0.20310709 0.39733988]], shape=(1, 2), dtype=float32)

Давайте посмотрим на структуру модели. Вы можете увидеть три ожидаемых входа BERT.

tf.keras.utils.plot_model(test_classifier_model)
('You must install pydot (`pip install pydot`) and install graphviz (see instructions at https://graphviz.gitlab.io/download/) ', 'for plot_model/model_to_dot to work.')

Выберите задачу из КЛЕЯ

Вы собираетесь использовать TensorFlow DataSet из набора тестов GLUE .

Colab позволяет загружать эти небольшие наборы данных в локальную файловую систему, а приведенный ниже код полностью считывает их в память, поскольку отдельный рабочий хост TPU не может получить доступ к локальной файловой системе среды выполнения colab.

Для больших наборов данных вам необходимо создать собственное ведро Google Cloud Storage, и рабочий TPU будет читать данные оттуда. Вы можете узнать больше в руководстве TPU .

Рекомендуется начать с набора данных CoLa (для одного предложения) или MRPC (для нескольких предложений), поскольку они небольшие и не требуют много времени для точной настройки.

Using glue/cola from TFDS
This dataset has 10657 examples
Number of classes: 2
Features ['sentence']
Splits ['test', 'train', 'validation']
Here are some sample rows from glue/cola dataset
['unacceptable', 'acceptable']

sample row 1
b'It is this hat that it is certain that he was wearing.'
label: 1 (acceptable)

sample row 2
b'Her efficient looking up of the answer pleased the boss.'
label: 1 (acceptable)

sample row 3
b'Both the workers will wear carnations.'
label: 1 (acceptable)

sample row 4
b'John enjoyed drawing trees for his syntax homework.'
label: 1 (acceptable)

sample row 5
b'We consider Leslie rather foolish, and Lou a complete idiot.'
label: 1 (acceptable)

Набор данных также определяет тип проблемы (классификация или регрессия) и соответствующую функцию потерь для обучения.

def get_configuration(glue_task):

  loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)

  if glue_task == 'glue/cola':
    metrics = tfa.metrics.MatthewsCorrelationCoefficient(num_classes=2)
  else:
    metrics = tf.keras.metrics.SparseCategoricalAccuracy(
        'accuracy', dtype=tf.float32)

  return metrics, loss

Обучите свою модель

Наконец, вы можете обучить модель от начала до конца на выбранном вами наборе данных.

Распределение

Вспомните код настройки вверху, который подключил среду выполнения colab к работнику TPU с несколькими устройствами TPU. Чтобы распространить на них обучение, вы создадите и скомпилируете свою основную модель Keras в рамках стратегии распространения TPU. (Подробнее см. Распределенное обучение с Keras .)

С другой стороны, предварительная обработка выполняется на ЦП рабочего хоста, а не на TPU, поэтому модель Keras для предварительной обработки, а также сопоставленные с ней наборы данных для обучения и проверки построены за пределами области стратегии распространения. Вызов Model.fit() позаботится о распределении переданного набора данных по репликам модели.

Оптимизатор

Точная настройка следует за настройкой оптимизатора из предварительного обучения BERT (как в случае с классификацией текста с помощью BERT ): он использует оптимизатор AdamW с линейным спадом условной начальной скорости обучения, с префиксом линейной фазы разогрева над первой. 10% тренировочных шагов ( num_warmup_steps ). Согласно статье BERT, начальная скорость обучения меньше для точной настройки (лучше всего 5e-5, 3e-5, 2e-5).

epochs = 3
batch_size = 32
init_lr = 2e-5

print(f'Fine tuning {tfhub_handle_encoder} model')
bert_preprocess_model = make_bert_preprocess_model(sentence_features)

with strategy.scope():

  # metric have to be created inside the strategy scope
  metrics, loss = get_configuration(tfds_name)

  train_dataset, train_data_size = load_dataset_from_tfds(
      in_memory_ds, tfds_info, train_split, batch_size, bert_preprocess_model)
  steps_per_epoch = train_data_size // batch_size
  num_train_steps = steps_per_epoch * epochs
  num_warmup_steps = num_train_steps // 10

  validation_dataset, validation_data_size = load_dataset_from_tfds(
      in_memory_ds, tfds_info, validation_split, batch_size,
      bert_preprocess_model)
  validation_steps = validation_data_size // batch_size

  classifier_model = build_classifier_model(num_classes)

  optimizer = optimization.create_optimizer(
      init_lr=init_lr,
      num_train_steps=num_train_steps,
      num_warmup_steps=num_warmup_steps,
      optimizer_type='adamw')

  classifier_model.compile(optimizer=optimizer, loss=loss, metrics=[metrics])

  classifier_model.fit(
      x=train_dataset,
      validation_data=validation_dataset,
      steps_per_epoch=steps_per_epoch,
      epochs=epochs,
      validation_steps=validation_steps)
Fine tuning https://tfhub.dev/tensorflow/bert_en_uncased_L-12_H-768_A-12/3 model
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/engine/functional.py:591: UserWarning: Input dict contained keys ['idx', 'label'] which did not match any model input. They will be ignored by the model.
  [n for n in tensors.keys() if n not in ref_input_names])
Epoch 1/3
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/framework/indexed_slices.py:449: UserWarning: Converting sparse IndexedSlices(IndexedSlices(indices=Tensor("AdamWeightDecay/gradients/StatefulPartitionedCall:1", shape=(None,), dtype=int32), values=Tensor("clip_by_global_norm/clip_by_global_norm/_0:0", dtype=float32), dense_shape=Tensor("AdamWeightDecay/gradients/StatefulPartitionedCall:2", shape=(None,), dtype=int32))) to a dense Tensor of unknown shape. This may consume a large amount of memory.
  "shape. This may consume a large amount of memory." % value)
266/267 [============================>.] - ETA: 0s - loss: 0.5234 - MatthewsCorrelationCoefficient: 0.0000e+00
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/metrics.py:257: UserWarning: Metric MatthewsCorrelationCoefficient implements a `reset_states()` method; rename it to `reset_state()` (without the final "s"). The name `reset_states()` has been deprecated to improve API consistency.
  'consistency.' % (self.__class__.__name__,))
267/267 [==============================] - 81s 73ms/step - loss: 0.5224 - MatthewsCorrelationCoefficient: 0.0000e+00 - val_loss: 0.5404 - val_MatthewsCorrelationCoefficient: 0.0000e+00
Epoch 2/3
267/267 [==============================] - 14s 54ms/step - loss: 0.3468 - MatthewsCorrelationCoefficient: 0.0000e+00 - val_loss: 0.6059 - val_MatthewsCorrelationCoefficient: 0.0000e+00
Epoch 3/3
267/267 [==============================] - 14s 54ms/step - loss: 0.2320 - MatthewsCorrelationCoefficient: 0.0000e+00 - val_loss: 0.6276 - val_MatthewsCorrelationCoefficient: 0.0000e+00

Экспорт для вывода

Вы создадите окончательную модель, которая будет иметь часть предварительной обработки и точно настроенный BERT, который мы только что создали.

Во время вывода предварительная обработка должна быть частью модели (потому что больше нет отдельной очереди ввода, как для обучающих данных, которые это делают). Предварительная обработка - это не просто вычисления; у него есть собственные ресурсы (таблица словаря), которые должны быть прикреплены к модели Keras, сохраненной для экспорта. Эта окончательная сборка будет сохранена.

Вы собираетесь сохранить модель в colab, а позже вы можете скачать ее, чтобы сохранить ее на будущее ( Просмотр -> Оглавление -> Файлы ).

main_save_path = './my_models'
bert_type = tfhub_handle_encoder.split('/')[-2]
saved_model_name = f'{tfds_name.replace("/", "_")}_{bert_type}'

saved_model_path = os.path.join(main_save_path, saved_model_name)

preprocess_inputs = bert_preprocess_model.inputs
bert_encoder_inputs = bert_preprocess_model(preprocess_inputs)
bert_outputs = classifier_model(bert_encoder_inputs)
model_for_export = tf.keras.Model(preprocess_inputs, bert_outputs)

print('Saving', saved_model_path)

# Save everything on the Colab host (even the variables from TPU memory)
save_options = tf.saved_model.SaveOptions(experimental_io_device='/job:localhost')
model_for_export.save(saved_model_path, include_optimizer=False,
                      options=save_options)
Saving ./my_models/glue_cola_bert_en_uncased_L-12_H-768_A-12
WARNING:absl:Found untraced functions such as restored_function_body, restored_function_body, restored_function_body, restored_function_body, restored_function_body while saving (showing 5 of 910). These functions will not be directly callable after loading.

Протестируйте модель

Последний шаг - тестирование результатов вашей экспортированной модели.

Чтобы провести некоторое сравнение, давайте перезагрузим модель и протестируем ее, используя некоторые входные данные из тестового разделения набора данных.

with tf.device('/job:localhost'):
  reloaded_model = tf.saved_model.load(saved_model_path)

Полезные методы

Контрольная работа

with tf.device('/job:localhost'):
  test_dataset = tf.data.Dataset.from_tensor_slices(in_memory_ds[test_split])
  for test_row in test_dataset.shuffle(1000).map(prepare).take(5):
    if len(sentence_features) == 1:
      result = reloaded_model(test_row[0])
    else:
      result = reloaded_model(list(test_row))

    print_bert_results(test_row, result, tfds_name)
sentence: [b'the putter on the table left.']
This sentence is acceptable
BERT raw results: tf.Tensor([-1.9087534  2.614734 ], shape=(2,), dtype=float32)

sentence: [b'Doug cleared the table of dishes.']
This sentence is acceptable
BERT raw results: tf.Tensor([-2.746095   3.2254264], shape=(2,), dtype=float32)

sentence: [b'I ran into the baker from whom I bought these bagels.']
This sentence is acceptable
BERT raw results: tf.Tensor([-2.7611763  2.8297088], shape=(2,), dtype=float32)

sentence: [b'I presented it to John dead.']
This sentence is unacceptable
BERT raw results: tf.Tensor([ 2.3774471 -2.079125 ], shape=(2,), dtype=float32)

sentence: [b'The only thing capable of consuming this food has four legs and flies.']
This sentence is acceptable
BERT raw results: tf.Tensor([-1.4872739  1.9206202], shape=(2,), dtype=float32)

Если вы хотите использовать свою модель для обслуживания TF , помните, что она будет вызывать вашу SavedModel через одну из своих именованных подписей. Обратите внимание, что во вводе есть небольшие отличия. В Python вы можете протестировать их следующим образом:

with tf.device('/job:localhost'):
  serving_model = reloaded_model.signatures['serving_default']
  for test_row in test_dataset.shuffle(1000).map(prepare_serving).take(5):
    result = serving_model(**test_row)
    # The 'prediction' key is the classifier's defined model name.
    print_bert_results(list(test_row.values()), result['prediction'], tfds_name)
sentence: b'There was believed to have been a riot in the kitchen.'
This sentence is acceptable
BERT raw results: tf.Tensor([-3.196773   2.9193494], shape=(2,), dtype=float32)

sentence: b'Tom swam the English Channel because he believed that Suzy ex.'
This sentence is acceptable
BERT raw results: tf.Tensor([-1.2277479  1.9688965], shape=(2,), dtype=float32)

sentence: b'I was convinced by John to leave.'
This sentence is acceptable
BERT raw results: tf.Tensor([-1.669661   2.0653794], shape=(2,), dtype=float32)

sentence: b'I can find the baker in whom to place your trust.'
This sentence is acceptable
BERT raw results: tf.Tensor([-2.5297134  2.9251165], shape=(2,), dtype=float32)

sentence: b'John promised Bill to be examined.'
This sentence is unacceptable
BERT raw results: tf.Tensor([ 2.2290623 -1.1185381], shape=(2,), dtype=float32)

Ты сделал это! Сохраненную модель можно использовать для обслуживания или простого вывода в процессе с более простым API, меньшим количеством кода и более простым в обслуживании.

Следующие шаги

Теперь, когда вы опробовали одну из базовых моделей BERT, вы можете попробовать другие для достижения большей точности или, возможно, с меньшими версиями моделей.

Вы также можете попробовать другие наборы данных.