Rozwiązuj zadania GLUE za pomocą BERT na TPU

Zobacz na TensorFlow.org Uruchom w Google Colab Zobacz na GitHub Pobierz notatnik Zobacz model piasty TF

BERT może być używany do rozwiązywania wielu problemów w przetwarzaniu języka naturalnego. Dowiesz się, jak dostroić BERT wielu zadań z benchmarku KLEJOWYM :

  1. Cola (Corpus Linguistic DOPUSZCZALNOŚCI): Czy zdanie poprawne gramatycznie?

  2. SST-2 (Stanford Sentyment bank drzew): Zadanie jest przewidzieć nastrojów danego zdania.

  3. MRPC (Microsoft Research Parafraza Corpus): Określenie, czy parę zdań są semantycznie równoważne.

  4. QQP (Quora Pytanie Pary2): Określenie, czy parę pytań są semantycznie równoważne.

  5. MNLI (Multi-Gatunek Wnioskowanie Natural Language): Biorąc pod uwagę zdanie i zdanie przesłanka hipoteza, zadaniem jest przewidzieć, czy przesłanka wiąże się hipotezy (wynikania), sprzeczne hipotezy (sprzeczność), czy nie (neutralny).

  6. QNLI (pytanie-odpowiadając Wnioskowanie Natural Language): Zadanie ma na celu określenie, czy zdanie kontekst zawiera odpowiedź na pytanie.

  7. RTE (uznając tekstowy wynikania): Określ, czy zdanie wiąże daną hipotezę, czy też nie.

  8. WNLI (Winograd Wnioskowanie Natural Language): Zadanie jest przewidzieć, czy zdanie z zaimkiem podstawiana jest logiczną konsekwencją wyroku pierwotnego.

Ten samouczek zawiera kompletny kompleksowy kod do trenowania tych modeli na TPU. Możesz także uruchomić ten notatnik na GPU, zmieniając jeden wiersz (opisany poniżej).

W tym notatniku będziesz:

  • Załaduj model BERT z TensorFlow Hub
  • Wybierz jedno z zadań GLUE i pobierz zestaw danych
  • Wstępnie przetwórz tekst
  • Dostosuj BERT (podano przykłady dla jednozdaniowych i wielozdaniowych zestawów danych)
  • Zapisz wytrenowany model i użyj go

Organizować coś

Użyjesz oddzielnego modelu do wstępnego przetworzenia tekstu przed użyciem go do dostrojenia BERT. Model ten zależy tensorflow / tekstu , który zostanie zainstalowany poniżej.

pip install -q -U tensorflow-text

Będziesz korzystać z optymalizatora AdamW z tensorflow / modeli dostrojenie BERT, który zostanie zainstalowany również.

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')
/home/kbuilder/.local/lib/python3.6/site-packages/requests/__init__.py:104: RequestsDependencyWarning: urllib3 (1.26.6) or chardet (2.3.0)/charset_normalizer (2.0.4) doesn't match a supported version!
  RequestsDependencyWarning)

Następnie skonfiguruj TFHub tak, aby odczytywał punkty kontrolne bezpośrednio z zasobników Cloud Storage TFHub. Jest to zalecane tylko w przypadku uruchamiania modeli TFHub na TPU.

Bez tego ustawienia program TFHub pobrałby skompresowany plik i lokalnie wyodrębniłby punkt kontrolny. Próba załadowania z tych plików lokalnych zakończy się niepowodzeniem z następującym błędem:

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

To dlatego, że TPU można tylko odczytać bezpośrednio z wiadra Cloud Storage .

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

Połącz się z pracownikiem TPU

Poniższy kod łączy się z pracownikiem TPU i zmienia domyślne urządzenie TensorFlow na urządzenie CPU w pracowniku TPU. Definiuje również strategię dystrybucji TPU, której będziesz używać do dystrybucji trenowania modelu na 8 oddzielnych rdzeni TPU dostępnych dla tego jednego pracownika TPU. Zobacz TensorFlow za TPU instrukcji , aby uzyskać więcej informacji.

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

