Preprocesamiento de datos de transformadores: Preprocesamiento de datos

Preprocesamiento de datos Preprocesamiento de datos

En transformers, la herramienta principal para el procesamiento de datos es el tokenizador de texto tokenizer. Podemos usar el tipo de tokenizador de texto correspondiente al modelo, o podemos usar la AutoTokenizerclasificación automática directamente.

Un tokenizador de texto primero divide el texto en palabras, signos de puntuación, etc. Estos elementos divididos se denominan token. Luego se tokenconvertirá en un número para que pueda convertirse en un tensor para el entrenamiento tensor. CLSAdemás, algunos tokenizadores de texto específicos también agregarán algunas etiquetas especiales requeridas por el modelo, como , en BERT SEP.

Nota:
Si desea utilizar un modelo previamente entrenado, debe utilizar el tokenizador de texto correspondiente del modelo. Debido a que el tokenizador de texto correspondiente transforma el texto de la misma manera que se entrenó su modelo, el vocabulario correspondiente también es el mismo. Si el tokenizador de texto es incorrecto, tendrá un gran impacto en la predicción o el ajuste fino del modelo. Por ejemplo, el índice original de la palabra "I" es 1 y el índice de "I" en otro tokenizador de texto es 100, lo que hace que los datos recibidos por el modelo sean completamente diferentes de lo que piensas.

Para descargar automáticamente el tokenizador de texto utilizado al entrenar o ajustar el modelo, puede usar from_pretrained()el método:

from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained('bert-base-cased')

uso básico

preprocesamiento

Los tokenizadores de texto en los transformadores tienen muchos métodos, pero solo hay un método para el preprocesamiento, es decir, __call__simplemente introduce el texto directamente en el objeto del tokenizador de texto. como sigue:

encoded_input = tokenizer("Hello, I'm a single sentence!")
print(encoded_input)

