Transformers documentation

Classificação de texto

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v5.22.2).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Classificação de texto

A classificação de texto é uma tarefa comum de PLN que atribui um rótulo ou classe a um texto. Algumas das maiores empresas executam a classificação de texto em produção para uma ampla variedade de aplicações práticas. 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 uma sequência de texto.

Este guia mostrará como:

  1. Ajuste o DistilBERT no conjunto de dados IMDb para determinar se uma crítica de filme é positiva ou negativa.
  2. Use seu modelo ajustado para inferência.

Para ver todas as arquiteturas e checkpoints compatíveis com esta tarefa, recomendamos consultar a página da tarefa.

Antes de começar, verifique se você tem todas as bibliotecas necessárias instaladas:

pip install transformers datasets evaluate accelerate

Recomendamos que você faça login na sua conta do Hugging Face para que possa enviar e compartilhar seu modelo com a comunidade. Quando solicitado, insira seu token para fazer login:

>>> from huggingface_hub import notebook_login

>>> notebook_login()

Carregar o conjunto de dados IMDb

Comece carregando o conjunto de dados IMDb a partir da biblioteca 🤗 Datasets:

>>> from datasets import load_dataset

>>> imdb = load_dataset("stanfordnlp/imdb")

Em seguida, veja 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.",
}

Este conjunto de dados possui dois campos:

  • text: o texto da crítica do filme.
  • label: um valor que é 0 para uma avaliação negativa ou 1 para uma avaliação positiva.

Pré-processar

O próximo passo é carregar um tokenizer DistilBERT para pré-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 text e truncar as sequências para que não excedam o comprimento máximo de entrada do DistilBERT:

>>> def preprocess_function(examples):
...     return tokenizer(examples["text"], truncation=True)

Para aplicar a função de pré-processamento em todo o conjunto de dados, use a função map do 🤗 Datasets. Você pode acelerar o map definindo batched=True para processar vários elementos do conjunto de dados de uma vez:

tokenized_imdb = imdb.map(preprocess_function, batched=True)

Agora, crie um lote de exemplos usando DataCollatorWithPadding. É mais eficiente aplicar padding dinamicamente às frases até o comprimento máximo do lote durante a colação, em vez de aplicar padding em todo o conjunto de dados até o comprimento máximo.

>>> from transformers import DataCollatorWithPadding

>>> data_collator = DataCollatorWithPadding(tokenizer=tokenizer)

Avaliar

Incluir uma métrica durante o treinamento é frequentemente útil para avaliar o desempenho do seu modelo. Você pode carregar rapidamente um método de avaliação com a biblioteca 🤗 Evaluate. Para esta tarefa, carregue a métrica accuracy (veja o quick tour do 🤗 Evaluate para saber mais sobre como carregar e calcular uma métrica):

>>> import evaluate

>>> accuracy = evaluate.load("accuracy")

Em seguida, crie uma função que passa suas previsões e rótulos para compute para calcular a precisão:

>>> import numpy as np


>>> def compute_metrics(eval_pred):
...     predictions, labels = eval_pred
...     predictions = np.argmax(predictions, axis=1)
...     return accuracy.compute(predictions=predictions, references=labels)

Sua função compute_metrics está pronta e você voltará a ela ao configurar o treinamento.

Treinar

Antes de iniciar o treinamento do seu modelo, crie um mapa dos ids esperados para seus rótulos com id2label e label2id:

>>> id2label = {0: "NEGATIVE", 1: "POSITIVE"}
>>> label2id = {"NEGATIVE": 0, "POSITIVE": 1}

Se você não está familiarizado com o ajuste fino de um modelo usando o Trainer, confira o tutorial básico aqui!

Agora você está pronto para começar a treinar seu modelo! Carregue o DistilBERT com AutoModelForSequenceClassification, juntamente com o número de rótulos esperados e os mapeamentos de rótulos:

>>> from transformers import AutoModelForSequenceClassification, TrainingArguments, Trainer

>>> model = AutoModelForSequenceClassification.from_pretrained(
...     "distilbert/distilbert-base-uncased", num_labels=2, id2label=id2label, label2id=label2id
... )

Neste ponto, restam apenas três etapas:

  1. Defina os hiperparâmetros de treinamento em TrainingArguments. O único parâmetro obrigatório é output_dir, que especifica onde salvar seu modelo. Você enviará este modelo para o Hub definindo push_to_hub=True (é necessário estar conectado ao Hugging Face para enviar seu modelo). No final de cada epoch, o Trainer avaliará a precisão e salvará o checkpoint de treinamento.
  2. Passe os argumentos de treinamento para o Trainer junto com o modelo, o conjunto de dados, o tokenizer, o data collator e a função compute_metrics.
  3. Chame train() para fazer o ajuste fino do seu modelo.
>>> training_args = TrainingArguments(
...     output_dir="my_awesome_model",
...     learning_rate=2e-5,
...     per_device_train_batch_size=16,
...     per_device_eval_batch_size=16,
...     num_train_epochs=2,
...     weight_decay=0.01,
...     eval_strategy="epoch",
...     save_strategy="epoch",
...     load_best_model_at_end=True,
...     push_to_hub=True,
... )

>>> trainer = Trainer(
...     model=model,
...     args=training_args,
...     train_dataset=tokenized_imdb["train"],
...     eval_dataset=tokenized_imdb["test"],
...     processing_class=tokenizer,
...     data_collator=data_collator,
...     compute_metrics=compute_metrics,
... )

>>> trainer.train()

O Trainer aplica padding dinâmico por padrão quando você passa tokenizer para ele. Nesse caso, não é necessário especificar um data collator explicitamente.

Quando o treinamento for concluído, compartilhe seu modelo no Hub com o método push_to_hub() para que todos possam usá-lo:

>>> trainer.push_to_hub()

Para um exemplo mais detalhado de como fazer o ajuste fino de um modelo para classificação de texto, confira o notebook do PyTorch correspondente.

Inferência

Ótimo, agora que você ajustou um modelo, pode usá-lo para inferência!

Obtenha um texto no qual você deseja executar inferência:

>>> text = "This was a masterpiece. Not completely faithful to the books, but enthralling from beginning to end. Might be my favorite of the three."

A maneira mais simples de testar seu modelo ajustado para inferência é usá-lo em um pipeline(). Instancie um pipeline para análise de sentimento com seu modelo e passe seu texto para ele:

>>> from transformers import pipeline

>>> classifier = pipeline("sentiment-analysis", model="stevhliu/my_awesome_model")
>>> classifier(text)
[{'label': 'POSITIVE', 'score': 0.9994940757751465}]

Você também pode replicar manualmente os resultados do pipeline, se desejar:

Tokenize o texto e retorne tensores do PyTorch:

>>> from transformers import AutoTokenizer

>>> tokenizer = AutoTokenizer.from_pretrained("stevhliu/my_awesome_model")
>>> inputs = tokenizer(text, return_tensors="pt")

Passe suas entradas para o modelo e retorne os logits:

>>> import torch
>>> from transformers import AutoModelForSequenceClassification

>>> model = AutoModelForSequenceClassification.from_pretrained("stevhliu/my_awesome_model")
>>> with torch.no_grad():
...     logits = model(**inputs).logits

Obtenha a classe com a maior probabilidade e use o mapeamento id2label do modelo para convertê-la em um rótulo de texto:

>>> predicted_class_id = logits.argmax().item()
>>> model.config.id2label[predicted_class_id]
'POSITIVE'
Update on GitHub