Cum ajustezi fin BERT pentru NER? Care este loss-ul și tokenizarea etichetelor?
sobes.tech AI
Răspuns de la AI
Pentru ajustarea BERT pentru sarcina NER, se utilizează de obicei abordarea următoare:
-
Tokenizare: se folosește tokenizatorul WordPiece al BERT. Etichetele (labels) pentru NER corespund de obicei tokenurilor, dar deoarece WordPiece împarte cuvintele în subcuvinte, eticheta se atribuie primului subcuvânt, iar pentru celelalte subcuvinte, de obicei, se pune o etichetă specială (de exemplu, "X") sau se repetă eticheta primului subcuvânt.
-
Formatul etichetelor: se folosește adesea schema BIO (Begin, Inside, Outside) pentru a indica începutul și continuarea entităților.
-
Funcția de pierdere: de obicei, se aplică Cross-Entropy Loss pentru clasificarea fiecărui token. Tokenurile care nu trebuie să contribuie la pierdere (de exemplu, padding sau subcuvinte cu eticheta "X") sunt mascate.
Exemplu în PyTorch cu HuggingFace Transformers:
from transformers import BertForTokenClassification, BertTokenizerFast
import torch
model = BertForTokenClassification.from_pretrained('bert-base-cased', num_labels=num_labels)
tokenizer = BertTokenizerFast.from_pretrained('bert-base-cased')
# Exemplu de propoziție și etichete
sentence = "John lives in New York"
labels = [1, 0, 0, 2, 3] # Exemplu de etichete în format BIO
encoding = tokenizer(sentence.split(), is_split_into_words=True, return_tensors="pt", truncation=True)
# Transformarea etichetelor pentru subcuvinte
word_ids = encoding.word_ids()
label_ids = []
previous_word_idx = None
for word_idx in word_ids:
if word_idx is None:
label_ids.append(-100) # Ignoră padding
elif word_idx != previous_word_idx:
label_ids.append(labels[word_idx])
else:
label_ids.append(-100) # Ignoră subcuvinte
previous_word_idx = word_idx
outputs = model(**encoding, labels=torch.tensor([label_ids]))
loss = outputs.loss
loss.backward()
Punctele cheie sunt o tokenizare atentă cu alinierea etichetelor și utilizarea Cross-Entropy Loss cu mascarea.