Ładowanie modeli z TensorFlow Hub

Tutaj możesz wybrać, który model BERT załadujesz z TensorFlow Hub i dostroić. Do wyboru jest wiele modeli BERT.

  • BERT-Base , nieobudowanego i siedem więcej modeli z przeszkolonych ciężarami uwalnianych przez pierwotnych autorów BERT.
  • Małe Berts mają taką samą ogólną architekturę, ale mniej i / lub mniejszych bloków transformator, który pozwala badać kompromisów pomiędzy szybkością, wielkości i jakości.
  • ALBERT : cztery różne rozmiary „lite BERT”, który redukuje rozmiar modelu (ale nie czas obliczeń) poprzez wymianę parametrów pomiędzy warstwami.
  • BERT Eksperci : osiem modeli, które mają architekturę Bert-bazowy ale oferują wybór między różnymi domenami pre-szkoleniowych, aby ściślej wyrównać z zadaniem docelowym.
  • Electra ma taką samą architekturę Bert (w trzech różnych rozmiarach), ale zostaje wstępnie przeszkolony jako dyskryminatora w zestawie-up, który przypomina Generative kontradyktoryjności Network (GAN).
  • BERT z mówieniem głowic uwagę i Gated Gelu [ bazowej , duży ] posiada dwa ulepszenia do rdzenia architektury transformatora.

Więcej informacji można znaleźć w dokumentacji modelu, do której link znajduje się powyżej.

W tym samouczku zaczniesz od BERT-base. Możesz użyć większych i nowszych modeli, aby uzyskać większą dokładność, lub mniejszych modeli, aby przyspieszyć czas treningu. Aby zmienić model, wystarczy przełączyć tylko jedną linię kodu (pokazano poniżej). Wszystkie różnice są zawarte w SavedModel, który pobierzesz z TensorFlow Hub.

Wybierz model BERT do dostrojenia

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

Wstępnie przetwórz tekst

Z tekstu klasyfikować z Bertem colab model przerób służy bezpośrednio wbudowane kodera BERT.

W tym samouczku pokazano, jak wykonać wstępne przetwarzanie w ramach potoku wejściowego na potrzeby uczenia przy użyciu Dataset.map, a następnie scalić go z modelem, który zostanie wyeksportowany w celu wnioskowania. W ten sposób zarówno uczenie, jak i wnioskowanie może działać na podstawie nieprzetworzonych danych wejściowych tekstowych, chociaż sama TPU wymaga danych wejściowych liczbowych.

Wymagania TPU na bok, może pomóc wydajność mają przerób odbywa się asynchronicznie w rurociągu wejściowego (można dowiedzieć się więcej w przewodniku wydajności tf.data ).

Ten samouczek pokazuje również, jak budować modele z wieloma danymi wejściowymi i jak dostosować długość sekwencji danych wejściowych do BERT.

Zademonstrujmy model przetwarzania wstępnego.

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

Każdy model przerób zapewnia również metodę .bert_pack_inputs(tensors, seq_length) , która pobiera listę znaczników (np tok powyżej), a długość sekwencji argumentu. To pakuje dane wejściowe w celu utworzenia słownika tensorów w formacie oczekiwanym przez model 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)

Oto kilka szczegółów, na które należy zwrócić uwagę:

  • input_mask Maska umożliwia model do czysto rozróżniania zawartości i wypełnienia. Maska ma taki sam kształt jak input_word_ids i zawiera 1 Anywhere input_word_ids nie dopełnienia.
  • input_type_ids ma taki sam kształt jak input_mask , ale wewnątrz regionu niewypełnionego, zawiera 0 lub 1, które wskazuje, zdanie znacznik jest częścią.

Następnie utworzysz model przetwarzania wstępnego, który zawiera całą tę logikę. Twój model przyjmie ciągi znaków jako dane wejściowe i zwróci odpowiednio sformatowane obiekty, które można przekazać do BERT.

