Transformers documentation

Классификация текста

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

Классификация текста

Классификация текста — распространённая задача NLP, в которой тексту присваивается метка или класс. Крупнейшие компании используют классификацию текста в продакшене для широкого круга практических приложений. Одна из самых популярных форм классификации текста — анализ тональности, который присваивает последовательности текста метку, например 🙂 positive, 🙁 negative или 😐 neutral.

В этом руководстве показано, как:

  1. Настройте DistilBERT на датасете IMDb, чтобы определять, является ли отзыв о фильме положительным или отрицательным.
  2. Используйте вашу дообученную модель для инференса.

Чтобы увидеть все архитектуры и контрольные точки, совместимые с этой задачей, рекомендуем обратиться к странице задачи.

Прежде чем начать, убедитесь, что у вас установлены все необходимые библиотеки:

pip install transformers datasets evaluate accelerate

Мы рекомендуем вам войти в свой аккаунт Hugging Face, чтобы вы могли загрузить свою модель и поделиться ею с сообществом. При появлении запроса введите токен для входа:

>>> from huggingface_hub import notebook_login

>>> notebook_login()

Загрузка набора данных IMDb

Начните с загрузки набора данных IMDb из библиотеки 🤗 Datasets:

>>> from datasets import load_dataset

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

Теперь рассмотрим пример:

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

В этом наборе данных есть два поля:

  • text: текст отзыва о фильме.
  • label: значение, равное 0 для отрицательного отзыва или 1 для положительного отзыва.

Предобработка

Следующий шаг — загрузить токенизатор DistilBERT для предобработки поля text:

>>> from transformers import AutoTokenizer

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

Создайте функцию предобработки для токенизации text и обрезки последовательностей до максимальной длины входных данных DistilBERT:

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

Чтобы применить функцию предобработки ко всему набору данных, используйте функцию map из 🤗 Datasets. Вы можете ускорить map, установив batched=True, чтобы обрабатывать несколько элементов набора данных одновременно:

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

Теперь создайте батч примеров с помощью DataCollatorWithPadding. При формировании батча эффективнее динамически дополнять предложения до максимальной длины в рамках батча, чем дополнять весь датасет до максимальной длины.

>>> from transformers import DataCollatorWithPadding

>>> data_collator = DataCollatorWithPadding(tokenizer=tokenizer)

Оценка

Добавление метрики в процесс обучения часто помогает оценить качество модели. Вы можете быстро загрузить метод оценки с помощью библиотеки 🤗 Evaluate. Для этой задачи загрузите метрику accuracy (ознакомьтесь с быстрым обзором 🤗 Evaluate, чтобы узнать, как загружать и вычислять метрики):

>>> import evaluate

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

Затем создайте функцию, которая передаёт ваши предсказания и метки в compute для вычисления точности:

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

Ваша функция compute_metrics готова, и вы вернётесь к ней при настройке обучения.

Обучение

Прежде чем начинать обучение модели, создайте сопоставление ожидаемых идентификаторов с их метками с помощью id2label и label2id:

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

Если вы не знакомы с дообучением модели с помощью Trainer, загляните в базовое руководство здесь!

Теперь вы готовы приступить к обучению модели! Загрузите DistilBERT с помощью AutoModelForSequenceClassification, указав количество ожидаемых меток и соответствия меток:

>>> from transformers import AutoModelForSequenceClassification, TrainingArguments, Trainer

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

На этом этапе осталось выполнить только три шага:

  1. Определите гиперпараметры обучения в TrainingArguments. Единственный обязательный параметр — output_dir, который указывает, куда сохранять модель. Чтобы загрузить модель на Hub, установите push_to_hub=True (для загрузки модели необходимо войти в аккаунт Hugging Face). В конце каждой эпохи Trainer оценивает точность и сохраняет контрольную точку обучения.
  2. Передайте аргументы обучения в Trainer вместе с моделью, набором данных, токенизатором, data collator и функцией compute_metrics.
  3. Вызовите train(), чтобы дообучить модель.
>>> 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 по умолчанию применяет динамическое выравнивание, если вы передаёте ему tokenizer. В этом случае явно указывать коллабор данных не требуется.

После завершения обучения используйте метод push_to_hub(), чтобы опубликовать модель на Hub и дать всем возможность её использовать:

>>> trainer.push_to_hub()

Более подробный пример дообучения модели для классификации текста можно найти в соответствующем ноутбуке PyTorch.

Вывод

Отлично, теперь, когда вы дообучили модель, вы можете использовать её для инференса!

Возьмите текст, на котором вы хотите выполнить инференс:

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

Самый простой способ проверить вашу дообученную модель для инференса — использовать её в pipeline(). Создайте экземпляр pipeline для анализа тональности с вашей моделью и передайте в него текст:

>>> from transformers import pipeline

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

Вы также можете вручную воспроизвести результаты pipeline, если хотите:

Токенизируйте текст и верните тензоры PyTorch:

>>> from transformers import AutoTokenizer

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

Передайте входные данные в модель и верните logits:

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

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

Получите класс с наибольшей вероятностью и используйте отображение id2label модели, чтобы преобразовать его в текстовую метку:

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