Bài viết này trình bày cách sử dụng mô hình tự động HuggingFace thông qua tác vụ phân loại văn bản. Nó không yêu cầu tính toán thủ công về mất mát hoặc định nghĩa thủ công các mô hình tác vụ hạ lưu. Bằng cách đọc mã nguồn triển khai mô hình tự động, bạn có thể cải thiện khả năng mô hình hóa NLP của mình.
I. Giới thiệu về nhiệm vụ và tập dữ liệu 1. Giới thiệu về nhiệm vụ Các chương trước đã định nghĩa thủ công các mô hình nhiệm vụ hạ nguồn. HuggingFace cũng cung cấp một số mô hình nhiệm vụ hạ nguồn được định nghĩa trước phổ biến, như được hiển thị bên dưới: Mô tả: Bao gồm dự đoán từ tiếp theo, điền văn bản, nhiệm vụ trả lời câu hỏi, tóm tắt văn bản, phân loại văn bản, nhận dạng thực thể được đặt tên, dịch, v.v.
2. Giới thiệu về tập dữ liệu Bài viết này sử dụng tập dữ liệu ChnSentiCorp. Nếu bạn chưa hiểu rõ, bạn có thể tham khảo phần giới thiệu về phân loại tình cảm của người Trung Quốc. Một số ví dụ được hiển thị dưới đây:
2. Chuẩn bị tập dữ liệu 1. Sử dụng công cụ mã hóa.
def load_encode_tool(tên_mô_hình_được_huấn_luyện_trước_hoặc_đường_dẫn):
""
"
Đang tải Công cụ Mã hóa
"
""
tokenizer = BertTokenizer.from_pretrained(Đường dẫn(f
'{tên_mô_hình_đã_huấn_luyện_trước_hoặc_đường_dẫn}'
))
trở lại
Mã thông báo
nếu như
__tên__ ==
'__chủ yếu__'
:
pretrained_model_name_or_path = r
'L:/20230713_HuggingFaceModel/bert-base-chinese'
tokenizer = load_encode_tool(tên_mô_hình_được_đào_tạo_trước_trước)
in
(bộ mã hóa)
Kết quả đầu ra như sau:
BertTokenizer(tên_hoặc_đường_dẫn=
'L:\20230713_HuggingFaceModel\bert-base-chinese'
, vocab_size=21128, model_max_length=100000000000000019884624838656, is_fast=False, padding_side=
'Phải'
, cắt ngắn_bên=
'Phải'
, mã thông báo đặc biệt={
'unk_token'
:
'[UNK]'
,
'mã thông báo tháng 9'
:
'[THÁNG 9]'
,
'mã thông báo pad'
:
'[BẠC]'
,
'cls_mã thông báo'
:
'[CLS]'
,
'mặt nạ_mã thông báo'
:
'[MẶT NẠ]'
}, clean_up_tokenization_spaces=Đúng)
2. Xác định tập dữ liệu và sử dụng trực tiếp đối tượng tập dữ liệu HuggingFace, như được hiển thị bên dưới:
định nghĩa load_dataset_from_disk():
pretrained_model_name_or_path = r
'L:\20230713_HuggingFaceModel\ChnSentiCorp'
tập dữ liệu = load_from_disk(tên_mô_hình_đã_huấn_luyện_trước_hoặc_đường_dẫn)
trở lại
tập dữ liệu
nếu như
__tên__ ==
'__chủ yếu__'
:
tập dữ liệu = load_dataset_from_disk()
in
(tập dữ liệu)
Kết quả đầu ra như sau:
Bộ dữ liệuDict({
tàu: Bộ dữ liệu({
đặc trưng: [
'chữ'
,
'nhãn'
],
số_hàng: 9600
})
xác thực: Dataset({
đặc trưng: [
'chữ'
,
'nhãn'
],
số_hàng: 1200
})
Bài kiểm tra
: Bộ dữ liệu({
đặc trưng: [
'chữ'
,
'nhãn'
],
số_hàng: 1200
})
})
3. Định nghĩa thiết bị điện toán.
thiết bị =
'bộ xử lý'
nếu như
torch.cuda.is_available():
thiết bị =
'cuda'
4. Định nghĩa các hàm sắp xếp dữ liệu.
def collate_fn(dữ liệu):
sents = [tôi[
'chữ'
]
vì
Tôi
TRONG
dữ liệu]
nhãn = [i[
'nhãn'
]
vì
Tôi
TRONG
dữ liệu]
dữ liệu = tokenizer.batch_encode_plus(batch_text_or_text_pairs=sents,
cắt bớt=Đúng,
padding=Đúng,
chiều dài tối đa = 512,
return_tensors=
'điểm'
)
vì
k, v
TRONG
dữ liệu. mục():
data[k] = v.to(thiết bị)
dữ liệu[
'nhãn'
] = torch.LongTensor(nhãn).to(thiết bị)
trở lại
dữ liệu
5. Xác định trình tải tập dữ liệu.
bộ nạp = torch.utils.data.DataLoader(bộ dữ liệu=bộ dữ liệu[
'xe lửa'
], batch_size=16, collate_fn=collate_fn, shuffle=Đúng, drop_last=Đúng)
in
(len(bộ nạp))
vì
tôi, dữ liệu
TRONG
liệt kê(bộ nạp):
phá vỡ
vì
k, v
TRONG
dữ liệu. mục():
in
(hình chữ k, chữ v)
Kết quả đầu ra như sau:
600
input_ids torch.Kích thước([16, 200])
token_type_ids torch.Kích thước([16, 200])
chú ý_mặt nạ torch.Kích thước([16, 200])
nhãn torch.Size([16])
3. Tải mô hình tự động Sử dụng lớp công cụ AutoModelForSequenceClassification của HuggingFace để tải mô hình tự động để triển khai tác vụ phân loại văn bản. Mã như sau:
mô hình = AutoModelForSequenceClassification.from_pretrained(Path(f
'{tên_mô_hình_đã_huấn_luyện_trước_hoặc_đường_dẫn}'
), số_nhãn=2)
model.to(thiết bị)
in
(tổng(i.numel()
vì
Tôi
TRONG
mô hình.tham số()) / 10000)
IV. Đào tạo và kiểm tra 1. Đào tạo cần giải thích rằng bản thân mô hình tự động bao gồm tính toán tổn thất, do đó không cần phải tính toán tổn thất thủ công trong train(), như được hiển thị bên dưới:
định nghĩa train():
trình tối ưu hóa = AdamW(model.parameters(), lr=5e-4)
trình lập lịch = get_scheduler(tên=
'tuyến tính'
,
số_bước_làm_ấm=0,
num_training_steps=len(bộ tải),
optimizer=người tối ưu hóa)
mô hình.train()
vì
tôi, dữ liệu
TRONG
liệt kê(bộ nạp):
ra = mô hình(**dữ liệu)
ngoài[
'sự mất mát'
].lùi lại()
optimizer.step()
trình lập lịch.step()
optimizer.zero_grad()
mô hình.zero_grad()
nếu như
tôi % 10 == 0:
kết quả ra = ra[
'logit'
].argmax(mờ=1)
độ chính xác = (out_result == data.labels).sum().item() / len(data.labels)
lr = trình tối ưu hóa.state_dict()[
'nhóm_param'
][0][
'lr'
]
in
(tôi, ra ngoài[
'sự mất mát'
].item(), lr, độ chính xác)
Trong đó, cấu trúc dữ liệu out như sau:
2. Kiểm tra.
định nghĩa
Bài kiểm tra
():
loader_test = torch.utils.data.DataLoader(bộ dữ liệu=bộ dữ liệu[
'Bài kiểm tra'
],
kích thước lô = 32,
collate_fn=collate_fn,
xáo trộn=Đúng,
drop_last=Đúng)
mô hình.eval()
đúng = 0
tổng cộng = 0
vì
tôi, dữ liệu
TRONG
liệt kê(loader_test):
nếu như
tôi == 5:
phá vỡ
in
(Tôi)
với torch.no_grad():
ra = mô hình(**dữ liệu)
ra = ra[
'logit'
].argmax(mờ=1)
đúng += (out == data.labels).sum().item()
tổng cộng += len(dữ liệu.nhãn)
in
(đúng / tổng số)
5. Mã nguồn mô hình tự động chuyên sâu 1. Quá trình tải tệp cấu hình Khi thực thi AutoModelForSequenceClassification.from_pretrained(Path(f'{pretrained_model_name_or_path}'), num_labels=2), AutoConfig.from_pretrained() thực sự được gọi. Đối tượng cấu hình được trả về bởi hàm này như sau: Đối tượng cấu hình như sau:
Cấu hình Bert {
"_tên_hoặc_đường_dẫn"
:
"L:\\20230713_HuggingFaceModel\\bert-base-chinese"
,
"kiến trúc"
: [
"BertForMaskedLM"
],
"chú ý_có_vấn_đề_bỏ_bỏ_có_vấn_đề"
: 0,1,
"phân loại_bỏ đi"
: vô giá trị,
"hướng"
:
"bidi"
,
"hành động ẩn"
:
"gelu"
,
"hidden_dropout_prob"
: 0,1,
"kích thước ẩn"
: 768,
"phạm vi khởi tạo"
: 0,02,
"kích thước trung gian"
: 3072,
"lớp_chuẩn_tiêu_số_eps"
: 1e-12,
"max_position_embeddings"
: 512,
"kiểu_mô_hình"
:
"bert"
,
"num_attention_heads"
: 12,
"số_lớp_ẩn"
: 12,
"mã_mã_băng_pad"
: 0,
"kích thước_pooler_fc"
: 768,
"pooler_num_attention_heads"
: 12,
"pooler_num_fc_layers"
: 3,
"pooler_size_per_head"
: 128,
"kiểu_pooler"
:
"chuyển đổi mã thông báo đầu tiên"
,
"kiểu nhúng_vị_trí"
:
"tuyệt đối"
,
"phiên bản_biến_hình"
:
"4.32.1"
,
"kích thước từ vựng loại"
: 2,
"sử dụng_bộ_chứa"
:
ĐÚNG VẬY
,
"kích thước từ vựng"
: 21128
}
(1) _name_or_path=bert-base-chinese : tên mô hình. (2) attention_probs_DropOut_prob=0.1: Tỷ lệ DropOut của lớp chú ý. (3) hidden_act=gelu: Hàm kích hoạt của lớp ẩn. (4) hidden_DropOut_prob=0.1: Tỷ lệ DropOut của lớp ẩn. (5) hidden_size=768: Số lượng tế bào thần kinh trong lớp ẩn. (6) layer_norm_eps=1e-12: Tham số EPS của lớp chuẩn hóa. (7) max_position_embeddings=512: Độ dài tối đa của một câu. (8) model_type=bert: loại mô hình. (9) num_attention_heads=12 : Số lượng đầu của lớp chú ý. (10) num_hidden_layers=12 : Số lớp ẩn. (11) pad_token_id=0: Số PAD. (12) pooler_fc_size=768: Số lượng tế bào thần kinh trong lớp gộp. (13) pooler_num_attention_heads=12: Số lượng đầu chú ý trong lớp nhóm. (14) pooler_num_fc_layers=3: Số lớp mạng nơ-ron được kết nối đầy đủ trong lớp gộp. (15) vocab_size=21128 : Kích thước của từ điển.
2. Quy trình mô hình khởi tạo Trình xây dựng lớp BertForSequenceClassification bao gồm mô hình BERT và mạng nơ-ron được kết nối đầy đủ. Ý tưởng cơ bản là trích xuất các tính năng thông qua BERT và phân loại thông qua mạng nơ-ron được kết nối đầy đủ, như được hiển thị bên dưới:
def __init__(bản thân, cấu hình):
siêu().__init__(cấu hình)
self.num_labels = config.num_labels
self.config = cấu hình
self.bert = BertModel(cấu hình)
phân loại_bỏ đi = (
cấu hình.phân loại_dropout
nếu như
config.classifier_dropout không phải là Không có
khác
cấu hình.hidden_dropout_prob
)
self.dropout = nn.Dropout(phân loại_dropout)
self.classifier = nn.Linear(config.hidden_size, config.num_labels)
tự.post_init()
Giả thuyết trên có thể được chứng minh bằng hàm forward() và hàm mất mát được chọn theo loại vấn đề: hồi quy (hàm mất mát MSELoss()), phân loại nhãn đơn (hàm mất mát CrossEntropyLoss()) và phân loại nhãn đa (hàm mất mát BCEWithLogitsLoss()).
Tài liệu tham khảo: [1] Giải thích chi tiết về Xử lý ngôn ngữ tự nhiên HuggingFace: Thực hành nhiệm vụ dựa trên Mô hình tiếng Trung BERT [2] https://github.com/ai408/nlp-engineering/blob/main/20230625_Giải thích chi tiết về Xử lý ngôn ngữ tự nhiên HuggingFace/Chương 12: Sử dụng Automatic Model.py.
Tôi là một lập trình viên xuất sắc, rất giỏi!