Construyendo Modelos de Lenguaje Una Guía de Implementación Paso a Paso de BERT

'Construyendo Modelos de Lenguaje Guía de Implementación de BERT'

Introducción

Los avances en modelos de aprendizaje automático que procesan lenguaje han sido rápidos en los últimos años. Este progreso ha salido del laboratorio de investigación y está comenzando a impulsar algunos de los principales productos digitales. Un gran ejemplo es el anuncio de que los modelos BERT son ahora una fuerza significativa detrás de la Búsqueda de Google. Google cree que este avance en la comprensión del lenguaje natural aplicado a la búsqueda representa “el salto más grande en los últimos cinco años y uno de los más grandes en la historia de la búsqueda”. Vamos a entender qué es BERT.

BERT significa Representaciones de Codificador Bidireccional de Transformadores. Su diseño implica el preentrenamiento de representaciones bidireccionales profundas a partir del texto no etiquetado, condicionando tanto los contextos izquierdos como los derechos. Podemos mejorar el modelo preentrenado de BERT para diferentes tareas de procesamiento del lenguaje natural agregando solo una capa adicional de salida.

Objetivos de aprendizaje

  • Comprender la arquitectura y los componentes de BERT.
  • Aprender los pasos de preprocesamiento necesarios para la entrada de BERT y cómo manejar longitudes variables de secuencia de entrada.
  • Adquirir conocimientos prácticos sobre cómo implementar BERT utilizando frameworks populares de aprendizaje automático como TensorFlow o PyTorch.
  • Aprender cómo ajustar finamente BERT para tareas específicas posteriores, como clasificación de texto o reconocimiento de entidades nombradas.

Ahora surgirá otra pregunta, ¿por qué necesitamos eso? Permítanme explicarlo.

Este artículo fue publicado como parte del Blogatón de Ciencia de Datos.

¿Por qué necesitamos BERT?

La representación adecuada del lenguaje es la capacidad de las máquinas para comprender el lenguaje general. Los modelos sin contexto como word2Vec o GloVe generan una representación de incrustación de palabras única para cada palabra en el vocabulario. Por ejemplo, el término “grúa” tendría la misma representación en “grúa en el cielo” y en “grúa para levantar objetos pesados”. Los modelos contextuales representan cada palabra en función de las otras palabras en la oración. Por lo tanto, BERT es un modelo contextual que captura estas relaciones en ambas direcciones.

BERT se basa en trabajos recientes e ideas inteligentes en representaciones contextuales de preentrenamiento, incluido el Aprendizaje de Secuencias Semi-Supervisadas, el Preentrenamiento Generativo, ELMo, el Transformer de OpenAI, ULMFit y el Transformer. Aunque estos modelos son todos unidireccionales o bidireccionales superficialmente, BERT es completamente bidireccional.

Podemos entrenar los modelos BERT en nuestros datos para un propósito específico, como análisis de sentimientos o respuesta a preguntas, para proporcionar predicciones avanzadas, o podemos usarlos para extraer características de lenguaje de alta calidad de nuestros datos de texto. La siguiente pregunta que viene a la mente es: “¿Qué está pasando detrás de esto?” Sigamos adelante para entender esto.

¿Cuál es la idea principal detrás de esto?

Para entender las ideas primero, necesitamos saber algunas cosas como:

  • ¿Qué es el modelado del lenguaje?
  • ¿Qué problema intentan resolver los modelos de lenguaje?

Tomemos un ejemplo: Completemos el espacio en blanco basado en el contexto para entender esto.

Un modelo de lenguaje (enfoque unidireccional) completará esta oración diciendo que las palabras son:

  • carro
  • par

La mayoría de los encuestados (80%) elegirán “par”, mientras que el 20% seleccionará “carro” correctamente. Ambas opciones son legítimas, pero ¿cuál debería tenerse en cuenta? Seleccionemos la palabra apropiada para completar el espacio en blanco utilizando diversas técnicas.

