¡Google I / O regresa del 18 al 20 de mayo! Reserva espacio y crea tu horario Regístrate ahora
Se usó la API de Cloud Translation para traducir esta página.
Switch to English

Resuelva las tareas de GLUE usando BERT en TPU

Ver en TensorFlow.org Ejecutar en Google Colab Ver en GitHub Descargar cuaderno Ver modelo TF Hub

BERT se puede utilizar para resolver muchos problemas en el procesamiento del lenguaje natural. Aprenderá cómo ajustar BERT para muchas tareas desde el punto de referencia GLUE :

  1. CoLA (Corpus of Linguistic Acceptability): ¿Es la oración gramaticalmente correcta?

  2. SST-2 (Stanford Sentiment Treebank): la tarea es predecir el sentimiento de una oración determinada.

  3. MRPC (Microsoft Research Paraphrase Corpus): determina si un par de oraciones son semánticamente equivalentes.

  4. QQP (Quora Question Pairs2): determina si un par de preguntas son semánticamente equivalentes.

  5. MNLI (Inferencia de lenguaje natural multigénero): Dada una oración de premisa y una oración de hipótesis, la tarea es predecir si la premisa implica la hipótesis (implicación), contradice la hipótesis (contradicción) o ninguna (neutral).

  6. QNLI (Inferencia de lenguaje natural de respuesta a preguntas): la tarea es determinar si la oración de contexto contiene la respuesta a la pregunta.

  7. RTE (Recognizing Textual Entailment): determina si una oración implica una hipótesis dada o no.

  8. WNLI (Inferencia del lenguaje natural de Winograd): la tarea es predecir si la oración con el pronombre sustituido está implicada por la oración original.

Este tutorial contiene código completo de un extremo a otro para entrenar estos modelos en una TPU. También puede ejecutar este portátil en una GPU, cambiando una línea (que se describe a continuación).

En este cuaderno, podrá:

  • Cargar un modelo BERT desde TensorFlow Hub
  • Elija una de las tareas de GLUE y descargue el conjunto de datos
  • Preprocesar el texto
  • Ajuste BERT (se dan ejemplos para conjuntos de datos de una o varias oraciones)
  • Guarde el modelo entrenado y utilícelo

Configuración

Utilizará un modelo separado para preprocesar el texto antes de usarlo para ajustar BERT. Este modelo depende de tensorflow / text , que instalará a continuación.

pip install -q -U tensorflow-text

Utilizará el optimizador AdamW de tensorflow / models para ajustar BERT, que también instalará.

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

A continuación, configure TFHub para leer puntos de control directamente desde los depósitos de almacenamiento en la nube de TFHub. Esto solo se recomienda cuando se ejecutan modelos TFHub en TPU.

Sin esta configuración, TFHub descargaría el archivo comprimido y extraería el punto de control localmente. Intentar cargar desde estos archivos locales fallará con el siguiente error:

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

Esto se debe a que la TPU solo puede leer directamente desde los depósitos de Cloud Storage .

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

Conectarse al trabajador de TPU

El siguiente código se conecta al trabajador de TPU y cambia el dispositivo predeterminado de TensorFlow al dispositivo de CPU en el trabajador de TPU. También define una estrategia de distribución de TPU que usarás para distribuir el entrenamiento del modelo en los 8 núcleos de TPU separados disponibles en este trabajador de TPU. Consulta la guía de TPU de TensorFlow para obtener más información.

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

Carga de modelos desde TensorFlow Hub

Aquí puede elegir qué modelo BERT cargará desde TensorFlow Hub y ajustarlo. Hay varios modelos BERT disponibles para elegir.

  • BERT-Base , Uncased y siete modelos más con pesos entrenados lanzados por los autores originales de BERT.
  • Los BERT pequeños tienen la misma arquitectura general pero menos bloques Transformer o más pequeños, lo que le permite explorar las compensaciones entre velocidad, tamaño y calidad.
  • ALBERT : cuatro tamaños diferentes de "A Lite BERT" que reduce el tamaño del modelo (pero no el tiempo de cálculo) al compartir parámetros entre capas.
  • Expertos en BERT : ocho modelos que tienen todos la arquitectura basada en BERT pero ofrecen la posibilidad de elegir entre diferentes dominios de formación previa, para alinearse más estrechamente con la tarea objetivo.
  • Electra tiene la misma arquitectura que BERT (en tres tamaños diferentes), pero se entrena previamente como discriminador en una configuración que se asemeja a una Red Adversarial Generativa (GAN).
  • BERT con Talking-Heads Attention y Gated GELU [ base , grande ] tiene dos mejoras en el núcleo de la arquitectura Transformer.

Consulte la documentación del modelo vinculada anteriormente para obtener más detalles.

