Métricas ROUGE Evaluando Resúmenes en Modelos de Lenguaje Grandes.

Métricas ROUGE para evaluar resúmenes en modelos de lenguaje grandes.

El incremento de las aplicaciones de negocios que se basan en modelos de lenguaje grande ha trado la necesidad de medir la calidad de las soluciones proporcionadas por estas aplicaciones. Aquí es donde métricas como ROUGE se vuelven importantes.

Imagen generada por el autor usando Dall-e2

Las métricas que hemos estado utilizando hasta ahora con modelos más tradicionales, como Accuracy, F1 Score o Recall, no nos ayudan a evaluar los resultados de los modelos generativos.

Con estos modelos, estamos empezando a utilizar métricas como BLEU, ROUGE o METEOR. Métricas que se adaptan al objetivo del modelo.

En este artículo, quiero explicar cómo utilizar las métricas ROUGE para medir la calidad de los resúmenes producidos por los nuevos modelos de lenguaje grande.

¿Qué es ROUGE?

ROUGE consiste en un conjunto de métricas que se utilizan para comparar la calidad de un texto generado con respecto a un texto de referencia.

Se puede utilizar siempre que tengamos un texto de referencia disponible. Algunas de las aplicaciones más comunes son: traducciones, resumen de texto o extracción de entidades, entre otras.

Es importante destacar que ROUGE es tan confiable como la calidad del texto de referencia. Si tienen una calidad deficiente, los resultados proporcionados por ROUGE pueden no reflejar correctamente la calidad del texto generado.

Otra utilidad de ROUGE es medir cuán diferentes son las salidas producidas por dos modelos diferentes. Tal vez queremos ver si hay diferencias significativas entre los textos producidos por los dos modelos.

Además, podemos utilizar ROUGE para estimar si procesos como la poda o la cuantización (reducción de peso de los modelos) han alterado significativamente los resultados producidos por nuestro modelo para la tarea específica que queremos utilizar.

Las métricas proporcionadas son:

  • ROUGE-1: Esto indica la concordancia entre el texto generado y el texto de referencia utilizando 1-gramas o palabras individuales.
  • ROUGE-2: Lo mismo que ROUGE-1, pero considera conjuntos de 2-gramas.
  • ROUGE-L: Esta métrica evalúa la concordancia de la subsecuencia común más larga de palabras entre los dos textos. Las palabras no necesitan estar en el mismo orden exacto.

Más información sobre las métricas ROUGE se puede encontrar en: https://pypi.org/project/rouge-score/

¿Qué vamos a medir en nuestro Notebook?

Vamos a medir un modelo base de T5 frente a un modelo T5 ajustado para la generación de resúmenes.

Inicialmente, analizaremos las diferencias entre los dos modelos para determinar si el proceso de ajuste ha producido un modelo con un comportamiento distinto.

Más tarde, evaluaremos ambos modelos utilizando los textos de referencia proporcionados en el conjunto de datos de CNN-DailyMail, para ver cuál produce mejores resúmenes.

El código fuente de este artículo, así como todo el curso sobre modelos de lenguaje grande, se puede encontrar en mi repositorio de GitHub junto con los artículos correspondientes en inglés. El cuaderno utilizado para este artículo se puede acceder en: https://github.com/peremartra/Large-Language-Model-Notebooks-Course/blob/main/rouge-evaluation-untrained-vs-trained-llm.ipynb

GitHub – peremartra/Large-Language-Model-Notebooks-Course

Contribuye al desarrollo de peremartra/Large-Language-Model-Notebooks-Course creando una cuenta en GitHub.

github.com

Los modelos utilizados se pueden encontrar en Hugging Face.

  • Ajustado: t5-Base: https://huggingface.co/flax-community/t5-base-cnn-dm
  • Base: t5-Base: https://huggingface.co/t5-base

Cargando los datos.

En la primera parte del artículo, utilizaremos un conjunto de datos disponible en Kaggle que contiene noticias del MIT que no tienen resúmenes generados. Este conjunto de datos se utilizará para verificar que ambos modelos cargados generen resúmenes lo suficientemente diferentes.

Enlace del conjunto de datos: https://www.kaggle.com/datasets/deepanshudalal09/mit-ai-news-published-till-2023

Comencemos importando las bibliotecas Python típicas:

#Importar bibliotecas genéricas
import numpy as np
import pandas as pd
import torch

