Classificação de texto
A classificação de texto é uma tarefa comum de NLP que atribui um rótulo ou classe a um texto. Existem muitas aplicações práticas de classificação de texto amplamente utilizadas em produção por algumas das maiores empresas da atualidade. Uma das formas mais populares de classificação de texto é a análise de sentimento, que atribui um rótulo como positivo, negativo ou neutro a um texto.
Este guia mostrará como realizar o fine-tuning do DistilBERT no conjunto de dados IMDb para determinar se a crítica de filme é positiva ou negativa.
Consulte a página de tarefas de classificação de texto para obter mais informações sobre outras formas de classificação de texto e seus modelos, conjuntos de dados e métricas associados.
Carregue o conjunto de dados IMDb
Carregue o conjunto de dados IMDb utilizando a biblioteca 🤗 Datasets:
>>> from datasets import load_dataset
>>> imdb = load_dataset("imdb")
Em seguida, dê uma olhada em um exemplo:
>>> imdb["test"][0]
{
"label": 0,
"text": "I love sci-fi and am willing to put up with a lot. Sci-fi movies/TV are usually underfunded, under-appreciated and misunderstood. I tried to like this, I really did, but it is to good TV sci-fi as Babylon 5 is to Star Trek (the original). Silly prosthetics, cheap cardboard sets, stilted dialogues, CG that doesn't match the background, and painfully one-dimensional characters cannot be overcome with a 'sci-fi' setting. (I'm sure there are those of you out there who think Babylon 5 is good sci-fi TV. It's not. It's clichéd and uninspiring.) While US viewers might like emotion and character development, sci-fi is a genre that does not take itself seriously (cf. Star Trek). It may treat important issues, yet not as a serious philosophy. It's really difficult to care about the characters here as they are not simply foolish, just missing a spark of life. Their actions and reactions are wooden and predictable, often painful to watch. The makers of Earth KNOW it's rubbish as they have to always say \"Gene Roddenberry's Earth...\" otherwise people would not continue watching. Roddenberry's ashes must be turning in their orbit as this dull, cheap, poorly edited (watching it without advert breaks really brings this home) trudging Trabant of a show lumbers into space. Spoiler. So, kill off a main character. And then bring him back as another actor. Jeeez! Dallas all over again.",
}
Existem dois campos neste dataset:
text
: uma string contendo o texto da crítica do filme.label
: um valor que pode ser0
para uma crítica negativa ou1
para uma crítica positiva.
Pré-processamento dos dados
Carregue o tokenizador do DistilBERT para processar o campo text
:
>>> from transformers import AutoTokenizer
>>> tokenizer = AutoTokenizer.from_pretrained("distilbert/distilbert-base-uncased")
Crie uma função de pré-processamento para tokenizar o campo text
e truncar as sequências para que não sejam maiores que o comprimento máximo de entrada do DistilBERT:
>>> def preprocess_function(examples):
... return tokenizer(examples["text"], truncation=True)
Use a função map
do 🤗 Datasets para aplicar a função de pré-processamento em todo o conjunto de dados. Você pode acelerar a função map
definindo batched=True
para processar vários elementos do conjunto de dados de uma só vez:
tokenized_imdb = imdb.map(preprocess_function, batched=True)
Use o DataCollatorWithPadding
para criar um batch de exemplos. Ele também preencherá dinamicamente seu texto até o comprimento do elemento mais longo em seu batch, para que os exemplos do batch tenham um comprimento uniforme. Embora seja possível preencher seu texto com a função tokenizer
definindo padding=True
, o preenchimento dinâmico utilizando um data collator é mais eficiente.
>>> from transformers import DataCollatorWithPadding
>>> data_collator = DataCollatorWithPadding(tokenizer=tokenizer)
>>> from transformers import DataCollatorWithPadding
>>> data_collator = DataCollatorWithPadding(tokenizer=tokenizer, return_tensors="tf")
Train
Carregue o DistilBERT com AutoModelForSequenceClassification
junto com o número de rótulos esperados:
>>> from transformers import AutoModelForSequenceClassification, TrainingArguments, Trainer
>>> model = AutoModelForSequenceClassification.from_pretrained("distilbert/distilbert-base-uncased", num_labels=2)
Se você não estiver familiarizado com o fine-tuning de um modelo com o Trainer
, dê uma olhada no tutorial básico aqui!
Nesse ponto, restam apenas três passos:
- Definir seus hiperparâmetros de treinamento em
TrainingArguments
. - Passar os argumentos de treinamento para o
Trainer
junto com o modelo, conjunto de dados, tokenizador e o data collator. - Chamar a função
train()
para executar o fine-tuning do seu modelo.
>>> training_args = TrainingArguments(
... output_dir="./results",
... learning_rate=2e-5,
... per_device_train_batch_size=16,
... per_device_eval_batch_size=16,
... num_train_epochs=5,
... weight_decay=0.01,
... )
>>> trainer = Trainer(
... model=model,
... args=training_args,
... train_dataset=tokenized_imdb["train"],
... eval_dataset=tokenized_imdb["test"],
... tokenizer=tokenizer,
... data_collator=data_collator,
... )
>>> trainer.train()
O Trainer
aplicará o preenchimento dinâmico por padrão quando você definir o argumento tokenizer
dele. Nesse caso, você não precisa especificar um data collator explicitamente.
Para executar o fine-tuning de um modelo no TensorFlow, comece convertendo seu conjunto de dados para o formato tf.data.Dataset
com to_tf_dataset
. Nessa execução você deverá especificar as entradas e rótulos (no parâmetro columns
), se deseja embaralhar o conjunto de dados, o tamanho do batch e o data collator:
>>> tf_train_set = tokenized_imdb["train"].to_tf_dataset(
... columns=["attention_mask", "input_ids", "label"],
... shuffle=True,
... batch_size=16,
... collate_fn=data_collator,
... )
>>> tf_validation_set = tokenized_imdb["test"].to_tf_dataset(
... columns=["attention_mask", "input_ids", "label"],
... shuffle=False,
... batch_size=16,
... collate_fn=data_collator,
... )
Se você não estiver familiarizado com o fine-tuning de um modelo com o Keras, dê uma olhada no tutorial básico aqui!
Configure o otimizador e alguns hiperparâmetros de treinamento:
>>> from transformers import create_optimizer
>>> import tensorflow as tf
>>> batch_size = 16
>>> num_epochs = 5
>>> batches_per_epoch = len(tokenized_imdb["train"]) // batch_size
>>> total_train_steps = int(batches_per_epoch * num_epochs)
>>> optimizer, schedule = create_optimizer(init_lr=2e-5, num_warmup_steps=0, num_train_steps=total_train_steps)
Carregue o DistilBERT com TFAutoModelForSequenceClassification
junto com o número de rótulos esperados:
>>> from transformers import TFAutoModelForSequenceClassification
>>> model = TFAutoModelForSequenceClassification.from_pretrained("distilbert/distilbert-base-uncased", num_labels=2)
Configure o modelo para treinamento com o método compile
:
>>> import tensorflow as tf
>>> model.compile(optimizer=optimizer)
Chame o método fit
para executar o fine-tuning do modelo:
>>> model.fit(x=tf_train_set, validation_data=tf_validation_set, epochs=3)
Para obter um exemplo mais aprofundado de como executar o fine-tuning de um modelo para classificação de texto, dê uma olhada nesse notebook utilizando PyTorch ou nesse notebook utilizando TensorFlow.