Ahora entra en juego BERT, un modelo de lenguaje entrenado en ambas direcciones. Esto significa que tenemos un sentido más profundo del contexto del lenguaje que los modelos de lenguaje unidireccionales.

Además, BERT se basa en la arquitectura del modelo Transformer en lugar de LSTMs.

Arquitectura de BERT

BERT (Representaciones de Codificador Bidireccional de Transformadores) es una arquitectura de modelo de lenguaje basada en transformadores. Consiste en múltiples capas de autoatención y redes neuronales de avance. BERT utiliza un enfoque bidireccional para capturar información contextual de las palabras anteriores y siguientes en una oración. Hay cuatro tipos de versiones preentrenadas de BERT dependiendo de la escala de la arquitectura del modelo:

1) BERT-Base (Cased / Un-Cased): 12 capas, 768 nodos ocultos, 12 cabezales de atención, 110M parámetros

2) BERT-Large (Cased / Un-Cased): 24 capas, 1024 nodos ocultos, 16 cabezas de atención, 340M parámetros

Según tus requisitos, puedes seleccionar los pesos pre-entrenados de BERT. Por ejemplo, seguiremos con los modelos base si no tenemos acceso a Google TPU. Y luego, la elección entre “cased” (con mayúsculas) y “uncased” (sin mayúsculas) depende de si las mayúsculas son útiles para la tarea en cuestión. Vamos a profundizar en ello.

¿Cómo funciona?

BERT funciona aprovechando el poder del pre-entrenamiento no supervisado seguido del ajuste fino supervisado. Esta sección cubrirá dos áreas: la preprocesamiento de texto y las tareas de pre-entrenamiento.

Preprocesamiento de texto

Un Transformer fundamental consta de un codificador para leer la entrada de texto y un decodificador para producir una predicción de tarea. Solo se necesita el elemento codificador de BERT porque su objetivo es crear un modelo de representación de lenguaje. La entrada al codificador de BERT es una secuencia de tokens convertidos primero en vectores. Luego, la red neuronal los procesa.

Para empezar, cada incrustación de entrada combina las siguientes tres incrustaciones:

Las incrustaciones de token, segmentación y posición se suman para formar la representación de entrada de BERT.

  • Incrustaciones de token: Al comienzo de la primera oración, se agrega un token [CLS] a los tokens de palabras de entrada, y después de cada oración, se agrega un token [SEP].
  • Incrustaciones de segmentos: Cada token recibe una marca que designa la Oración A o la Oración B. De esta manera, el codificador puede identificar qué oraciones son.
  • Incrustaciones posicionales: Cada token recibe una incrustación posicional para mostrar dónde pertenece en la oración.

Tareas de pre-entrenamiento

BERT ya ha completado dos tareas de procesamiento del lenguaje natural:

1. Modelado de lenguaje enmascarado

El modelado de lenguaje consiste en predecir la siguiente palabra a partir de una cadena de palabras. En el modelado de lenguaje enmascarado, algunos tokens de entrada se enmascaran aleatoriamente y solo se pronostican esos tokens enmascarados en lugar del token que le sigue.

  • Token [MASK]: Este token indica que falta otro token.
  • El token enmascarado [MASK] no siempre se utiliza para reemplazar las palabras enmascaradas porque, en ese caso, los tokens enmascarados nunca se mostrarían antes del ajuste fino. Por lo tanto, se realiza una selección aleatoria para el 15% de los tokens. Además, de ese 15% de tokens elegidos para el enmascaramiento:

2. Predicción de la siguiente oración

La tarea de predicción de la siguiente oración evalúa si la segunda oración de un par sigue genuinamente a la primera oración. Existe un problema de clasificación binaria.

La construcción de este trabajo a partir de cualquier corpus monolingüe es fácil. Reconocer la conexión entre dos oraciones es beneficioso ya que es necesario para diversas tareas posteriores como preguntas y respuestas e inferencia de lenguaje natural.