Todas estas son bibliotecas conocidas en el universo de Python. La importación de torch es necesaria porque ROUGE lo requiere.

Carguemos el conjunto de datos.

news = pd.read_csv('/kaggle/input/mit-ai-news-published-till-2023/articles.csv')
DOCUMENT="Cuerpo del artículo" # Debido a que es solo un curso, seleccionamos una pequeña porción de las noticias.
MAX_NEWS = 3
subset_news = news.head(MAX_NEWS)
subset_news.head()

El contenido completo del artículo se encuentra en la columna Cuerpo del artículo. Este es el único campo del conjunto de datos que necesitamos.

Seleccionamos solo tres artículos para acelerar la ejecución del cuaderno.

articles = subset_news[DOCUMENT].tolist()

Hemos almacenado el texto completo de los tres artículos cargados en la variable llamada articles. Si queremos trabajar con más o menos artículos de noticias, es tan simple como cambiar el valor de la variable MAX_NEWS.

Cargar los modelos y crear los resúmenes.

Los dos modelos utilizados son de la familia T5. Uno de ellos es el modelo T5-Base fundamental, y el otro es un modelo derivado de T5-Base, pero ajustado con el conjunto de datos CNN-DailyMail.

Dado que ambos modelos están disponibles en Hugging Face, trabajaremos con la biblioteca transformers.

import transformers
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
# Los nombres de los modelos se almacenan en las variables model_name_small y model_name_reference.
model_name_small = "t5-base"
model_name_reference = "flax-community/t5-base-cnn-dm"

Para obtener los tokenizadores y modelos, creé la siguiente función:

# Esta función devuelve el tokenizador y el modelo.
def get_model(model_id):
    tokenizer = AutoTokenizer.from_pretrained(model_id)
    model = AutoModelForSeq2SeqLM.from_pretrained(model_id)
    return tokenizer, model

Esta función recibe el model_id como entrada y devuelve el modelo cargado junto con el tokenizador.

El tokenizador se utiliza para convertir el texto en secuencias de tokens que pueden ser procesados por el modelo.

Usando la función get_model, podemos obtener los dos tokenizadores y modelos:

tokenizer_small, model_small = get_model(model_name_small)
tokenizer_reference, model_reference = get_model(model_name_reference)

Para generar los resúmenes, crearemos una función que tome cuatro parámetros:

  • Una lista de textos para resumir.
  • El tokenizador.
  • El modelo.
  • La longitud máxima para el resumen obtenido.

La función debe formatear un poco el texto de los artículos que se van a resumir. Esto implica introducir un prefijo antes de cada artículo. Este prefijo consistirá en instrucciones para el modelo. En nuestro caso, queremos que el modelo haga un resumen de los artículos, por lo que el prefijo a agregar será: “Resumir estas noticias: “.

Usando el tokenizador, cada artículo se transformará en codificaciones que se enviarán al modelo. El modelo devolverá un resumen que debe ser decodificado y convertido de codificaciones a texto.

def create_summaries(texts_list, tokenizer, model, max_l=125):
    # Vamos a agregar un prefijo a cada artículo para resumirlo
    # para que el modelo sepa lo que debe hacer
    prefix = "Resumir estas noticias: "
    summaries_list = [] # Contendrá todos los resúmenes
    texts_list = [prefix + text for text in texts_list]
    for text in texts_list:
        summary = ""
        # Calcular las codificaciones
        input_encodings = tokenizer(text,
                                     max_length=1024,
                                     return_tensors='pt',
                                     padding=True,
                                     truncation=True)
        # Generar los resúmenes
        with torch.no_grad():
            output = model.generate(
                input_ids=input_encodings.input_ids,
                attention_mask=input_encodings.attention_mask,
                max_length=max_l,  # Establecer la longitud máxima del resumen generado
                num_beams=2,     # Establecer el número de beams para la búsqueda de beams
                early_stopping=True
            )
        # Decodificar para obtener el texto
        summary = tokenizer.batch_decode(output, skip_special_tokens=True)
        # Agregar el resumen a la lista de resúmenes
        summaries_list += summary
    return summaries_list 

Veamos una parte específica del código de la función: la invocación del modelo para generar los resúmenes:

   # Generar los resúmenes    with torch.no_grad():        output = model.generate(            input_ids=input_encodings.input_ids,            attention_mask=input_encodings.attention_mask,            max_length=max_l,  # Establecer la longitud máxima del resumen generado            num_beams=2,     # Establecer el número de beams para la búsqueda de beams            early_stopping=True        )

