Google I/O — это обертка! Наверстать упущенное в сеансах TensorFlow Просмотреть сеансы

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

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

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

  1. КОЛА (Corpus Лингвистического Приемлемость): Является ли предложение грамматически правильно?

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

  3. МНПК (Microsoft Research парафраз Corpus): Определить , является ли семантически эквивалентны пара предложений.

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

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

  6. QNLI (Вопрос-ответив Natural Language Умозаключение): Задача состоит в том, чтобы определить , содержит ли контекст предложение ответ на этот вопрос.

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

  8. WNLI (Виноград Natural Language Умозаключение): Задача состоит в том, чтобы предсказать , если предложение с местоимением подставляется влекут за первоначальным предложением.

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

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

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

Настраивать

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

pip install -q -U tensorflow-text

Вы будете использовать оптимизатор AdamW из tensorflow / моделей для тонкой настройки 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')
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/requests/__init__.py:104: RequestsDependencyWarning: urllib3 (1.26.7) or chardet (2.3.0)/charset_normalizer (2.0.7) doesn't match a supported version!
  RequestsDependencyWarning)

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

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

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

Это происходит потому , что ТПУ может читать только непосредственно из ведра Cloud Storage .

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

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

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

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.config.list_physical_devices('GPU'):
  strategy = tf.distribute.MirroredStrategy()
  print('Using GPU')
else:
  raise ValueError('Running on CPU is not recommended.')
Using TPU

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

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

  • БЕРТ-Base , бескорпусный и еще семь моделей с обученными весами , выпущенных оригинальными авторами BERT.
  • Малый Berts имеет одинаковую общую архитектуру , но меньше и / или меньшие Трансформаторные блоки, которая позволяет исследовать компромисс между скоростью, размером и качеством.
  • АЛЬБЕРТ : четыре различных размеров «A Lite BERT» , что уменьшает размер модели (но не время вычисления) путем обмена параметров между слоями.
  • BERT Эксперты : восемь моделей , которые все имеют БЕРТ-базовую архитектуру , но предлагают выбор между различными предварительно обучением доменами, более тесно увязать с целевой задачей.
  • Electra имеет ту же архитектуру, что и BERT (в трех разных размеров), но получает предварительно обучен как дискриминатор в подстроено , который напоминает Generative Состязательность Network (ГАН).
  • БЕРТ с Talking Heads-Вниманием и Gated Джелом [ базы , большие ] имеет два улучшений в ядро архитектуры трансформатора.

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

В этом руководстве вы начнете с 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 с Бертом colab модель предварительной обработки используется встраивать непосредственно с кодером BERT.

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

Требования ТПУ в сторону, это может помочь производительности у Preprocessing выполняется асинхронно во входном трубопроводе (Вы можете узнать больше в руководстве производительности 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_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). Выход какая модель БЕРТА бы ожидать в качестве входного: 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_word_ids', 'input_mask', 'input_type_ids']
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, show_shapes=True, show_dtype=True)
('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):

  class Classifier(tf.keras.Model):
    def __init__(self, num_classes):
      super(Classifier, self).__init__(name="prediction")
      self.encoder = hub.KerasLayer(tfhub_handle_encoder, trainable=True)
      self.dropout = tf.keras.layers.Dropout(0.1)
      self.dense = tf.keras.layers.Dense(num_classes)

    def call(self, preprocessed_text):
      encoder_outputs = self.encoder(preprocessed_text)
      pooled_output = encoder_outputs["pooled_output"]
      x = self.dropout(pooled_output)
      x = self.dense(x)
      return x

  model = Classifier(num_classes)
  return model

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

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

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

Вы собираетесь использовать TensorFlow DataSet из КЛЕЯ базового пакета.

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

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

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

Using glue/cola from TFDS
This dataset has 10657 examples
Number of classes: 2
Features ['sentence']
Splits ['train', 'validation', 'test']
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 предварительно обучения (как в Classify тексте с Бертом ): Он использует оптимизатор 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/keras/engine/functional.py:585: 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)
267/267 [==============================] - 86s 81ms/step - loss: 0.6092 - MatthewsCorrelationCoefficient: 0.0000e+00 - val_loss: 0.4846 - val_MatthewsCorrelationCoefficient: 0.0000e+00
Epoch 2/3
267/267 [==============================] - 14s 53ms/step - loss: 0.3774 - MatthewsCorrelationCoefficient: 0.0000e+00 - val_loss: 0.5322 - val_MatthewsCorrelationCoefficient: 0.0000e+00
Epoch 3/3
267/267 [==============================] - 14s 53ms/step - loss: 0.2623 - MatthewsCorrelationCoefficient: 0.0000e+00 - val_loss: 0.6469 - val_MatthewsCorrelationCoefficient: 0.0000e+00

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

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

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

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

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'An old woman languished in the forest.']
This sentence is acceptable
BERT raw results: tf.Tensor([-1.7032353  3.3714833], shape=(2,), dtype=float32)

sentence: [b"I went to the movies and didn't pick up the shirts."]
This sentence is acceptable
BERT raw results: tf.Tensor([-0.73970896  1.0806316 ], shape=(2,), dtype=float32)

sentence: [b"Every essay that she's written and which I've read is on that pile."]
This sentence is acceptable
BERT raw results: tf.Tensor([-0.7034159  0.6236454], shape=(2,), dtype=float32)

sentence: [b'Either Bill ate the peaches, or Harry.']
This sentence is unacceptable
BERT raw results: tf.Tensor([ 0.05972151 -0.08620442], 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([-1.6862067  3.285925 ], 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'Everyone attended more than two seminars.'
This sentence is acceptable
BERT raw results: tf.Tensor([-1.5594155  2.862155 ], shape=(2,), dtype=float32)

sentence: b'Most columnists claim that a senior White House official has been briefing them.'
This sentence is acceptable
BERT raw results: tf.Tensor([-1.6298996  3.3155093], shape=(2,), dtype=float32)

sentence: b"That my father, he's lived here all his life is well known to those cops."
This sentence is acceptable
BERT raw results: tf.Tensor([-1.2048947  1.8589772], shape=(2,), dtype=float32)

sentence: b'Ourselves like us.'
This sentence is acceptable
BERT raw results: tf.Tensor([-1.2723312  2.0494034], shape=(2,), dtype=float32)

sentence: b'John is clever.'
This sentence is acceptable
BERT raw results: tf.Tensor([-1.6516167  3.3147635], shape=(2,), dtype=float32)

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

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

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

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