Implementación de BERT

La implementación de BERT (Representaciones de Codificador Bidireccional a partir de Transformadores) implica utilizar modelos pre-entrenados de BERT y ajustarlos al tarea específica. Esto incluye tokenizar los datos de texto, codificar secuencias, definir la arquitectura del modelo, entrenar el modelo y evaluar su rendimiento. La implementación de BERT ofrece potentes capacidades de modelado de lenguaje, lo que permite realizar tareas influyentes de procesamiento del lenguaje natural como clasificación de texto y análisis de sentimientos. Aquí tienes una lista de pasos para implementar BERT:

  • Importar bibliotecas y conjunto de datos requeridos
  • Dividir el conjunto de datos en entrenamiento/prueba
  • Importar BERT – base- uncased
  • Tokenizar y codificar las secuencias
  • Lista a tensores
  • Cargador de datos
  • Arquitectura del modelo
  • Ajuste fino
  • Realizar predicciones

Comencemos con el enunciado del problema.

Enunciado del problema

El objetivo es crear un sistema que pueda clasificar mensajes SMS como spam o no spam. Este sistema tiene como objetivo mejorar la experiencia del usuario y prevenir posibles amenazas de seguridad al identificar y filtrar con precisión los mensajes de spam. La tarea implica desarrollar un modelo que distinga entre mensajes de spam y mensajes legítimos, lo que permite una detección y acción rápidas contra mensajes no deseados.

Tenemos varios mensajes SMS, ese es el problema. La mayoría de estos mensajes son auténticos. Sin embargo, algunos de ellos son spam. Nuestro objetivo es crear un sistema que pueda determinar instantáneamente si un texto es spam o no. Enlace del conjunto de datos: ()

Importar bibliotecas y conjunto de datos necesarios

Importa las bibliotecas y conjuntos de datos necesarios para la tarea en cuestión. Prepara el entorno cargando las dependencias necesarias y pone el conjunto de datos disponible para su posterior procesamiento y análisis.

import numpy as np
import pandas as pd
import torch
import torch.nn as nn
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
import transformers
from transformers import AutoModel, BertTokenizerFast

# especificar GPU
device = torch.device("cuda")

df = pd.read_csv("../input/spamdatatest/spamdata_v2.csv")
df.head()

El conjunto de datos consiste en dos columnas: “label” y “text”. La columna “text” contiene el cuerpo del mensaje y la “label” es una variable binaria donde 1 significa spam y 0 representa el mensaje que no es spam.

# verificar la distribución de clases
df['label'].value_counts(normalize = True)

Dividir el conjunto de datos en entrenamiento/prueba

Dividir un conjunto de datos para entrenamiento en conjuntos de entrenamiento, validación y prueba.

Dividimos el conjunto de datos en tres partes según los parámetros dados utilizando una biblioteca como la función train_test_split de scikit-learn.

Los conjuntos resultantes, es decir, train_text, val_text y test_text, van acompañados de sus respectivas etiquetas: train_labels, val_labels y test_labels. Estos conjuntos se pueden utilizar para entrenar, validar y probar el modelo de aprendizaje automático.

Evaluar el rendimiento del modelo en datos hipotéticos permite evaluar los modelos y evitar el sobreajuste adecuadamente.

# dividir el conjunto de datos de entrenamiento en conjuntos de entrenamiento, validación y prueba
train_text, temp_text, train_labels, temp_labels = train_test_split(df['text'], df['label'], 
                                                                    random_state=2018, 
                                                                    test_size=0.3, 
                                                                    stratify=df['label'])


val_text, test_text, val_labels, test_labels = train_test_split(temp_text, temp_labels, 
                                                                random_state=2018, 
                                                                test_size=0.5, 
                                                                stratify=temp_labels)

Importar BERT-Base-Uncased