En este tutorial, comenzará con BERT-base. Puede utilizar modelos más grandes y más recientes para una mayor precisión, o modelos más pequeños para tiempos de entrenamiento más rápidos. Para cambiar el modelo, solo necesita cambiar una sola línea de código (que se muestra a continuación). Todas las diferencias están encapsuladas en el modelo guardado que descargará de TensorFlow Hub.

Elija un modelo BERT para ajustarlo

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

Preprocesar el texto

En Classify text with BERT colab, el modelo de preprocesamiento se utiliza directamente incrustado con el codificador BERT.

En este instructivo, se muestra cómo realizar el procesamiento previo como parte de su canalización de entrada para el entrenamiento, usando Dataset.map, y luego fusionarlo en el modelo que se exporta para la inferencia. De esa manera, tanto el entrenamiento como la inferencia pueden funcionar a partir de entradas de texto sin formato, aunque la propia TPU requiere entradas numéricas.

Dejando a un lado los requisitos de TPU, puede ayudar al rendimiento a que el preprocesamiento se realice de forma asincrónica en una canalización de entrada (puede obtener más información en la guía de rendimiento de tf.data ).

Este tutorial también demuestra cómo construir modelos de múltiples entradas y cómo ajustar la longitud de secuencia de las entradas a BERT.

Demostremos el modelo de preprocesamiento.

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

Cada modelo de preprocesamiento también proporciona un método, .bert_pack_inputs(tensors, seq_length) , que toma una lista de tokens (como tok arriba) y un argumento de longitud de secuencia. Esto empaqueta las entradas para crear un diccionario de tensores en el formato esperado por el modelo 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)

Aquí hay algunos detalles a los que debe prestar atención:

  • input_mask La máscara permite al modelo diferenciar claramente entre el contenido y el relleno. La máscara tiene la misma forma que input_word_ids y contiene un 1 en cualquier lugar en el que input_word_ids no esté relleno.
  • input_type_ids tiene la misma forma que input_mask , pero dentro de la región no rellenada, contiene un 0 o un 1 que indica de qué oración forma parte el token.

A continuación, creará un modelo de preprocesamiento que encapsula toda esta lógica. Su modelo tomará cadenas como entrada y devolverá objetos con el formato adecuado que se pueden pasar a BERT.

Cada modelo BERT tiene un modelo de preprocesamiento específico, asegúrese de utilizar el adecuado descrito en la documentación del modelo 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)

Demostremos el modelo de preprocesamiento. Creará una prueba con dos oraciones input (input1 y input2). El resultado es lo que un modelo BERT esperaría como entrada: input_word_ids , input_masks y 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_mask', 'input_type_ids', 'input_word_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)

Echemos un vistazo a la estructura del modelo, prestando atención a las dos entradas que acaba de definir.

tf.keras.utils.plot_model(test_preprocess_model)
('Failed to import pydot. You must `pip install pydot` and install graphviz (https://graphviz.gitlab.io/download/), ', 'for `pydotprint` to work.')

Para aplicar el preprocesamiento en todas las entradas del conjunto de datos, utilizará la función de map del conjunto de datos. Luego, el resultado se almacena en caché para el rendimiento .

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

Define tu modelo

Ahora está listo para definir su modelo para la clasificación de oraciones o pares de oraciones alimentando las entradas preprocesadas a través del codificador BERT y colocando un clasificador lineal en la parte superior (u otra disposición de capas que prefiera), y utilizando la salida para regularización.

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

Intentemos ejecutar el modelo en algunas entradas preprocesadas.

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

Echemos un vistazo a la estructura del modelo. Puede ver las tres entradas esperadas de BERT.

tf.keras.utils.plot_model(test_classifier_model)
('Failed to import pydot. You must `pip install pydot` and install graphviz (https://graphviz.gitlab.io/download/), ', 'for `pydotprint` to work.')

Elija una tarea de GLUE

Vas a utilizar un TensorFlow DataSet del paquete de pruebas GLUE .

Colab le permite descargar estos pequeños conjuntos de datos al sistema de archivos local, y el código a continuación los lee completamente en la memoria, porque el host trabajador de TPU independiente no puede acceder al sistema de archivos local del tiempo de ejecución de colab.

Para conjuntos de datos más grandes, deberá crear su propio depósito de Google Cloud Storage y hacer que el trabajador de TPU lea los datos desde allí. Puede obtener más información en la guía de TPU .

Se recomienda comenzar con el conjunto de datos CoLa (para una sola oración) o MRPC (para varias oraciones), ya que son pequeños y no tardan mucho en ajustarse.

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)

El conjunto de datos también determina el tipo de problema (clasificación o regresión) y la función de pérdida apropiada para el entrenamiento.

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

Entrena tu modelo

Por último, puede entrenar el modelo de un extremo a otro en el conjunto de datos que elija.

Distribución

Recuerde el código de configuración en la parte superior, que ha conectado el tiempo de ejecución de colab a un trabajador de TPU con varios dispositivos de TPU. Para distribuir la capacitación sobre ellos, creará y compilará su modelo principal de Keras dentro del alcance de la estrategia de distribución de TPU. (Para obtener más información, consulte Capacitación distribuida con Keras ).