Każdy model BERT ma określony model przetwarzania wstępnego, upewnij się, że używasz właściwego, opisanego w dokumentacji modelu 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)

Zademonstrujmy model przetwarzania wstępnego. Utworzysz test z dwoma zdaniami wejściowymi (input1 i input2). Wyjście jest co model BERT spodziewałbym jako wkład: input_word_ids , input_masks i 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)

Przyjrzyjmy się strukturze modelu, zwracając uwagę na dwa właśnie zdefiniowane dane wejściowe.

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.')

Aby zastosować wstępne przetwarzanie we wszystkich wejściach z zestawu danych, można skorzystać z map funkcji ze zbioru danych. Wynik jest następnie buforowane dla wydajności .

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

Zdefiniuj swój model

Jesteś teraz gotowy do zdefiniowania swojego modelu klasyfikacji zdań lub par zdań, wprowadzając wstępnie przetworzone dane wejściowe przez koder BERT i umieszczając na górze klasyfikator liniowy (lub inny układ warstw, jak wolisz), a następnie używając odrzucania do regularyzacji.

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

Spróbujmy uruchomić model na kilku wstępnie przetworzonych danych wejściowych.

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

Wybierz zadanie z GLUE

Masz zamiar użyć TensorFlow DataSet z GLUE pakietu benchmarku.

Colab umożliwia pobranie tych małych zestawów danych do lokalnego systemu plików, a poniższy kod wczytuje je w całości do pamięci, ponieważ oddzielny host roboczy TPU nie może uzyskać dostępu do lokalnego systemu plików środowiska wykonawczego colab.

Dla większych zbiorów danych, musisz stworzyć swój własny Google Cloud Storage wiadro i mieć pracownik TPU odczytać dane stamtąd. Więcej informacji można znaleźć w przewodniku TPU .

Zaleca się zacząć od zestawu danych CoLa (dla pojedynczego zdania) lub MRPC (dla wielu zdań), ponieważ są one małe i dostrojenie nie trwa długo.

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)

Zestaw danych określa również typ problemu (klasyfikacja lub regresja) oraz odpowiednią funkcję straty do treningu.

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

Wytrenuj swoją modelkę

Na koniec możesz trenować model od początku do końca na wybranym zestawie danych.

Dystrybucja

Przypomnij kod konfiguracji u góry, który połączył środowisko wykonawcze colab z pracownikiem TPU z wieloma urządzeniami TPU. Aby przekazać im szkolenia, utworzysz i skompilujesz swój główny model Keras w ramach strategii dystrybucji TPU. (Aby uzyskać szczegółowe informacje, zobacz Rozproszone szkolenia z Keras ).

Z drugiej strony przetwarzanie wstępne działa na procesorze hosta procesu roboczego, a nie na jednostkach TPU, więc model Keras do przetwarzania wstępnego oraz zmapowane za jego pomocą zestawy danych uczenia i walidacji są budowane poza zakresem strategii dystrybucji. Wezwanie do Model.fit() zajmie się dystrybucją przekazany w zbiorze danych do modelu replik.

Optymalizator

