Predicción de la siguiente oración usando BERT

Requisito previo : BERT-GFG

BERT significa Representación bidireccional para transformadores . Fue propuesto por investigadores de Google Research en 2018. Aunque, el objetivo principal era mejorar la comprensión del significado de las consultas relacionadas con la Búsqueda de Google. Un estudio muestra que Google encontró el 15% de las consultas nuevas todos los días. Por lo tanto, requiere que el motor de búsqueda de Google comprenda mucho mejor el idioma para comprender la consulta de búsqueda. 

Sin embargo, BERT está capacitado en una variedad de tareas diferentes para mejorar la comprensión del lenguaje del modelo. En este artículo, discutiremos las tareas bajo la siguiente oración de predicción para BERT.

Predicción de la siguiente oración usando BERT

BERT está ajustado en 3 métodos para la siguiente tarea de predicción de oraciones:

  • En el primer tipo, tenemos oraciones como entrada y solo hay una salida de etiqueta de clase, como para la siguiente tarea:
    • MNLI (Multi-Genre Natural Language Inference) : es una tarea de clasificación a gran escala. En esta tarea, hemos dado un par de oraciones. El objetivo es identificar si la segunda oración es una vinculación, una contradicción o neutral con respecto a la primera oración.
    • QQP (Pares de preguntas de Quora): en este conjunto de datos, el objetivo es determinar si dos preguntas son semánticamente iguales.
    • QNLI (inferencia de lenguaje natural de preguntas): en esta tarea, el modelo debe determinar si la segunda oración es la respuesta a la pregunta formulada en la primera oración.
    • SWAG (Situaciones con generaciones antagónicas): este conjunto de datos contiene 113k clasificaciones de oraciones. La tarea es determinar si la segunda oración es la continuación de la primera o no.

Arquitectura BERT primer tipo

  • En el segundo tipo, solo tenemos una oración como entrada, pero la salida es similar a la siguiente etiqueta de clase. A continuación se muestran las tareas/conjuntos de datos utilizados para ello:
    • SST-2 (The Stanford Sentiment Treebank): es una tarea de clasificación de oraciones binarias que consiste en oraciones extraídas de reseñas de películas con anotaciones de su sentimiento representado en la oración. BERT generó resultados de última generación en SST-2.
    • CoLA: (Corpus de Aceptabilidad Lingüística): es la tarea de clasificación binaria. El objetivo de esta tarea es predecir si una oración en inglés proporcionada es lingüísticamente aceptable o no.

Arquitectura BERT segundo tipo

  • En el tercer tipo de oración siguiente, predicción, se nos ha proporcionado una pregunta y un párrafo y se genera una oración del párrafo que es la respuesta a esa pregunta. Se realiza en conjuntos de datos SQuAD (Stanford Question Answer D) v1.1 y 2.0.

Arquitectura BERT 3er tipo.

En la arquitectura anterior, el token [CLS] es el primer token en la entrada. Esto significa que viene una oración de entrada, el [SEP] representa la separación entre las diferentes entradas. Aquí, la oración de entrada se tokeniza de acuerdo con el vocabulario BERT, y la salida también se tokeniza.

Implementación

  • En esta implementación, usaremos el conjunto de datos de preguntas Insinceras de Quora en el que tenemos algunas preguntas que pueden contener blasfemias, lenguaje obsceno, odio, etc. Usaremos BERT de TF-dev.

Python3

# Check if there is GPU or not
!nvidia-smi
# Install tensorflow 2.3.0
!pip install -q tensorflow==2.3.0
# Clone the TensorFlow models Repo
!git clone --depth 1 -b v2.3.0 https://github.com/tensorflow/models.git
!pip install -Uqr models/official/requirements.txt
# Imports
import sys
import numpy as np
import tensorflow as tf
import tensorflow_hub as hub
sys.path.append('models')
from official.nlp.data import classifier_data_lib
from official.nlp.bert import tokenization
from official.nlp import optimization
 
# keras imports
from tf.keras.layers import Input, Dropout, Dense
from tf.keras.optimizers import Adam
from tf.keras.metrics import BinaryAccuracy
from tf.keras.losses import BinaryCrossentropy
from tf.keras.utils import plot_model
from tf.keras.models import Model
# Load the Quora Insincrere QUesrtion dataset.
df = pd.read_csv(
  'https://archive.org/download/fine-tune-bert-tensorflow-train.csv/train.csv.zip',
                 compression='zip')