El modelo pre-entrenado BERT-base se importa utilizando la función AutoModel.from_pretrained() de la biblioteca Transformers de Hugging Face. Esto permite a los usuarios acceder a la arquitectura BERT y sus pesos pre-entrenados para poder realizar tareas de procesamiento de lenguaje poderosas.

También se carga el tokenizador de BERT utilizando la función BertTokenizerFast.from_pretrained(). El tokenizador se encarga de convertir el texto de entrada en tokens que BERT comprende. El tokenizador ‘Bert-base-uncased’ está diseñado específicamente para manejar texto en minúsculas y está alineado con el modelo pre-entrenado ‘Bert-base-uncased’.

# importar el modelo pre-entrenado BERT-base
bert = AutoModel.from_pretrained('bert-base-uncased')

# Cargar el tokenizador de BERT
tokenizer = BertTokenizerFast.from_pretrained('bert-base-uncased')

# obtener la longitud de todos los mensajes en el conjunto de entrenamiento
seq_len = [len(i.split()) for i in train_text]

pd.Series(seq_len).hist(bins = 30)

Tokenizar y codificar las secuencias

¿Cómo implementa BERT la tokenización?

Para la tokenización, BERT utiliza WordPiece.

Inicializamos el vocabulario con todos los caracteres individuales del idioma y luego lo actualizamos iterativamente con las combinaciones más frecuentes/probables de las palabras existentes.

Para mantener la consistencia, la longitud de la secuencia de entrada se restringe a 512 caracteres.

Utilizamos el tokenizador de BERT para tokenizar y codificar las secuencias en los conjuntos de entrenamiento, validación y prueba. Al utilizar la función tokenizer.batch_encode_plus(), las secuencias de texto se transforman en tokens numéricos.

Para la uniformidad en la longitud de las secuencias, se establece una longitud máxima de 25 para cada conjunto. Cuando se establece el parámetro pad_to_max_length=True, las secuencias se rellenan o truncan según corresponda. Las secuencias más largas que la longitud máxima especificada se truncan cuando se habilita el parámetro truncation=True.

# tokenizar y codificar secuencias en el conjunto de entrenamiento
tokens_train = tokenizer.batch_encode_plus(
    train_text.tolist(),
    max_length = 25,
    pad_to_max_length=True,
    truncation=True
)

# tokenizar y codificar secuencias en el conjunto de validación
tokens_val = tokenizer.batch_encode_plus(
    val_text.tolist(),
    max_length = 25,
    pad_to_max_length=True,
    truncation=True
)

# tokenizar y codificar secuencias en el conjunto de prueba
tokens_test = tokenizer.batch_encode_plus(
    test_text.tolist(),
    max_length = 25,
    pad_to_max_length=True,
    truncation=True
)

Lista a Tensores

Para convertir las secuencias tokenizadas y las etiquetas correspondientes en tensores utilizando PyTorch. La función “torch.tensor()” crea tensores a partir de las secuencias tokenizadas y las etiquetas.

Para cada conjunto (entrenamiento, validación y prueba), las secuencias de entrada tokenizadas se convierten en tensores utilizando “torch.tensor(tokens_train[‘input_ids’])”. De manera similar, las máscaras de atención se convierten en tensores utilizando “torch.tensor(tokens_train[‘attention_mask’])”. Convertimos las etiquetas a tensores utilizando “torch.tensor(train_labels.tolist())”.

La conversión de los datos a tensores permite una computación eficiente y compatibilidad con modelos de PyTorch, lo que permite un procesamiento y entrenamiento adicionales utilizando BERT u otros modelos en el ecosistema de PyTorch.

convertir listas a tensores

train_seq = torch.tensor(tokens_train[‘input_ids’]) train_mask = torch.tensor(tokens_train[‘attention_mask’]) train_y = torch.tensor(train_labels.tolist())

val_seq = torch.tensor(tokens_val[‘input_ids’]) val_mask = torch.tensor(tokens_val[‘attention_mask’]) val_y = torch.tensor(val_labels.tolist())

test_seq = torch.tensor(tokens_test[‘input_ids’]) test_mask = torch.tensor(tokens_test[‘attention_mask’]) test_y = torch.tensor(test_labels.tolist())

Cargador de Datos

La creación de cargadores de datos utilizando las clases TensorDataset, DataLoader, RandomSampler y SequentialSampler de PyTorch. La clase TensorDataset envuelve las secuencias de entrada, las máscaras de atención y las etiquetas en un solo objeto de conjunto de datos.

Utilizamos RandomSampler para muestrear aleatoriamente el conjunto de entrenamiento, asegurando una representación diversa de los datos durante el entrenamiento. Por otro lado, utilizamos SequentialSampler para el conjunto de validación para probar los datos de manera secuencial.

Para facilitar la iteración y el agrupamiento eficientes de los datos durante el entrenamiento y la validación, utilizamos DataLoader. Esta herramienta permite la creación de iteradores sobre los conjuntos de datos con un tamaño de lote designado, agilizando el proceso.

from torch.utils.data import TensorDataset, DataLoader, RandomSampler, SequentialSampler

#define a batch size
batch_size = 32

# envolver tensores
train_data = TensorDataset(train_seq, train_mask, train_y)

# muestreador para muestrear los datos durante el entrenamiento
train_sampler = RandomSampler(train_data)

# DataLoader para el conjunto de entrenamiento
train_dataloader = DataLoader(train_data, sampler=train_sampler, batch_size=batch_size)

# envolver tensores
val_data = TensorDataset(val_seq, val_mask, val_y)

# muestreador para muestrear los datos durante el entrenamiento
val_sampler = SequentialSampler(val_data)

# DataLoader para el conjunto de validación
val_dataloader = DataLoader(val_data, sampler = val_sampler, batch_size=batch_size)

Arquitectura del Modelo

La clase BERT_Arch extiende la clase nn.Module e inicializa el modelo BERT como un parámetro. Al establecer que los parámetros del modelo BERT no requieren gradientes (param.requires_grad = False), nos aseguramos de que solo los parámetros de las capas añadidas se entrenen durante el proceso de entrenamiento. Esta técnica nos permite aprovechar el modelo BERT pre-entrenado para el aprendizaje por transferencia y adaptarlo a una tarea específica.

# congelar todos los parámetros
for param in bert.parameters():
    param.requires_grad = False

La arquitectura consiste en una capa de dropout, una función de activación ReLU, dos capas densas (con 768 y 512 unidades, respectivamente) y una función de activación softmax. El método forward toma las IDs de las frases y las máscaras como entradas, las pasa a través del modelo BERT para obtener la salida del token de clasificación (cls_hs) y luego aplica las capas y activaciones definidas para producir las probabilidades de clasificación finales.

class BERT_Arch(nn.Module):

    def __init__(self, bert):
        super(BERT_Arch, self).__init__()
        
        self.bert = bert 
        
        # capa de dropout
        self.dropout = nn.Dropout(0.1)
      
        # función de activación ReLU
        self.relu =  nn.ReLU()

        # capa densa 1
        self.fc1 = nn.Linear(768,512)
      
        # capa densa 2 (capa de salida)
        self.fc2 = nn.Linear(512,2)

        # función de activación softmax
        self.softmax = nn.LogSoftmax(dim=1)

    # definir el pase hacia adelante
    def forward(self, sent_id, mask):
        
        # pasar las entradas al modelo  
        _, cls_hs = self.bert(sent_id, attention_mask=mask, return_dict=False)
      
        x = self.fc1(cls_hs)

        x = self.relu(x)

        x = self.dropout(x)

        # capa de salida
        x = self.fc2(x)
      
        # aplicar la activación softmax
        x = self.softmax(x)

        return x

