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.
- 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.
- 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.
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
- 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.
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 __________________________________________________________________________________________________
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']