El preprocesamiento, por otro lado, se ejecuta en la CPU del host trabajador, no en las TPU, por lo que el modelo de Keras para el preprocesamiento, así como los conjuntos de datos de entrenamiento y validación asignados con él, se construyen fuera del alcance de la estrategia de distribución. La llamada a Model.fit() se encargará de distribuir el conjunto de datos pasado a las réplicas del modelo.

Optimizador

El ajuste fino sigue la configuración del optimizador del preentrenamiento de BERT (como en Clasificar texto con BERT ): utiliza el optimizador AdamW con una caída lineal de una tasa de aprendizaje inicial teórica, precedida de una fase de calentamiento lineal sobre la 10% de pasos de entrenamiento ( num_warmup_steps ). De acuerdo con el documento BERT, la tasa de aprendizaje inicial es menor para el ajuste fino (mejor de 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:595: 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:437: 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 [==============================] - 79s 77ms/step - loss: 0.5812 - MatthewsCorrelationCoefficient: 0.5968 - val_loss: 0.4688 - val_MatthewsCorrelationCoefficient: 0.5871
Epoch 2/3
267/267 [==============================] - 15s 58ms/step - loss: 0.3561 - MatthewsCorrelationCoefficient: 0.5906 - val_loss: 0.5723 - val_MatthewsCorrelationCoefficient: 0.5871
Epoch 3/3
267/267 [==============================] - 15s 58ms/step - loss: 0.2352 - MatthewsCorrelationCoefficient: 0.5909 - val_loss: 0.6748 - val_MatthewsCorrelationCoefficient: 0.5871

Exportar para inferencia

Creará un modelo final que tiene la parte de preprocesamiento y el BERT ajustado que acabamos de crear.

En el momento de la inferencia, el preprocesamiento debe ser parte del modelo (porque ya no hay una cola de entrada separada para los datos de entrenamiento que lo hace). El preprocesamiento no es solo un cálculo; tiene sus propios recursos (la tabla de vocabulario) que deben adjuntarse al modelo de Keras que se guarda para la exportación. Esta asamblea final es la que se salvará.

Vas a guardar el modelo en colab y luego puedes descargarlo para guardarlo para el futuro ( Ver -> Tabla de contenido -> Archivos ).

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

Prueba el modelo

El último paso es probar los resultados de su modelo exportado.

Solo para hacer una comparación, recarguemos el modelo y probémoslo usando algunas entradas de la división de prueba del conjunto de datos.

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

Métodos de utilidad

Prueba

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'Onto the table jumped a cat.']
This sentence is acceptable
BERT raw results: tf.Tensor([-1.5364362  3.0245366], shape=(2,), dtype=float32)

sentence: [b'it is important to John to leave.']
This sentence is acceptable
BERT raw results: tf.Tensor([-2.1081586  4.0080795], shape=(2,), dtype=float32)

sentence: [b'Gina filled the pitcher with lemonade.']
This sentence is acceptable
BERT raw results: tf.Tensor([-2.5824902  3.740626 ], shape=(2,), dtype=float32)

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

sentence: [b'The student hated his morphology professor.']
This sentence is acceptable
BERT raw results: tf.Tensor([-2.4559186  3.5234451], shape=(2,), dtype=float32)

Si desea utilizar su modelo en TF Serving , recuerde que llamará a su SavedModel a través de una de sus firmas nombradas. Observe que hay algunas pequeñas diferencias en la entrada. En Python, puede probarlos de la siguiente manera:

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'His loves him'
This sentence is unacceptable
BERT raw results: tf.Tensor([ 2.160802  -2.4170692], shape=(2,), dtype=float32)

sentence: b'John says Mary likes himself.'
This sentence is unacceptable
BERT raw results: tf.Tensor([ 1.759533  -2.0088294], shape=(2,), dtype=float32)

sentence: b'He treats John very under.'
This sentence is acceptable
BERT raw results: tf.Tensor([-0.19971004  1.1566539 ], shape=(2,), dtype=float32)

sentence: b'Karen asked where him to vote for.'
This sentence is unacceptable
BERT raw results: tf.Tensor([ 2.1606677 -2.1753395], shape=(2,), dtype=float32)

sentence: b"I didn't give Jack Ed's picture of anybody."
This sentence is unacceptable
BERT raw results: tf.Tensor([ 1.755337 -1.904901], shape=(2,), dtype=float32)

¡Lo hiciste! Su modelo guardado podría usarse para servir o realizar inferencias simples en un proceso, con una API más simple con menos código y más fácil de mantener.

Próximos pasos

Ahora que ha probado uno de los modelos básicos de BERT, puede probar otros para lograr una mayor precisión o tal vez con versiones de modelos más pequeñas.

También puede probar con otros conjuntos de datos.