df.head()
# plot the histogram of sincere and insincere question vs sincere ques
df.target.plot(kind='hist', title='Sincere (0) vs Insincere (1) distribution')
qid question_text target
000002165364db923c7e6 How did Quebec nationalists see their province...0
1000032939017120e6e44 Do you have an adopted dog, how would you enco...0
20000412ca6e4628ce2cf Why does velocity affect time? Does velocity a...0
3000042bf85aa498cd78e How did Otto von Guericke used the Magdeburg h...0
40000455dfa3e01eae3af Can I convert montra helicon D to a mountain b...0

Sincero vs Insincero

  • En el código a continuación, usaremos solo el 1% de los datos para ajustar nuestro modelo Bert (alrededor de 13,000 ejemplos), también convertiremos los datos al formato requerido por BERT y para usar una ejecución ansiosa, usamos un python envoltura. Antes de hacer esto, necesitamos tokenizar el conjunto de datos usando el vocabulario de BERT.

Tarea de clasificación de Bert

Python3

# split into train and validation
train_df, remaining = train_test_split(df, train_size=0.01,
                                       stratify=df.target.values)
valid_df, _ = train_test_split(remaining,  train_size=0.001,
                               stratify=remaining.target.values)
train_df.shape, valid_df.shape
 
# import for processing dataset
from tf.data.Dataset import from_tensor_slices
from tf.data.experimental import AUTOTUNE
 
# convert dataset into tensor slices
with tf.device('/cpu:0'):
  train_data =from_tensor_slices((train_df.question_text.values,
                                                   train_df.target.values))
  valid_data = from_tensor_slices((valid_df.question_text.values,
                                                   valid_df.target.values))
     
  for text, label in train_data.take(2):
    print(text)
    print(label)
     
label_list = [0, 1] # Label categories
max_seq_length = 128 # maximum length of input sequences
train_batch_size = 32
 
# Get BERT layer and tokenizer:
bert_layer = hub.KerasLayer(
  "https://tfhub.dev/tensorflow/bert_en_uncased_L-12_H-768_A-12/2",
                            trainable=True)
vocab_file = bert_layer.resolved_object.vocab_file.asset_path.numpy()
do_lower_case = bert_layer.resolved_object.do_lower_case.numpy()
tokenizer = tokenization.FullTokenizer(vocab_file, do_lower_case)
 
# example
# convert to tokens ids and
tokenizer.convert_tokens_to_ids(
  tokenizer.wordpiece_tokenizer.tokenize('how are you?'))
 
# convert the dataset into the format required by BERT i.e we convert the row into
# input features (Token id, input mask, input type id ) and labels
 
def convert_to_bert_feature(text, label, label_list=label_list,
               max_seq_length=max_seq_length, tokenizer=tokenizer):
  example = classifier_data_lib.InputExample(guid = None,
                                            text_a = text.numpy(),
                                            text_b = None,
                                            label = label.numpy())
  feature = classifier_data_lib.convert_single_example(0, example, label_list,
                                    max_seq_length, tokenizer)
   
  return (feature.input_ids, feature.input_mask, feature.segment_ids,
          feature.label_id)
 
# wrap the dataset around the python function in order to use the tf
# datasets map function
def to_bert_feature_map(text, label):
   
  input_ids, input_mask, segment_ids, label_id = tf.py_function(
    convert_to_bert_feature,
    inp=[text, label],
    Tout=[tf.int32, tf.int32, tf.int32, tf.int32])
 
  # py_func doesn't set the shape of the returned tensors.
  input_ids.set_shape([max_seq_length])
  input_mask.set_shape([max_seq_length])
  segment_ids.set_shape([max_seq_length])
  label_id.set_shape([])
 
  x = {
        'input_word_ids': input_ids,
        'input_mask': input_mask,
        'input_type_ids': segment_ids
    }
  return (x, label_id)
with tf.device('/cpu:0'):
  # train
  train_data = (train_data.map(to_bert_feature_map,
                              num_parallel_calls=AUTOTUNE)
                          #.cache()
                          .shuffle(1000)
                          .batch(32, drop_remainder=True)
                          .prefetch(AUTOTUNE))
 
  # valid
  valid_data = (valid_data.map(to_bert_feature_map,
                            num_parallel_calls=AUTOTUNE)
                          .batch(32, drop_remainder=True)
                          .prefetch(AUTOTUNE))
 
# example format train and valid data
print("train data format",train_data.element_spec)
print("validation data format",valid_data.element_spec)
((13061, 3), (1293, 3))