输出:
{
    
    'input_ids': [101, 8667, 117, 146, 112, 182, 170, 1423, 5650, 106, 102], 
'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}

Este método devuelve un diccionario. input_idses tokenel índice de cada uno en el texto de entrada. attention_maskEl uso de y se discutirá más adelante token_type_ids.

descodificación

Además de codificar texto, los tokenizadores de texto también pueden decodificar índices:

print(tokenizer.decode(encoded_input["input_ids"]))

输出:
[CLS] Hello, I'm a single sentence! [SEP]

Podemos ver que el etiquetador de texto agregó automáticamente las etiquetas especiales requeridas por BERT durante el preprocesamiento.

No todos los modelos requieren un marcado especial, si usamos gtp2-mediumnot bert-base-cased, podemos obtener el mismo resultado que el texto original al decodificar.

Al decodificar, también podemos agregar parámetros al método add_special_tokens=Falsepara eliminar etiquetas especiales (algunas versiones son skip_special_tokens=True).

múltiples datos

Si desea procesar varios textos a la vez, puede combinarlos en una matriz, dentro y fuera del tokenizador de texto a la vez, de la siguiente manera:

batch_sentences = ["Hello I'm a single sentence",
                   "And another sentence",
                   "And the very very last one"]
encoded_inputs = tokenizer(batch_sentences)
print(encoded_inputs)

输出:
{
    
    'input_ids': [[101, 8667, 146, 112, 182, 170, 1423, 5650, 102],
               [101, 1262, 1330, 5650, 102],
               [101, 1262, 1103, 1304, 1304, 1314, 1141, 102]],
 'token_type_ids': [[0, 0, 0, 0, 0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0, 0, 0, 0]],
 'attention_mask': [[1, 1, 1, 1, 1, 1, 1, 1, 1],
                    [1, 1, 1, 1, 1],
                    [1, 1, 1, 1, 1, 1, 1, 1]]}

Rellenar, truncar, devolver tipos específicos

Al procesar varios extractos a la vez, también podemos tener los siguientes requisitos:

  • rellenar cada oración a la longitud máxima del lote
  • Trunca cada oración a la longitud máxima que el modelo puede aceptar
  • tensordatos de tipo de retorno

Puede lograr todos los requisitos con las siguientes operaciones:

batch = tokenizer(batch_sentences, max_length=7, padding=True, truncation=True, return_tensors="pt", )
print(batch)

结果:
{
    
    'input_ids': tensor([
				[ 101, 8667,  146,  112,  182,  170,  102],
        [ 101, 1262, 1330, 5650,  102,    0,    0],
        [ 101, 1262, 1103, 1304, 1304, 1314,  102]]), 
'token_type_ids': tensor([
				[0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0]]), 
'attention_mask': tensor([
				[1, 1, 1, 1, 1, 1, 1],
        [1, 1, 1, 1, 1, 0, 0],
        [1, 1, 1, 1, 1, 1, 1]])}

Esta vez se devuelve un pytorch.tensordiccionario de cadenas a tipos . Ahora podemos ver el uso basado en los resultados devueltos attention_mask: le dirá al modelo a cuáles tokense debe prestar atención y cuáles no se deben ignorar, porque algunos no tienen sentido para el llenado token.

Tenga en cuenta que el código anterior emitirá una advertencia cuando se ejecute si se usa un modelo que no tiene una longitud máxima asociada. Esto está bien y se puede ignorar, o se pueden agregar parámetros verbose=Falsepara evitar que el tokenizador de texto arroje estas excepciones.

procesamiento de pares de oraciones

A veces puede ser necesario introducir un par de frases en el modelo. Por ejemplo, necesitamos juzgar si dos oraciones son similares, o estamos usando un modelo de respuesta a preguntas y necesitamos introducir texto y preguntas en el modelo. Para BERTel modelo, los pares de oraciones deben transformarse en la siguiente forma:[CLS] Sequence A [SEP] Sequence B [SEP]

Cuando usamos Transformers para procesar pares de oraciones, necesitamos pasar las dos oraciones al tokenizador de texto como variables diferentes (tenga en cuenta que no está integrado en una lista como antes, sino dos variables separadas). Entonces obtendremos un diccionario correspondiente, como en el siguiente ejemplo:

encoded_input = tokenizer("How old are you?", "I'm 6 years old")
print(encoded_input)
print(tokenizer.decode(encoded_input["input_ids"]))
for i in encoded_input["input_ids"]:
    print(tokenizer.decode(i))

结果:
{
    
    'input_ids': [101, 1731, 1385, 1132, 1128, 136, 102, 146, 112, 182, 127, 1201, 1385, 102], 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}
[CLS] How old are you? [SEP] I'm 6 years old [SEP]
[ C L S ]
H o w
o l d
a r e
y o u
?
[ S E P ]
I
'
m
6
y e a r s
o l d
[ S E P ]

A partir de los resultados podemos ver token_type_idsel efecto: le dicen al modelo qué parte de la entrada pertenece a la primera oración y qué parte pertenece a la segunda oración. Tenga en cuenta que no todos los modelos lo requieren token_tyoe_ids. De forma predeterminada, los tokenizadores de texto solo devolverán la entrada deseada en relación con el modelo. Puede pasar algunos parámetros como return_token_type_idso return_lengthpara cambiar la salida del tokenizador de texto.

encoded_input = tokenizer("How old are you?", "I'm 6 years old",
                        return_token_type_ids=False, 
                        return_length=True,
                        )
print(encoded_input)

输出:
{
    
    'input_ids': [101, 1731, 1385, 1132, 1128, 136, 102, 146, 112, 182, 127, 1201, 1385, 102], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 'length': 14}

Además, si desea procesar varias declaraciones a la vez, puede pasar dos listas de texto por separado. como sigue:

batch_sentences = ["Hello I'm a single sentence",
                   "And another sentence",
                   "And the very very last one"]
batch_of_second_sentences = ["I'm a sentence that goes with the first sentence",
                             "And I should be encoded with the second sentence",
                             "And I go with the very last one"]
encoded_inputs = tokenizer(batch_sentences, batch_of_second_sentences)
print(encoded_inputs)

结果:
{
    
    'input_ids': [[101, 8667, 146, 112, 182, 170, 1423, 5650, 102, 146, 112, 182, 170, 5650, 1115, 2947, 1114, 1103, 1148, 5650, 102],
               [101, 1262, 1330, 5650, 102, 1262, 146, 1431, 1129, 12544, 1114, 1103, 1248, 5650, 102],
               [101, 1262, 1103, 1304, 1304, 1314, 1141, 102, 1262, 146, 1301, 1114, 1103, 1304, 1314, 1141, 102]],
'token_type_ids': [[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
                   [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
                   [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1]],
'attention_mask': [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
                   [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
                   [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]}

input_idsPodemos verificar nuestra entrada recorriendo la lista decodificada , de la siguiente manera:

for ids in encoded_inputs["input_ids"]:
    print(tokenizer.decode(ids))

结果:
[CLS] Hello I'm a single sentence [SEP] I'm a sentence that goes with the first sentence [SEP]
[CLS] And another sentence [SEP] And I should be encoded with the second sentence [SEP]
[CLS] And the very very last one [SEP] And I go with the very last one [SEP]

Y aún puede ingresar algunos parámetros para completar o interceptar el texto, o convertirlo a un tipo específico al codificar, de la siguiente manera:

batch = tokenizer(batch_sentences, batch_of_second_sentences, padding=True, truncation=True, return_tensors="pt")

algo sobre el relleno y el truncamiento

Las instrucciones aplicables en la mayoría de los casos se han introducido anteriormente. Pero Transformers también ofrece más métodos, que giran en torno a tres parámetros , paddingpara ampliar.truncationmax_length

  • paddingSe utiliza para controlar el relleno. Puede ser de tipo booleano o de tipo cadena, de la siguiente manera:
    • Trueo ”longest”para rellenar todas las oraciones a la longitud máxima en la lista de secuencias, o no hacer nada si proporciona solo una oración.
    • “max_length”Se utiliza para llenar la secuencia hasta la longitud del parámetro Si no max_lengthse proporciona ningún max_lengthparámetro ( ) max_length=None, se llenará hasta la longitud máxima que el modelo pueda aceptar. Y también funciona cuando solo proporciona una oración.
    • Falseo ”do_not_pad”para configurarlo sin relleno. Y este es el valor predeterminado del parámetro.
  • truncationSe utiliza para controlar el truncamiento. Puede ser booleano o cadena.
    • TrueO “only_first”la oración se trunca a la longitud del parámetro, si no max_lengthse proporciona ningún max_lengthparámetro ( ) max_length=None, la oración se trunca a la longitud máxima aceptable para el modelo. Si los datos proporcionados son un par de oraciones o un lote de pares de oraciones, solo se truncará la primera oración.
    • “only_sceond”Trunque la oración a max_lengthla longitud del parámetro, si no se proporciona ningún max_lengthparámetro ( max_length=None), se truncará a la longitud máxima que el modelo puede aceptar. Cuando los datos de entrada son un par de oraciones, solo se truncará el segundo dato.
    • FalseO ”do_not_truncate”indicar que la sentencia no debe ser interceptada. Y este es el valor predeterminado del parámetro.
  • max_lengthSe utiliza para controlar la longitud del relleno o el truncamiento. Puede ser 整数o None, el valor predeterminado es el grado máximo que el modelo puede aceptar. Si el modelo no tiene una longitud de entrada máxima específica, se truncará o se rellenará con max_length.

Algunos resumen de uso

Si en el siguiente ejemplo, la entrada es un par de oraciones, puede truncation=Truereemplazar ** con STRATEGY, las opciones son las siguientes:['only_first', 'only_second', 'longest_first'] **.

  • no truncar
    • No llenado:**tokenizer(batch_sentences)**
    • pad hasta la longitud máxima del lote actual: **tokenizer(batch_sentences, padding=True)**o**tokenizer(batch_sentences, padding=’longest’)**
    • Almohadilla hasta la longitud máxima aceptable del modelo:**tokenizer(batch_sentences, padding='max_length')**
    • Relleno a una longitud específica:**tokenizer(batch_sentences, padding='max_length', max_length=42)**
  • Truncar a la longitud máxima de la entrada del modelo
    • Sin relleno: tokenizer(batch_sentences, truncation=True)o tokenizer(batch_sentences, padding=True, truncation=STRATEGY)****
    • pad hasta la longitud máxima del lote actual: tokenizer(batch_sentences, padding=True, truncation=True)otokenizer(batch_sentences, padding=True, truncation=STRATEGY)
    • Relleno hasta la longitud máxima aceptable del modelo: tokenizer(batch_sentences, padding='max_length', truncation=True)otokenizer(batch_sentences, padding='max_length', truncation=STRATEGY)
    • Rellenar hasta una longitud específica: no se puede hacer, porque agregar max_lengthparámetros no puede llenar y truncar hasta la entrada máxima.
  • truncar a una longitud específica
    • sin relleno: otokenizer(batch_sentences, truncation=True, max_length=42)
      tokenizer(batch_sentences, truncation=STRATEGY, max_length=42)
    • Almohadilla a la longitud máxima del lote actual: otokenizer(batch_sentences, padding=True, truncation=True, max_length=42)
      tokenizer(batch_sentences, padding=True, truncation=STRATEGY, max_length=42)
    • Acolchado hasta la longitud máxima aceptable del modelo: no es posible
    • almohadilla a una longitud específica: otokenizer(batch_sentences, padding='max_length', truncation=True, max_length=42)
      tokenizer(batch_sentences, padding='max_length', truncation=STRATEGY, max_length=42)

entrada preetiquetada

Los tokenizadores también pueden aceptar entradas previamente tokenizadas. Esto es importante en las tareas de reconocimiento de entidades nombradas y etiquetado de partes del discurso.

Cabe señalar que la entrada preetiquetada no es una entrada indexada, sino que solo divide las palabras,

Para usar una entrada preetiquetada, simplemente establezca el parámetro en is_split_into_words=True. Los ejemplos son los siguientes:

encoded_input = tokenizer(["Hello", "I'm", "a", "single", "sentence"], is_split_into_words=True)
print(encoded_input)

结果:
{
    
    'input_ids': [101, 8667, 146, 112, 182, 170, 1423, 5650, 102], 
'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0], 
'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1]}

Nota: La entrada preetiquetada también agregará etiquetas especiales relacionadas con el modelo, a menos que el parámetro de atributo sea add_special_tokens=False.

Introduce varias frases

La entrada de múltiples oraciones previa al token es exactamente igual que antes, puede codificar múltiples oraciones como esta:

batch_sentences = [["Hello", "I'm", "a", "single", "sentence"],
                   ["And", "another", "sentence"],
                   ["And", "the", "very", "very", "last", "one"]]
encoded_inputs = tokenizer(batch_sentences, is_split_into_words=True)

par de oraciones de entrada

Los pares de oraciones también se pueden ingresar así:

batch_of_second_sentences = [["I'm", "a", "sentence", "that", "goes", "with", "the", "first", "sentence"],
                             ["And", "I", "should", "be", "encoded", "with", "the", "second", "sentence"],
                             ["And", "I", "go", "with", "the", "very", "last", "one"]]
encoded_inputs = tokenizer(batch_sentences, batch_of_second_sentences, is_split_into_words=True)

relleno y truncamiento

También es posible rellenar y truncar como antes:

batch = tokenizer(batch_sentences,
                  batch_of_second_sentences,
                  is_split_into_words=True,
                  padding=True,
                  truncation=True,
                  return_tensors="pt")

Supongo que te gusta

Origin blog.csdn.net/qq_42464569/article/details/123239558
Recomendado
Clasificación