Risolvi le attività GLUE utilizzando BERT su TPU

Visualizza su TensorFlow.org Esegui in Google Colab Visualizza su GitHub Scarica taccuino Vedi il modello del mozzo TF

BERT può essere utilizzato per risolvere molti problemi nell'elaborazione del linguaggio naturale. Potrai imparare a perfezionare BERT per molte attività del benchmark COLLA :

  1. Cola (Corpus di linguistica accettabilità): E 'la frase grammaticalmente corretta?

  2. SST-2 (Stanford Sentiment Treebank): Il compito è quello di prevedere il sentimento di una determinata frase.

  3. MRPC (Microsoft Research Parafrasi Corpus): determinare se un paio di frasi sono semanticamente equivalenti.

  4. QQP (Quora Domanda Pairs2): determinare se un paio di domande sono semanticamente equivalenti.

  5. MnlI (multi-genere Natural Language Inference): condannato premessa e una frase ipotesi, il compito è quello di prevedere se la premessa comporta l'ipotesi (implicazione), contraddice l'ipotesi (contraddizione), o nessuno dei due (neutro).

  6. QNLI (Domanda-rispondendo Natural Language Inference): Il compito è quello di stabilire se la frase di contesto contiene la risposta alla domanda.

  7. RTE (Riconoscendo testuale Entailment): Determinare se una frase implica una data ipotesi o no.

  8. WNLI (Winograd Natural Language Inference): Il compito è quello di prevedere se la frase con il pronome sostituito è comportato dalla frase originale.

Questo tutorial contiene il codice end-to-end completo per addestrare questi modelli su una TPU. Puoi anche eseguire questo notebook su una GPU, modificando una riga (descritta di seguito).

In questo quaderno:

  • Carica un modello BERT da TensorFlow Hub
  • Scegli una delle attività GLUE e scarica il set di dati
  • Preelabora il testo
  • Ottimizzazione del BERT (sono forniti esempi per set di dati a frase singola e multifrase)
  • Salva il modello addestrato e usalo

Impostare

Utilizzerai un modello separato per preelaborare il testo prima di utilizzarlo per mettere a punto BERT. Questo modello dipende tensorflow / testo , che verrà installato sotto.

pip install -q -U tensorflow-text

Si utilizzerà l'ottimizzatore AdamW da tensorflow / modelli per perfezionare BERT, che verrà installato pure.

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)

Successivamente, configura TFHub per leggere i checkpoint direttamente dai bucket di Cloud Storage di TFHub. Questo è consigliato solo quando si eseguono modelli TFHub su TPU.

Senza questa impostazione, TFHub scaricherà il file compresso ed estrae il checkpoint localmente. Il tentativo di caricare da questi file locali avrà esito negativo con il seguente errore:

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

Questo perché il TPU può solo leggere direttamente da secchi Cloud Storage .

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

Connettiti al lavoratore TPU

Il codice seguente si connette al lavoratore TPU e cambia il dispositivo predefinito di TensorFlow nel dispositivo CPU sul lavoratore TPU. Definisce inoltre una strategia di distribuzione TPU che utilizzerai per distribuire l'addestramento del modello sugli 8 core TPU separati disponibili su questo unico lavoratore TPU. Vedi di tensorflow guida TPU per ulteriori informazioni.

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

Caricamento di modelli da TensorFlow Hub

Qui puoi scegliere quale modello BERT caricare da TensorFlow Hub e perfezionare. Sono disponibili più modelli BERT tra cui scegliere.

  • BERT-Base , uncased e altri sette modelli con pesi addestrati rilasciate dagli autori BERT originali.
  • Piccole BERT hanno la stessa architettura generale, ma meno e / o blocchi trasformatore più piccolo, che ti permette di esplorare compromessi tra velocità, dimensioni e qualità.
  • ALBERT : quattro diverse dimensioni di "A Lite BERT" che riduce la dimensione modello (ma non il tempo di calcolo) ripartendo parametri tra gli strati.
  • BERT Gli esperti : otto modelli che tutti hanno l'architettura BERT-base, ma offrono una scelta tra diversi domini di pre-formazione, per allineare più strettamente con il compito di destinazione.
  • Electra ha la stessa architettura BERT (in tre diverse dimensioni), ma viene pre-formato come discriminatore in un set-up che assomiglia a un contraddittorio rete Generativa (GAN).
  • BERT con Talking teste Attenzione e gated GELU [ basamento , grande ] ha due miglioramenti al nucleo dell'architettura trasformatore.

Vedere la documentazione del modello collegata sopra per maggiori dettagli.

In questo tutorial, inizierai con BERT-base. È possibile utilizzare modelli più grandi e più recenti per una maggiore precisione o modelli più piccoli per tempi di addestramento più rapidi. Per cambiare il modello, devi solo cambiare una singola riga di codice (mostrato sotto). Tutte le differenze sono incapsulate nel SavedModel che scaricherai da TensorFlow Hub.

Scegli un modello BERT da mettere a punto

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

Preelabora il testo

Sul testo adesso con BERT CoLab il modello pre-elaborazione viene utilizzato direttamente integrato con l'encoder BERT.

Questa esercitazione illustra come eseguire la preelaborazione come parte della pipeline di input per il training, usando Dataset.map e quindi unirlo nel modello che viene esportato per l'inferenza. In questo modo, sia l'addestramento che l'inferenza possono funzionare da input di testo non elaborato, sebbene la stessa TPU richieda input numerici.

Requisiti TPU a parte, possono aiutare le prestazioni hanno fatto in modo asincrono pre-elaborazione in una pipeline di input (si può imparare di più nella guida prestazioni tf.data ).

Questo tutorial mostra anche come creare modelli multi-input e come regolare la lunghezza della sequenza degli input in BERT.

Dimostriamo il modello di pre-elaborazione.

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

Ogni modello preelaborazione fornisce anche un metodo, .bert_pack_inputs(tensors, seq_length) , che prende un elenco di token (come tok sopra) e un argomento lunghezza della sequenza. Questo racchiude gli input per creare un dizionario di tensori nel formato previsto dal modello 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)

Ecco alcuni dettagli a cui prestare attenzione:

  • input_mask La maschera consente al modello di differenziare correttamente fra il contenuto e l'imbottitura. La maschera ha la stessa forma delle input_word_ids , e contiene un 1 ovunque i input_word_ids non viene imbottitura.
  • input_type_ids ha la stessa forma input_mask , ma all'interno della regione non-riempito, contiene uno 0 o un 1 indicando che frase il token è una parte di.

Successivamente, creerai un modello di pre-elaborazione che incapsula tutta questa logica. Il tuo modello prenderà le stringhe come input e restituirà oggetti formattati in modo appropriato che possono essere passati a BERT.

Ogni modello BERT ha un modello di pre-elaborazione specifico, assicurati di utilizzare quello corretto descritto nella documentazione del modello 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)

Dimostriamo il modello di pre-elaborazione. Creerai un test con due frasi di input (input1 e input2). L'uscita è ciò che un modello BERT si aspetta come input: input_word_ids , input_masks e 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)

Diamo un'occhiata alla struttura del modello, prestando attenzione ai due input appena definiti.

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

Per applicare la pre-elaborazione in tutti gli ingressi dal set di dati, si utilizzerà la map funzione dal set di dati. Il risultato viene poi memorizzato nella cache per prestazioni .

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

Definisci il tuo modello

Ora sei pronto per definire il tuo modello per la classificazione di frasi o coppie di frasi alimentando gli input preelaborati tramite l'encoder BERT e inserendo un classificatore lineare in cima (o un'altra disposizione di livelli come preferisci) e utilizzando il dropout per la regolarizzazione.

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

Proviamo a eseguire il modello su alcuni input preelaborati.

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)

Scegli un'attività da GLUE

Avete intenzione di utilizzare un tensorflow DataSet dal COLLA suite di benchmark.

Colab ti consente di scaricare questi piccoli set di dati nel filesystem locale e il codice seguente li legge interamente in memoria, poiché l'host di lavoro TPU separato non può accedere al filesystem locale del runtime di colab.

Per i set di dati più grandi, sarà necessario creare il proprio Google Cloud Storage secchio e avere il lavoratore TPU leggere i dati da lì. Potete saperne di più nella guida TPU .

Si consiglia di iniziare con il set di dati CoLa (per una frase singola) o MRPC (per più frasi) poiché sono piccoli e non richiedono molto tempo per la messa a punto.

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)

Il set di dati determina anche il tipo di problema (classificazione o regressione) e la funzione di perdita appropriata per l'addestramento.

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

Allena il tuo modello

Infine, puoi addestrare il modello end-to-end sul set di dati che hai scelto.

Distribuzione

Richiama il codice di configurazione in alto, che ha connesso il runtime colab a un lavoratore TPU con più dispositivi TPU. Per distribuire la formazione su di essi, creerai e compilerai il tuo modello Keras principale nell'ambito della strategia di distribuzione TPU. (Per i dettagli, vedere Distributed allenamento con Keras .)

La preelaborazione, d'altra parte, viene eseguita sulla CPU dell'host di lavoro, non sulle TPU, quindi il modello Keras per la preelaborazione e i set di dati di addestramento e convalida mappati con esso sono costruiti al di fuori dell'ambito della strategia di distribuzione. La chiamata a Model.fit() si occuperà di distribuire il passato-nel set di dati al modello repliche.

Ottimizzatore

Messa a punto segue l'ottimizzatore di set-up da BERT pre-formazione (come nel testo adesso con BERT ): utilizza l'ottimizzatore AdamW con un decadimento lineare di un tasso di apprendimento iniziale nozionale, preceduto da una fase lineare di warm-up rispetto al primo il 10% dei passaggi di formazione ( num_warmup_steps ). In linea con il documento BERT, il tasso di apprendimento iniziale è inferiore per la messa a punto (migliore di 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

Esporta per inferenza

Creerai un modello finale che ha la parte di pre-elaborazione e il BERT messo a punto che abbiamo appena creato.

Al momento dell'inferenza, la pre-elaborazione deve essere parte del modello (perché non esiste più una coda di input separata come per i dati di addestramento che lo fa). La pre-elaborazione non è solo calcolo; dispone di risorse proprie (la tabella vocab) che devono essere allegate al Keras Model che viene salvato per l'esportazione. Questo assemblaggio finale è ciò che verrà salvato.

Si sta per salvare il modello sul CoLab e in seguito è possibile scaricare per conservare per il futuro (Visualizza -> Indice -> File).

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.

Prova il modello

Il passaggio finale consiste nel testare i risultati del modello esportato.

Giusto per fare un confronto, ricarichiamo il modello e testiamolo utilizzando alcuni input dal test diviso dal set di dati.

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

Metodi di utilità

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

Se si desidera utilizzare il modello sul Servire TF , ricordate che esso chiamerà il SavedModel attraverso una delle sue firme di nome. Notare che ci sono alcune piccole differenze nell'input. In Python, puoi testarli come segue:

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)

Ce l'hai fatta! Il tuo modello salvato potrebbe essere utilizzato per servire o semplice inferenza in un processo, con un'API più semplice con meno codice e più facile da mantenere.

Prossimi passi

Ora che hai provato uno dei modelli BERT di base, puoi provarne altri per ottenere una maggiore precisione o magari con versioni del modello più piccole.

Puoi anche provare in altri set di dati.