Transformers documentation
Phân loại văn bản
Phân loại văn bản
Phân loại văn bản là một tác vụ NLP phổ biến, gán một nhãn hoặc lớp cho văn bản. Một số công ty lớn nhất đang triển khai phân loại văn bản trong môi trường sản xuất cho nhiều ứng dụng thực tế khác nhau. Một trong những dạng phân loại văn bản phổ biến nhất là phân tích cảm xúc, gán một nhãn như 🙂 tích cực, 🙁 tiêu cực, hoặc 😐 trung lập cho một chuỗi văn bản.
Hướng dẫn này sẽ cho bạn thấy cách:
- Huấn luyện lại DistilBERT trên bộ dữ liệu IMDb để xác định xem một bài đánh giá phim là tích cực hay tiêu cực.
- Sử dụng mô hình đã tinh chỉnh của bạn để suy luận.
Để xem tất cả các kiến trúc và checkpoint tương thích với tác vụ này, chúng tôi khuyến nghị bạn kiểm tra trang tác vụ.
Trước khi bắt đầu, hãy đảm bảo bạn đã cài đặt tất cả các thư viện cần thiết:
pip install transformers datasets evaluate accelerate
Chúng tôi khuyến khích bạn đăng nhập vào tài khoản Hugging Face của mình để có thể tải lên và chia sẻ mô hình của bạn với cộng đồng. Khi được yêu cầu, hãy nhập token của bạn để đăng nhập:
>>> from huggingface_hub import notebook_login
>>> notebook_login()Tải bộ dữ liệu IMDb
Bắt đầu bằng cách tải bộ dữ liệu IMDb từ thư viện 🤗 Datasets:
>>> from datasets import load_dataset
>>> imdb = load_dataset("stanfordnlp/imdb")Sau đó, hãy xem một ví dụ:
>>> 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.",
}Bộ dữ liệu này có hai trường:
text: nội dung đánh giá phim.label: một giá trị là0cho đánh giá tiêu cực hoặc1cho đánh giá tích cực.
Tiền xử lý
Bước tiếp theo là nạp một tokenizer DistilBERT để tiền xử lý trường text:
>>> from transformers import AutoTokenizer
>>> tokenizer = AutoTokenizer.from_pretrained("distilbert/distilbert-base-uncased")Tạo một hàm tiền xử lý để mã hóa text và cắt ngắn các chuỗi để không dài hơn độ dài đầu vào tối đa của DistilBERT:
>>> def preprocess_function(examples):
... return tokenizer(examples["text"], truncation=True)Để áp dụng hàm tiền xử lý lên toàn bộ bộ dữ liệu, hãy sử dụng hàm map của 🤗 Datasets. Bạn có thể tăng tốc map bằng cách đặt batched=True để xử lý nhiều phần tử của bộ dữ liệu cùng lúc:
tokenized_imdb = imdb.map(preprocess_function, batched=True)Bây giờ hãy tạo một batch các ví dụ bằng cách sử dụng DataCollatorWithPadding. Việc đệm động các câu đến độ dài dài nhất trong một batch trong quá trình collation sẽ hiệu quả hơn so với việc đệm toàn bộ dataset đến độ dài tối đa.
>>> from transformers import DataCollatorWithPadding
>>> data_collator = DataCollatorWithPadding(tokenizer=tokenizer)Đánh giá
Việc đưa một chỉ số vào trong quá trình huấn luyện thường hữu ích để đánh giá hiệu suất của mô hình. Bạn có thể nhanh chóng tải một phương pháp đánh giá bằng thư viện 🤗 Evaluate. Đối với tác vụ này, hãy tải chỉ số accuracy (xem quick tour của 🤗 Evaluate để tìm hiểu thêm về cách tải và tính toán một chỉ số):
>>> import evaluate
>>> accuracy = evaluate.load("accuracy")Sau đó, tạo một hàm truyền các dự đoán và nhãn của bạn vào compute để tính độ chính xác:
>>> 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)Hàm compute_metrics của bạn đã sẵn sàng, và bạn sẽ quay lại với nó khi thiết lập quá trình huấn luyện.
Huấn luyện
Trước khi bắt đầu huấn luyện mô hình của bạn, hãy tạo một bản đồ ánh xạ các id dự kiến tương ứng với nhãn của chúng bằng id2label và label2id:
>>> id2label = {0: "NEGATIVE", 1: "POSITIVE"}
>>> label2id = {"NEGATIVE": 0, "POSITIVE": 1}Nếu bạn chưa quen với việc tinh chỉnh mô hình bằng Trainer, hãy xem hướng dẫn cơ bản tại đây!
Bạn đã sẵn sàng để bắt đầu huấn luyện mô hình của mình! Hãy nạp DistilBERT bằng AutoModelForSequenceClassification cùng với số nhãn dự kiến và các ánh xạ nhãn:
>>> from transformers import AutoModelForSequenceClassification, TrainingArguments, Trainer
>>> model = AutoModelForSequenceClassification.from_pretrained(
... "distilbert/distilbert-base-uncased", num_labels=2, id2label=id2label, label2id=label2id
... )Tới bước này, chỉ còn ba bước nữa:
- Định nghĩa các siêu tham số huấn luyện của bạn trong TrainingArguments. Tham số bắt buộc duy nhất là
output_dir, chỉ định nơi lưu trữ mô hình của bạn. Bạn sẽ đẩy mô hình này lên Hub bằng cách đặtpush_to_hub=True(bạn cần đăng nhập vào Hugging Face để tải lên mô hình). Vào cuối mỗi epoch, Trainer sẽ đánh giá độ chính xác và lưu checkpoint huấn luyện. - Truyền các đối số huấn luyện vào Trainer cùng với mô hình, tập dữ liệu, tokenizer, data collator và hàm
compute_metrics. - Gọi train() để tinh chỉnh mô hình của bạn.
>>> 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 áp dụng dynamic padding theo mặc định khi bạn truyền
tokenizervào. Trong trường hợp này, bạn không cần chỉ định data collator một cách tường minh.
Khi quá trình huấn luyện hoàn tất, hãy chia sẻ mô hình của bạn lên Hub bằng phương thức push_to_hub() để mọi người có thể sử dụng mô hình của bạn:
>>> trainer.push_to_hub()Để xem một ví dụ chi tiết hơn về cách tinh chỉnh mô hình cho phân loại văn bản, hãy xem notebook PyTorch tương ứng.
Suy luận
Tuyệt, giờ đây bạn đã tinh chỉnh một mô hình, bạn có thể sử dụng nó để suy luận!
Lấy một đoạn văn bản mà bạn muốn chạy suy luận:
>>> text = "This was a masterpiece. Not completely faithful to the books, but enthralling from beginning to end. Might be my favorite of the three."Cách đơn giản nhất để thử nghiệm mô hình đã tinh chỉnh của bạn cho suy luận là sử dụng nó trong một pipeline(). Khởi tạo một pipeline cho phân tích cảm xúc với mô hình của bạn, và truyền văn bản của bạn vào đó:
>>> from transformers import pipeline
>>> classifier = pipeline("sentiment-analysis", model="stevhliu/my_awesome_model")
>>> classifier(text)
[{'label': 'POSITIVE', 'score': 0.9994940757751465}]Bạn cũng có thể tự động tái tạo kết quả của pipeline nếu muốn:
Phân tách token văn bản và trả về các tensor PyTorch:
>>> from transformers import AutoTokenizer
>>> tokenizer = AutoTokenizer.from_pretrained("stevhliu/my_awesome_model")
>>> inputs = tokenizer(text, return_tensors="pt")Truyền các đầu vào của bạn vào mô hình và trả về logits:
>>> import torch
>>> from transformers import AutoModelForSequenceClassification
>>> model = AutoModelForSequenceClassification.from_pretrained("stevhliu/my_awesome_model")
>>> with torch.no_grad():
... logits = model(**inputs).logitsLấy lớp có xác suất cao nhất và sử dụng ánh xạ id2label của mô hình để chuyển đổi nó thành nhãn văn bản:
>>> predicted_class_id = logits.argmax().item()
>>> model.config.id2label[predicted_class_id]
'POSITIVE'