Como puedes ver, estamos iniciando el bloque con la línea: with torch.no_grad(), lo cual indica que no queremos calcular gradientes dentro del bloque. Esto mejora la velocidad del código.

Luego llamamos a model.generate con los siguientes parámetros:

  • input_ids: Las codificaciones que representan el texto de entrada tokenizado.
  • attention_mask: La máscara de atención proporcionada por el tokenizador.
  • max_length: La longitud máxima de la respuesta del modelo.
  • beams: Cuanto mayor sea el número de beams, mayor será la diversidad en la respuesta generada por el modelo. Lo mantenemos en 2 para introducir cierta variedad.
  • early_stopping: este parámetro permite que el modelo deje de generar texto antes de que la respuesta alcance la longitud máxima. Es una buena práctica establecer este valor en True.

Veamos cómo llamar a la función create_summaries para obtener los resúmenes:

# Creando los resúmenes para ambos modelos. summaries_small = create_summaries(articles,                                   tokenizer_small,                                   model_small)summaries_reference = create_summaries(articles,                                       tokenizer_reference,                                       model_reference)

Como puedes ver, es simple. Solo necesitas pasar los textos que se deben resumir junto con los tokenizadores y los modelos.

Echemos un vistazo a los resúmenes generados por los dos modelos:

summaries_small: [‘MIT y MIT-Watson AI Lab han desarrollado un marco unificado. el sistema puede predecir simultáneamente propiedades moleculares y generar nuevas moléculas. utiliza esta gramática para construir moléculas viables y predecir sus propiedades.’, ‘\’BioAutoMATED\’ es un sistema automatizado de aprendizaje automático que puede seleccionar y construir un modelo adecuado para un conjunto de datos dado. incluso puede encargarse de la tarea laboriosa de preprocesamiento de datos, reduciendo un proceso de meses a solo unas pocas horas. \‘“Queremos reducir estas barreras para muchas personas que quieren usar el aprendizaje automático o la biología”, dice la primera coautora Jacqueline Valeri.’, “Científicos de investigación del MIT y IBM han mejorado un modelo de visión por computadora haciéndolo trabajar como una parte del cerebro en la que los humanos y otros primates confían para el reconocimiento de objetos. ‘le pedimos a la red neuronal artificial que haga que la función de una de tus capas “neuronales” internas sea lo más similar posible a la capa neuronal biológica correspondiente’, dice el profesor del MIT.”]

summaries_reference: [‘Los investigadores crearon un sistema de aprendizaje automático que aprende automáticamente el “lenguaje” de las moléculas utilizando solo un pequeño conjunto de datos específico del dominio. El sistema aprende a construir moléculas viables y predecir sus propiedades. El Grupo de Diseño Computacional y Fabricación se presentará en la Conferencia Internacional de Aprendizaje Automático.’, “El sistema de aprendizaje automático automatizado puede seleccionar y construir un modelo adecuado para un conjunto de datos dado. ‘BioAutoMATED’ es un sistema de aprendizaje automático automatizado. La herramienta incluye modelos de clasificación binaria, modelos de clasificación multiclase y redes neuronales más complejas.”, “Los investigadores del MIT y IBM descubrieron que las redes neuronales artificiales se parecen a los circuitos cerebrales multicapa que procesan información visual en humanos y otros primates. ‘Le pedimos que haga ambas cosas, así como el enfoque estándar de visión por computadora’, dijo un experto. La red se encontró que es más robusta al entrenarla para que funcione como una parte del cerebro en la que los humanos confían para el reconocimiento de objetos.”]

A simple vista, ya puedes observar que los resúmenes generados son diferentes. Sin embargo, es difícil determinar cuál de ellos es mejor para nuestras necesidades simplemente mirando los resúmenes.

Para determinar si los resúmenes son significativamente diferentes, utilizaremos ROUGE. Al comparar dos resúmenes generados, donde ninguno de ellos sirve como resumen de referencia, no estamos obteniendo una comprensión de la calidad de los resúmenes generados en sí. En cambio, estamos obteniendo una indicación de cuán diferentes son los resultados entre sí. Lo que nos permite identificar si el proceso de ajuste fino ha tenido algún impacto en los resultados de los resúmenes.

Calculando ROUGE

Instalemos y carguemos las bibliotecas necesarias para que podamos ejecutar las métricas ROUGE.

Aunque hay varias bibliotecas que implementan el cálculo de ROUGE, he decidido usar la biblioteca evaluate. A veces, la elección se basa en la familiaridad y esta es la biblioteca a la que estoy acostumbrado a usar.

!pip install evaluate import evaluatefrom nltk.tokenize import sent_tokenize#Con la función load de la biblioteca evaluate #creamos un objeto rouge_scorerouge_score = evaluate.load("rouge")

Una vez que hemos importado las bibliotecas, calcular la métrica ROUGE es tan simple como llamar a la función compute del objeto rouge_score que acabamos de crear.

Los textos se pasan a esta función, junto con un tercer parámetro que indica si desea usar los tallos de las palabras (lemas) o palabras completas para las comparaciones. Es común comparar solo los tallos para que palabras como “jump” y “jumped” se consideren iguales.

Aquí hay algunos ejemplos de lemas:

  • Jumping → Jump.
  • Running → Run.
  • Cats → Cat.

Cuando se usa True para el parámetro steamer, las palabras con el mismo tallo se consideran iguales, mientras que False las trata como palabras distintas.

Sin embargo, es importante preparar un poco el texto agregando saltos de línea al principio de cada línea y eliminando caracteres vacíos. Para lograr esto, creemos la función compute_rouge_score:

def compute_rouge_score(generated, reference):        #Necesitamos agregar '\n' a cada línea antes de enviarla a ROUGE    generated_with_newlines = ["\n".join(sent_tokenize(s.strip())) for s in generated]    reference_with_newlines = ["\n".join(sent_tokenize(s.strip())) for s in reference]        return rouge_score.compute(        predictions=generated_with_newlines,        references=reference_with_newlines,        use_stemmer=True,            )

Como puede ver, esta función modifica los textos recibidos como parámetros agregando saltos de línea a cada oración. Después, hace una sola llamada a la función rouge_score.compute.

 compute_rouge_score(summaries_small, summaries_reference)

En esta llamada, pasamos el texto generado utilizando tanto el modelo T5 Base como el modelo T5 ajustado. El resultado que devuelve es:

{‘rouge1’: 0.47018752391886715, ‘rouge2’: 0.3209013209013209, ‘rougeL’: 0.34330271718331423, ‘rougeLsum’: 0.44692881745120555}

Podemos ver que el grado de similitud en ROUGE-1 es del 47%, mientras que en ROUGE-2 es del 32%. Esto indica claramente que los resúmenes generados por ambos modelos son distintos. Con algunas similitudes pero diferencias significativas, lo que sugiere que el proceso de ajuste ha influido en cómo el modelo genera los resúmenes.

Sin embargo, todavía no podemos determinar qué modelo es mejor, ya que no hemos comparado con ningún texto de referencia.

Comparando con un texto de referencia.

Ahora vamos a usar un segundo conjunto de datos: el CNN_Dailymail, un conjunto de datos bien conocido que forma parte de la biblioteca Datasets.

Además de los artículos, este conjunto de datos contiene resúmenes generados por humanos que vamos a usar como textos de referencia.

Compararemos los resúmenes generados por los dos modelos con los resúmenes de referencia en el conjunto de datos. Esto nos ayudará a determinar qué modelo produce resúmenes que son más similares a los proporcionados como textos de referencia.

from datasets import load_datasetcnn_dataset = load_dataset(    "cnn_dailymail", version="3.0.0")#Obtenemos solo algunas noticias para pruebasample_cnn = cnn_dataset["test"].select(range(MAX_NEWS))sample_cnn

Como en la primera parte del artículo, cargaremos solo un número limitado de noticias. Y esto ayudará a mantener el tiempo de ejecución bajo control.

Obtenemos la longitud máxima de los resúmenes seleccionados del conjunto de datos, para indicar la longitud máxima que queremos que tenga la respuesta generada por los modelos.

max_length = max(len(item['highlights']) for item in sample_cnn)
max_length = max_length + 10

Ahora tenemos todo lo necesario para generar los resúmenes.

summaries_t5_base = create_summaries(sample_cnn["article"], tokenizer_small, model_small, max_l=max_length)
summaries_t5_finetuned = create_summaries(sample_cnn["article"], tokenizer_reference, model_reference, max_l=max_length)
# Obtén los resúmenes reales del conjunto de datos de CNN
real_summaries = sample_cnn['highlights']

Con los tres resúmenes en sus respectivas variables. Veamos el contenido.