Para inicializar una instancia de la clase BERT_Arch con el modelo BERT como argumento, pasamos el modelo BERT preentrenado a la arquitectura definida, BERT_Arch. Esto establece el modelo BERT como la base de la arquitectura personalizada.

Aceleración de GPU

El modelo se mueve a la GPU llamando al método to() y especificando el dispositivo deseado (device) para aprovechar la aceleración de la GPU. Esto permite realizar cálculos más rápidos durante el entrenamiento y la inferencia utilizando las capacidades de procesamiento paralelo de la GPU.

# pasar el modelo BERT preentrenado a nuestra arquitectura definida
modelo = BERT_Arch(bert)

# enviar el modelo a la GPU
modelo = modelo.to(device)

El optimizador AdamW de Hugging Face importa la biblioteca Transformers. AdamW es una variante del optimizador Adam que incluye regularización de decaimiento de peso.

A continuación, se define el optimizador pasando los parámetros del modelo (modelo.parameters()) y la tasa de aprendizaje (lr) de 1e-5 al constructor del optimizador AdamW. Este optimizador actualizará los parámetros del modelo durante el entrenamiento, optimizando el rendimiento del modelo en la tarea en cuestión.

# optimizador de Hugging Face Transformers
from transformers import AdamW

# definir el optimizador
optimizador = AdamW(modelo.parameters(),lr = 1e-5)

La función compute_class_weight del módulo sklearn.utils.class_weight se utiliza para calcular los pesos de clase con varios parámetros para las etiquetas de entrenamiento.

from sklearn.utils.class_weight import compute_class_weight

# calcular los pesos de clase
class_weights = compute_class_weight(‘balanced’, np.unique(train_labels), train_labels)

print(“Pesos de Clase:”,class_weights)

Para convertir los pesos de clase en un tensor, moverlo a la GPU y definir la función de pérdida con los pesos de clase ponderados. El número de épocas de entrenamiento se establece en 10.

# convertir la lista de pesos de clase en un tensor
pesos = torch.tensor(class_weights,dtype=torch.float)

# enviar a la GPU
pesos = pesos.to(device)

# definir la función de pérdida
entropia_cruzada = nn.NLLLoss(weight=pesos) 

# número de épocas de entrenamiento
epocas = 10

Ajuste Fino

Una función de entrenamiento que itera sobre lotes de datos realiza pases hacia adelante y hacia atrás, actualiza los parámetros del modelo y calcula la pérdida de entrenamiento. La función también almacena las predicciones del modelo y devuelve la pérdida promedio y las predicciones.

# función para entrenar el modelo
def entrenar():
    
    modelo.train()
    total_pérdida, exactitud_total = 0, 0
  
    # lista vacía para guardar las predicciones del modelo
    total_predicciones=[]
  
    # iterar sobre los lotes
    for paso,lote in enumerate(train_dataloader):
        
        # actualización de progreso después de cada 50 lotes.
        if paso % 50 == 0 and not paso == 0:
            print('  Lote {:>5,}  de  {:>5,}.'.format(paso, len(train_dataloader)))
        
        # enviar el lote a la gpu
        lote = [r.to(device) for r in lote]
 
        sent_id, mask, etiquetas = lote
        
        # borrar los gradientes calculados previamente 
        modelo.zero_grad()        

        # obtener las predicciones del modelo para el lote actual
        predicciones = modelo(sent_id, mask)

        # calcular la pérdida entre los valores reales y predichos
        pérdida = entropia_cruzada(predicciones, etiquetas)

        # agregar a la pérdida total
        total_pérdida = total_pérdida + pérdida.item()

        # pase hacia atrás para calcular los gradientes
        pérdida.backward()

        # recortar los gradientes a 1.0. Ayuda a prevenir el problema del gradiente explosivo
        torch.nn.utils.clip_grad_norm_(modelo.parameters(), 1.0)

        # actualizar los parámetros
        optimizador.step()

        # las predicciones del modelo se almacenan en la GPU. Entonces, se envían a la CPU
        predicciones=predicciones.detach().cpu().numpy()

    # agregar las predicciones del modelo
    total_predicciones.append(predicciones)

    # calcular la pérdida de entrenamiento de la época
    pérdida_promedio = total_pérdida / len(train_dataloader)
  
      # las predicciones están en forma de (número de lotes, tamaño del lote, número de clases).
      # remodelar las predicciones en forma de (número de muestras, número de clases)
    total_predicciones  = np.concatenate(total_predicciones, axis=0)

    # devolver la pérdida y las predicciones
    return pérdida_promedio, total_predicciones