Dostrajanie następuje konfiguracja optymalizatora z BERT pre-szkolenia (jak w tekście klasyfikować z Bertem ): Używa optymalizator AdamW liniowej rozkładu hipotetycznego początkowej szybkości uczenia się, z prefiksem z liniowej fazy rozgrzewania nad pierwszym 10% fazy treningowych ( num_warmup_steps ). Zgodnie z dokumentem BERT, początkowa szybkość uczenia się jest mniejsza w przypadku dostrajania (najlepsza z 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.5384 - MatthewsCorrelationCoefficient: 0.0000e+00 - val_loss: 0.5082 - val_MatthewsCorrelationCoefficient: 0.0000e+00
Epoch 2/3
267/267 [==============================] - 14s 53ms/step - loss: 0.3510 - MatthewsCorrelationCoefficient: 0.0000e+00 - val_loss: 0.4895 - val_MatthewsCorrelationCoefficient: 0.0000e+00
Epoch 3/3
267/267 [==============================] - 14s 54ms/step - loss: 0.2331 - MatthewsCorrelationCoefficient: 0.0000e+00 - val_loss: 0.6271 - val_MatthewsCorrelationCoefficient: 0.0000e+00

Eksport do wnioskowania

Stworzysz ostateczny model, który będzie zawierał część do obróbki wstępnej i dopracowany BERT, który właśnie stworzyliśmy.

W czasie wnioskowania przetwarzanie wstępne musi być częścią modelu (ponieważ nie ma już oddzielnej kolejki wejściowej, jak w przypadku danych uczących, które to robią). Wstępne przetwarzanie to nie tylko obliczenia; posiada własne zasoby (tablicę vocab), które należy dołączyć do modelu Keras, który jest zapisany do eksportu. To ostateczne zgromadzenie jest tym, co zostanie zbawione.

Masz zamiar zapisać model na colab a później można pobrać, aby utrzymać go na przyszłość (Widok -> Spis treści -> Pliki).

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.

Przetestuj model

Ostatnim krokiem jest przetestowanie wyników wyeksportowanego modelu.

Aby dokonać porównania, przeładujmy model i przetestujmy go, używając niektórych danych wejściowych z testu podzielonego ze zbioru danych.

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

Metody użytkowe

Test

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'I will try to meet at 6.']
This sentence is acceptable
BERT raw results: tf.Tensor([-2.5220253  1.8490468], shape=(2,), dtype=float32)

sentence: [b'Cornelia lodged in the new boarding house.']
This sentence is acceptable
BERT raw results: tf.Tensor([-3.1192958  2.7799528], shape=(2,), dtype=float32)

sentence: [b'Both workers will wear carnations.']
This sentence is acceptable
BERT raw results: tf.Tensor([-2.237738   3.2021792], shape=(2,), dtype=float32)

sentence: [b'Medea murdered']
This sentence is unacceptable
BERT raw results: tf.Tensor([ 0.56222165 -2.260996  ], shape=(2,), dtype=float32)

sentence: [b'List all experts for the defendant who represented themselves.']
This sentence is acceptable
BERT raw results: tf.Tensor([-2.087904   1.6495142], shape=(2,), dtype=float32)

Jeśli chcesz korzystać z modelu na TF porcji , należy pamiętać, że będzie to zadzwoń do SavedModel przez jednego z jego nazwanych podpisów. Zauważ, że są pewne małe różnice w danych wejściowych. W Pythonie możesz je przetestować w następujący sposób:

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"While Perry might switch the TV off, he won't on."
This sentence is acceptable
BERT raw results: tf.Tensor([-1.6701834  0.8465962], shape=(2,), dtype=float32)

sentence: b'Pat took a seat available.'
This sentence is unacceptable
BERT raw results: tf.Tensor([ 1.3545492 -2.9612012], shape=(2,), dtype=float32)

sentence: b'That Pat is innocent proves.'
This sentence is unacceptable
BERT raw results: tf.Tensor([ 1.2258279 -2.2433956], shape=(2,), dtype=float32)

sentence: b'The jeweller printed the name.'
This sentence is acceptable
BERT raw results: tf.Tensor([-2.266377   1.8589431], shape=(2,), dtype=float32)

sentence: b'Paul breathed on Mary.'
This sentence is acceptable
BERT raw results: tf.Tensor([-2.676597   2.8310988], shape=(2,), dtype=float32)

Zrobiłeś to! Zapisany model może być używany do obsługi lub prostego wnioskowania w procesie z prostszym interfejsem API z mniejszą ilością kodu i łatwiejszym w utrzymaniu.

Następne kroki

Teraz, gdy wypróbowałeś jeden z podstawowych modeli BERT, możesz wypróbować inne, aby osiągnąć większą dokładność lub być może z mniejszymi wersjami modeli.

Możesz też spróbować w innych zestawach danych.