summaries = pd.DataFrame.from_dict(
    {
        "base": summaries_t5_base,
        "finetuned": summaries_t5_finetuned,
        "reference": real_summaries,
    }
)
summaries.head()

La verdad es que a simple vista, es realmente difícil saber cuál de los dos modelos crea mejores resúmenes.

Calculemos las métricas ROUGE para ambos modelos.

compute_rouge_score(summaries_t5_base, real_summaries)

summaries_t5_base: {‘rouge1’: 0.3050834824090638, ‘rouge2’: 0.07211128178870115, ‘rougeL’: 0.2095520274299344, ‘rougeLsum’: 0.2662418008348241}

compute_rouge_score(summaries_t5_finetuned, real_summaries)

summaries_t5_finetuned: {‘rouge1’: 0.31659149328289443, ‘rouge2’: 0.11065084340946411, ‘rougeL’: 0.22002036956205442, ‘rougeLsum’: 0.24877540132887144}

Con estos resultados, diría que el modelo ajustado obtiene mejores resúmenes que el modelo T5-Base. Esto se basa en el hecho de que obtiene puntajes más altos en todas las métricas, excepto en LSUM, donde la diferencia es mínima.

También es importante tener en cuenta que las métricas ROUGE son altamente interpretables y no proporcionan una verdad absoluta. En otras palabras, un modelo no necesariamente es mejor que otro simplemente porque sus puntajes ROUGE son más altos. Estos puntajes solo indican que los textos que genera tienen más similitud con los textos de referencia que los producidos por otro modelo.

Ambos modelos tienen resultados muy similares, pero el modelo ajustado obtiene puntajes más altos en todas las métricas, especialmente en ROUGE-2 y ROUGE-L, excepto en ROUGE-LSUM. Esto implica que el modelo Base puede generar textos más similares, mientras que el modelo ajustado utiliza un vocabulario más similar a los textos de referencia.

En cualquier caso, no podemos obtener conclusiones claras ya que solo hemos analizado algunos resúmenes. Para determinar qué modelo es el mejor, necesitaríamos desarrollar una estrategia diferente. Un enfoque interesante puede ser agrupar las noticias por tema y examinar si hay diferencias significativas en los resultados.

Conclusiones.

Las métricas no son suficientes, incluso ROUGE se queda corto para nosotros, ya que depende en gran medida de la calidad de los textos que tomamos como referencia.

El factor humano sigue siendo muy importante para verificar la idoneidad de las respuestas. Por eso, los modelos que se han entrenado con mediación humana están teniendo éxito.

Al menos tenemos una buena noticia: es bastante fácil obtener métricas como ROUGE, que pueden ayudarnos en el proceso de toma de decisiones, y esto nos ayuda a tomar mejores decisiones sobre los modelos.

El curso completo sobre Modelos de Lenguaje Grandes está disponible en Github. Para mantenerte actualizado sobre nuevos artículos, considera seguir el repositorio o marcarlo como favorito. De esta manera, recibirás notificaciones cada vez que se agregue nuevo contenido.

GitHub – peremartra/Large-Language-Model-Notebooks-Course

Contribuye a peremartra/Large-Language-Model-Notebooks-Course desarrollando una cuenta en GitHub.

github.com

Escribo regularmente sobre Aprendizaje Profundo e Inteligencia Artificial. Ten en cuenta seguirme en VoAGI para recibir actualizaciones sobre nuevos artículos. Y, por supuesto, eres bienvenido a conectarte conmigo en LinkedIn.

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

Noticias de Inteligencia Artificial

BIOTRONIK presenta implantes de monitores cardíacos con inteligencia artificial.

BIOTRONIK, un líder reconocido en tecnología de dispositivos médicos implantables, ha implementado con éxito su revol...

Inteligencia Artificial

Científicos recrean canción de Pink Floyd leyendo las señales cerebrales de los oyentes

El audio suena como si se estuviera reproduciendo bajo el agua. Aún así, es un primer paso hacia la creación de dispo...

Inteligencia Artificial

Aprendizaje automático con MATLAB y Amazon SageMaker

Esta publicación está escrita en colaboración con Brad Duncan, Rachel Johnson y Richard Alcock de MathWorks. MATLAB e...

Inteligencia Artificial

Investigadores de UCSD y Microsoft presentan ColDeco una herramienta de inspección sin código para columnas calculadas.

En el artículo “COLDECO: una herramienta de inspección de hojas de cálculo para código generado por IA” u...