Una función de evaluación que evalúa el modelo en los datos de validación. Calcula la pérdida de validación, almacena las predicciones del modelo y devuelve la pérdida promedio y las predicciones. La función desactiva las capas de dropout y realiza pasos hacia adelante sin cálculo de gradientes utilizando torch.no_grad().

# función para evaluar el modelo
def evaluar():
    
    print("\nEvaluando...")
  
    # desactivar las capas de dropout
    model.eval()

    total_pérdida, total_precisión = 0, 0
    
    # lista vacía para guardar las predicciones del modelo
    total_predicciones = []

    # iterar sobre los lotes
    for paso, lote in enumerate(val_dataloader):
        
        # Actualización de progreso cada 50 lotes.
        if paso % 50 == 0 and not paso == 0:
            
            # Calcular el tiempo transcurrido en minutos.
            transcurrido = format_time(time.time() - t0)
            
            # Informar progreso.
            print('  Lote {:>5,}  de  {:>5,}.'.format(paso, len(val_dataloader)))

        # enviar el lote a la gpu
        lote = [t.to(device) for t in lote]

        sent_id, mask, etiquetas = lote

        # desactivar autograd
        with torch.no_grad():
            
            # predicciones del modelo
            preds = model(sent_id, mask)

            # calcular la pérdida de validación entre los valores reales y predichos
            pérdida = cross_entropy(preds, etiquetas)

            total_pérdida = total_pérdida + pérdida.item()

            preds = preds.detach().cpu().numpy()

            total_predicciones.append(preds)

    # calcular la pérdida de validación de la época
    pérdida_promedio = total_pérdida / len(val_dataloader) 

    # remodelar las predicciones en forma de (número de muestras, número de clases)
    total_predicciones  = np.concatenate(total_predicciones, axis=0)

    return pérdida_promedio, total_predicciones

Entrenar el Modelo

Para entrenar el modelo durante el número especificado de épocas. Realiza un seguimiento de la mejor pérdida de validación, guarda los pesos del modelo si la pérdida de validación actual es mejor y agrega las pérdidas de entrenamiento y validación a sus respectivas listas. Las pérdidas de entrenamiento y validación se imprimen para cada época.

# establecer la pérdida inicial como infinita
mejor_pérdida_validación = float('inf')

# definir las épocas
épocas = 1

# listas vacías para almacenar la pérdida de entrenamiento y validación de cada época
pérdidas_entrenamiento=[]
pérdidas_validación=[]

# para cada época
for época in range(épocas):
     
    print('\n Época {:} / {:}'.format(época + 1, épocas))
    
    # entrenar el modelo
    pérdida_entrenamiento, _ = entrenar()
    
    # evaluar el modelo
    pérdida_validación, _ = evaluar()
    
    # guardar el mejor modelo
    if pérdida_validación < mejor_pérdida_validación:
        mejor_pérdida_validación = pérdida_validación
        torch.save(model.state_dict(), 'saved_weights.pt')
    
    # agregar la pérdida de entrenamiento y validación
    pérdidas_entrenamiento.append(pérdida_entrenamiento)
    pérdidas_validación.append(pérdida_validación)
    
    print(f'\nPérdida de Entrenamiento: {pérdida_entrenamiento:.3f}')
    print(f'Pérdida de Validación: {pérdida_validación:.3f}')