#printed an example
tf.Tensor(b'What is your experience living in Venezuela in the current crisis? (2018)', shape=(), dtype=string)
tf.Tensor(0, shape=(), dtype=int64)

# converted to tokens
['how', 'are', 'you', '?']
[2129, 2024, 2017, 29632]

# train and validation data
# train
({'input_mask': TensorSpec(shape=(32, 128), dtype=tf.int32, name=None),
  'input_type_ids': TensorSpec(shape=(32, 128), dtype=tf.int32, name=None),
  'input_word_ids': TensorSpec(shape=(32, 128), dtype=tf.int32, name=None)},
 TensorSpec(shape=(32,), dtype=tf.int32, name=None))

# validation
({'input_mask': TensorSpec(shape=(32, 128), dtype=tf.int32, name=None),
  'input_type_ids': TensorSpec(shape=(32, 128), dtype=tf.int32, name=None),
  'input_word_ids': TensorSpec(shape=(32, 128), dtype=tf.int32, name=None)},
 TensorSpec(shape=(32,), dtype=tf.int32, name=None))
  • En este paso, envolveremos la capa BERT alrededor del modelo de Keras, lo ajustaremos para 4 épocas y trazaremos la precisión.

Python3

# define the keras model
# Building the model
def fine_tuned_model():
  input_word_ids = Input(shape=(max_seq_length,), dtype=tf.int32,
                                      name="input_word_ids")
  input_mask = Input(shape=(max_seq_length,), dtype=tf.int32,
                                  name="input_mask")
  input_type_ids = Input(shape=(max_seq_length,), dtype=tf.int32,
                                  name="input_type_ids")
 
  pooled_output, sequence_output = bert_layer([input_word_ids, input_mask,
                                               input_type_ids])
 
  drop = Dropout(0.4)(pooled_output)
  output = Dense(1, activation="sigmoid", name="output")(drop)
 
  model = Model(
    inputs={
        'input_word_ids': input_word_ids,
        'input_mask': input_mask,
        'input_type_ids': input_type_ids
    },
    outputs=output)
  return model
 
#compile the model
model = fine_tuned_model()
model.compile(optimizer=Adam(learning_rate=2e-5),
              loss=BinaryCrossentropy(),
              metrics=[BinaryAccuracy()])
model.summary()
#plot the model
plot_model(model=model, show_shapes=True)
# Train model
epochs = 4
history = model.fit(train_data,
                    validation_data=valid_data,
                    epochs=epochs,
                    verbose=1)
# plot the accuracy
def plot_graphs(history, metric):
  plt.plot(history.history[metric])
  plt.plot(history.history['val_'+metric], '')
  plt.xlabel("Epochs")
  plt.ylabel(metric)
  plt.legend([metric, 'val_'+metric])
  plt.show()
plot_graphs(history, 'binary_accuracy')
Model: "functional_1"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_word_ids (InputLayer)     [(None, 128)]        0                                            
__________________________________________________________________________________________________
input_mask (InputLayer)         [(None, 128)]        0                                            
__________________________________________________________________________________________________
input_type_ids (InputLayer)     [(None, 128)]        0                                            
__________________________________________________________________________________________________
keras_layer (KerasLayer)        [(None, 768), (None, 109482241   input_word_ids[0][0]             
                                                                 input_mask[0][0]                 
                                                                 input_type_ids[0][0]             
__________________________________________________________________________________________________
dropout (Dropout)               (None, 768)          0           keras_layer[0][0]                
__________________________________________________________________________________________________
output (Dense)                  (None, 1)            769         dropout[0][0]                    
==================================================================================================
Total params: 109,483,010
Trainable params: 109,483,009
Non-trainable params: 1
__________________________________________________________________________________________________

modelo Keras

Gráfico de precisión binaria

Python3

# check
test_eg=['what is the current marketprice of petroleum?',
         'who is Oswald?', 'why are you here idiot ?']
test_data =from_tensor_slices((test_eg, [0]*len(test_eg)))
# wrap test data into BERT format
test_data = (test_data.map(to_feature_map_bert).batch(1))
preds = model.predict(test_data)
print(preds)
['Insincere' if pred >=0.5 else 'Sincere' for pred in preds]
[[1.3862031e-05]
 [6.7259348e-04]
 [8.9223766e-01]]
['Sincere', 'Sincere', 'Insincere']

Referencia:

Publicación traducida automáticamente

Artículo escrito por pawangfg y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *