Transformers documentation

Classification de texte

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

and get access to the augmented documentation experience

to get started

Classification de texte

La classification de texte est une tâche courante en NLP qui consiste à attribuer un libellé ou une classe à un texte. Certaines des plus grandes entreprises exploitent la classification de texte en production pour une large gamme d'applications pratiques. L'une des formes les plus populaires de classification de texte est l'analyse de sentiments, qui attribue un libellé tel que 🙂 positif, 🙁 négatif ou 😐 neutre à une séquence de texte.

Ce guide vous montre comment :

  1. Effectuer le fine-tuning de DistilBERT sur le jeu de données IMDb afin de déterminer si une critique de film est positive ou négative.
  2. Utilisez votre modèle affiné pour l'inférence.

Pour consulter toutes les architectures et points de contrôle compatibles avec cette tâche, nous vous recommandons de consulter la page de la tâche.

Avant de commencer, assurez-vous d'avoir installé toutes les bibliothèques nécessaires :

pip install transformers datasets evaluate accelerate

Nous vous encourage à vous connecter à votre compte Hugging Face afin de pouvoir téléverser et partager votre modèle avec la communauté. Lorsque cela vous est demandé, saisissez votre jeton pour vous connecter :

>>> from huggingface_hub import notebook_login

>>> notebook_login()

Charger le jeu de données IMDb

Commencez par charger le jeu de données IMDb à partir de la bibliothèque 🤗 Datasets :

>>> from datasets import load_dataset

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

Puis, jetez un œil à un exemple :

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

Ce jeu de données comporte deux champs :

  • text : le texte de la critique de film.
  • label : une valeur qui est soit 0 pour une critique négative, soit 1 pour une critique positive.

Prétraitement

L'étape suivante consiste à charger un tokenizer DistilBERT pour prétraiter le champ text :

>>> from transformers import AutoTokenizer

>>> tokenizer = AutoTokenizer.from_pretrained("distilbert/distilbert-base-uncased")

Créez une fonction de prétraitement pour tokeniser text et tronquer les séquences afin qu’elles ne dépassent pas la longueur d’entrée maximale de DistilBERT :

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

Pour appliquer la fonction de prétraitement à l'ensemble du jeu de données, utilisez la fonction map de 🤗 Datasets. Vous pouvez accélérer map en définissant batched=True afin de traiter plusieurs éléments du jeu de données à la fois :

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

Créez maintenant un lot d’exemples à l’aide de DataCollatorWithPadding. Il est plus efficace de rembourrer dynamiquement les phrases à la longueur maximale du lot lors de la collation, plutôt que de rembourrer l’ensemble du jeu de données à la longueur maximale.

>>> from transformers import DataCollatorWithPadding

>>> data_collator = DataCollatorWithPadding(tokenizer=tokenizer)

Évaluer

Inclure une métrique pendant l’entraînement est souvent utile pour évaluer les performances de votre modèle. Vous pouvez charger rapidement une méthode d’évaluation avec la bibliothèque 🤗 Evaluate. Pour cette tâche, chargez la métrique accuracy (consultez le quick tour de 🤗 Evaluate pour en savoir plus sur la façon de charger et de calculer une métrique) :

>>> import evaluate

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

Créez ensuite une fonction qui transmet vos prédictions et vos étiquettes à compute pour calculer la précision :

>>> 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)

Votre fonction compute_metrics est prête, et vous y reviendrez lors de la configuration de l’entraînement.

Entraînement

Avant de commencer l'entraînement de votre modèle, créez une correspondance entre les ids attendus et leurs libellés à l'aide de id2label et label2id :

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

Si vous n’êtes pas familier avec l’ajustement fin d’un modèle à l’aide du Trainer, consultez le tutoriel de base ici !

Vous êtes prêt à commencer l’entraînement de votre modèle ! Chargez DistilBERT avec AutoModelForSequenceClassification, en précisant le nombre de classes attendues ainsi que les correspondances des étiquettes :

>>> from transformers import AutoModelForSequenceClassification, TrainingArguments, Trainer

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

À ce stade, il ne reste que trois étapes :

  1. Définissez vos hyperparamètres d’entraînement dans TrainingArguments. Le seul paramètre obligatoire est output_dir, qui spécifie l’endroit où enregistrer votre modèle. Vous publierez ce modèle sur le Hub en définissant push_to_hub=True (vous devez être connecté à Hugging Face pour téléverser votre modèle). À la fin de chaque époque, le Trainer évalue la précision et enregistre le point de contrôle d’entraînement.
  2. Transmettez les arguments d’entraînement à Trainer en même temps que le modèle, le jeu de données, le tokenizer, le data collator et la fonction compute_metrics.
  3. Appel de train() pour l’ajustement fin de votre modèle.
>>> 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()

Trainer applique un rembourrage dynamique par défaut lorsque vous lui passez tokenizer. Dans ce cas, vous n’avez pas besoin de spécifier explicitement un collateur de données.

Une fois l’entraînement terminé, partagez votre modèle sur le Hub à l’aide de la méthode push_to_hub() afin que chacun puisse l’utiliser :

>>> trainer.push_to_hub()

Pour un exemple plus approfondi sur la façon d’affiner un modèle pour la classification de texte, consultez le notebook PyTorch correspondant.

Inférence

Parfait, maintenant que vous avez affiné un modèle, vous pouvez l'utiliser pour l'inférence !

Récupérez un texte sur lequel vous souhaitez effectuer une inférence :

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

La manière la plus simple de tester votre modèle finement ajusté pour l’inférence est de l’utiliser dans un pipeline(). Instanciez un pipeline pour l’analyse de sentiments avec votre modèle, puis transmettez-lui votre texte :

>>> from transformers import pipeline

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

Vous pouvez également reproduire manuellement les résultats de pipeline si vous le souhaitez :

Tokeniser le texte et retourner des tenseurs PyTorch :

>>> from transformers import AutoTokenizer

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

Transmettez vos entrées au modèle et renvoyez les logits :

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

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

Obtenez la classe ayant la probabilité la plus élevée, puis utilisez le mapping id2label du modèle pour la convertir en libellé texte :

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