Para cargar los mejores pesos del modelo desde el archivo guardado ‘saved_weights.pt’ utilizando torch.load() y establecerlos en el modelo utilizando model.load_state_dict().

# cargar los pesos del mejor modelo
ruta = ‘saved_weights.pt’
model.load_state_dict(torch.load(ruta))

Realizar Predicciones

Para hacer predicciones sobre los datos de prueba utilizando el modelo entrenado y convertir las predicciones en arreglos de NumPy. Calculamos métricas de clasificación, incluyendo precisión, recall y F1-score, para evaluar el rendimiento del modelo utilizando la función classification_report del módulo metrics de scikit-learn.

# obtener predicciones para los datos de prueba
with torch.no_grad():
    predicciones = model(test_seq.to(device), test_mask.to(device))
    predicciones = predicciones.detach().cpu().numpy()

# rendimiento del modelo
predicciones = np.argmax(predicciones, axis = 1)
print(classification_report(test_y, predicciones))

Conclusión

En conclusión, BERT es sin duda un avance en el uso del Aprendizaje Automático para el Procesamiento del Lenguaje Natural. El hecho de que sea accesible y permita un ajuste rápido seguramente permitirá una amplia gama de aplicaciones prácticas en el futuro. Este tutorial paso a paso de implementación de BERT capacita a los usuarios para construir modelos de lenguaje potentes que puedan comprender y generar lenguaje natural de manera precisa.

Aquí hay algunos puntos críticos sobre BERT:

  • Éxito de BERT: BERT ha revolucionado el campo del procesamiento del lenguaje natural con su capacidad para capturar representaciones contextualizadas profundas, lo que ha llevado a mejoras notables en el rendimiento en varias tareas de NLP.
  • Accesibilidad para todos: Este tutorial tiene como objetivo hacer que la implementación de BERT sea accesible para una amplia gama de usuarios, independientemente de su nivel de experiencia. Siguiendo la guía paso a paso, cualquier persona puede aprovechar el poder de BERT y construir modelos de lenguaje sofisticados.
  • Aplicaciones en el mundo real: La versatilidad de BERT permite su aplicación a problemas del mundo real en diversas industrias, que incluyen análisis de sentimientos de los clientes, chatbots, sistemas de recomendación y más. Su implementación puede generar beneficios e ideas tangibles para empresas e investigadores.

Preguntas frecuentes

Los medios mostrados en este artículo no son propiedad de Analytics Vidhya y se utilizan a discreción del autor.

We will continue to update Zepes; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

Inteligencia Artificial

DreamBooth Difusión estable para imágenes personalizadas

Introducción Bienvenido al mundo de las técnicas de Difusión Estable para crear imágenes personalizadas, donde la cre...

Inteligencia Artificial

Utilizando el lenguaje para dar a los robots una mejor comprensión del mundo abierto

El método de Campos de Características para la Manipulación Robótica ayuda a los robots a identificar objetos cercano...

Inteligencia Artificial

Este artículo de IA propone un método de generación de memoria recursivo para mejorar la consistencia conversacional a largo plazo en modelos de lenguaje grandes

Los chatbots y otras formas de sistemas de comunicación de dominio abierto han experimentado un aumento de interés e ...

Inteligencia Artificial

De harapos a riquezas

A medida que los modelos de lenguaje grandes (LLMs por sus siglas en inglés) se han apoderado del mundo, los motores ...

Inteligencia Artificial

Amplios horizontes La presentación de NVIDIA señala el camino hacia nuevos avances en Inteligencia Artificial

Los avances dramáticos en el rendimiento del hardware han dado lugar a la IA generativa y a una rica variedad de idea...

Ciencia de Datos

Descubriendo los efectos perjudiciales de la IA en la comunidad trans

Cómo la inteligencia artificial está fallando a las personas transgénero. Los peligros del software de reconocimiento...