RoBERTa: Eine optimierte Methode zum Vortrainieren selbstüberwachter NLP-Systeme
Vortrainierte Sprachmodelle haben bemerkenswerte Erfolge in der Verarbeitung natürlicher Sprache (NLP) erzielt und zu einem Paradigmenwechsel vom überwachten Lernen hin zum Vortraining mit anschließendem Fine-Tuning geführt. Das Ziel der Sprachmodellierung besteht darin, das nächste Token in einer Sequenz vorherzusagen, gegeben eine Historie unannotierter Texte, also großer Mengen roher Textdaten, die nicht mit spezifischen Informationen gekennzeichnet wurden. BERT (Bidirectional Encoder Representations from Transformers) setzt neue Maßstäbe für dieses Konzept, indem es bidirektionales Sprachverständnis ermöglicht, da es den gesamten Satz betrachtet und nicht nur jeweils ein Wort. Es berücksichtigt die Wörter davor und danach, um deren Bedeutung besser zu verstehen.
Das Hauptproblem, das bei BERT festgestellt wurde, war jedoch sein unzureichendes Training, das seine Leistung bei NLP-Aufgaben einschränkte. Diese Einschränkung veranlasste die Forscher dazu, in nachfolgenden Modellen wie RoBERTa verbesserte Trainingsmethoden zu untersuchen.
RoBERTa (A Robustly Optimized BERT Pretraining Approach) ist eine verbesserte Version von BERT, die entwickelt wurde, um dessen Einschränkungen zu beheben. RoBERTa führte mehrere wichtige Verbesserungen ein, die seine Leistung bei verschiedenen NLP-Problemen steigern.
Dieser Artikel behandelt die Methoden und Technologien, die bei der Entwicklung von RoBERTa verwendet wurden, einschließlich seines Trainingsansatzes, der erzielten Ergebnisse und der potenziellen zukünftigen Forschungsmöglichkeiten, die es eröffnet.
Eine kurze Einführung in BERT (Bidirectional Encoder Representations from Transformers)
Um RoBERTa zu verstehen, ist es wichtig, seinen Vorgänger BERT und die Herausforderungen, mit denen er konfrontiert war, zu verstehen. BERT führte das Konzept bidirektionaler Transformer ein und ermöglichte es Deep-Learning-Modellen, Kontext auf eine zuvor unerreichbare Weise zu verstehen.
Aber um wirklich zu verstehen, wie BERT funktioniert, müssen wir es aufschlüsseln. Werfen wir also einen genaueren Blick auf seine Architektur und darauf, wie es trainiert wurde.
BERTs Architektur und Vortrainingsprozess
BERTs Architektur basiert auf Transformers, eingeführt von Devlin et al. im Jahr 2018. Sie verwendet einen mehrschichtigen bidirektionalen (von links nach rechts und von rechts nach links) Encoder, um die Wichtigkeit verschiedener Wörter in einem Satz zu gewichten.
BERT-Architektur
Abbildung 1: BERT-Architektur
Ein Wort beginnt mit seiner Embedding-Darstellung aus der Embedding-Schicht; ein Embedding ist ein dichter Vektor (numerische Darstellung) eines Wortes oder Tokens in einem hochdimensionalen Raum. Die Embedding-Schicht ist die erste Schicht in einem neuronalen Netzwerk, die Eingabewörter in diese dichten Vektoren umwandelt. Jede Schicht führt Multi-Head-Attention-Berechnungen auf der Wortdarstellung der vorherigen Schicht durch, um eine neue Zwischendarstellung zu erzeugen. Alle diese Zwischendarstellungen haben die gleiche Größe. In der obigen Abbildung ist E1 die Embedding-Darstellung, T1 die endgültige Ausgabe und Trm die Zwischendarstellung des Tokens.
BERTs Vortrainingsprozess umfasst zwei Hauptaufgaben:
Masked Language Modeling (MLM)
Next-Sentence Prediction (NSP)
Sprachmodellierung sagt das nächste Wort anhand einer Sequenz von Wörtern voraus. Bei der MLM-Aufgabe wird jedoch, anstatt jedes nächste Token vorherzusagen, ein Prozentsatz der Eingabetokens zufällig maskiert, und nur diese maskierten Tokens werden vorhergesagt. Die NSP-Aufgabe hingegen ist eine binäre Klassifikationsaufgabe, die vorhersagt, ob zwei gegebene Sätze im Originaltext aufeinander folgen. Dieser Ansatz hilft dem Modell, die Beziehungen zwischen Sätzen zu verstehen.
Next Sentence Prediction
Abbildung 2: Next Sentence Prediction
BERTs Vortrainingsprozess hatte Einschränkungen, die verhinderten, dass es sein volles Potenzial erreichte. Eines der Hauptprobleme war die Verwendung eines statischen Maskierungsmusters in der MLM-Aufgabe. In BERT wurden, sobald ein Wort während des Trainings maskiert wurde, dieselben Wörter über alle Iterationen hinweg maskiert. Dieser statische Ansatz beschränkte das Modell auf unterschiedliche Maskierungsszenarien und verringerte seine Generalisierungsfähigkeit. Darüber hinaus waren auch die Größe der Trainingsdaten und die Dauer begrenzt.
Diese Einschränkungen führten zu Inkonsistenzen in BERTs Leistung bei domänenspezifischen Aufgaben, wie der Analyse juristischer oder medizinischer Texte, und bei komplexen Szenarien des Sprachverständnisses, wie Sentimentanalyse oder mehrstufigem Schlussfolgern. Die Behebung dieser Schwächen erfordert weitere Forschung und Entwicklung.
Das Aufkommen von RoBERTa
Die Hauptmotivation hinter der Entwicklung von RoBERTa bestand darin, die Herausforderungen anzugehen, die im Vortrainingsprozess von BERT beobachtet wurden. RoBERTa behält jedoch dieselbe Kernarchitektur wie Bert Large bei, die aus 24 Schichten, 1024 verborgenen Einheiten und 16 Attention-Heads besteht und insgesamt 355 Millionen Parameter umfasst.
Die Herausforderungen, die RoBERTa angehen sollte, waren:
Statisches Maskierungsmuster: BERTs statische Maskierung führte zu begrenzten Trainingsszenarien und verursachte Overfitting. Overfitting tritt auf, wenn ein Modell bei Trainingsdaten sehr gut abschneidet, aber bei Testdaten (neuen Daten) schlecht abschneidet. RoBERTa führte dynamische Maskierung ein, erzeugte neue Masken für jede Epoche und verbesserte seine Fähigkeit, mit neuen Daten umzugehen.
Unzureichende Trainingsdaten: BERTs Training basierte auf einem Datensatz von etwa 16 GB Text, was nicht ausreicht, um die volle Vielfalt der Sprache zu erfassen. RoBERTa skalierte die Trainingsdaten hoch und verwendete über 160 GB Text aus verschiedenen Quellen.
Kurze Trainingsdauer: Das ursprüngliche BERT-Modell wurde für eine relativ kurze Dauer trainiert, aber RoBERTa verlängerte die Trainingsdauer erheblich und lief über mehr Epochen und Iterationen.
Kleine Batch-Größen und konservative Lernraten: BERTs Vortraining verwendete relativ kleine Batch-Größen und konservative Lernraten, was ein sicherer, aber einschränkender Ansatz war. RoBERTa hingegen experimentierte mit größeren Batch-Größen und aggressiveren Lernraten, was zu einer besseren Modellleistung führte.
Was ist RoBERTa und wie funktioniert es?
RoBERTa (A Robustly Optimized BERT Pretraining Approach) ist eine verbesserte Version von BERT, die entwickelt wurde, um dessen Einschränkungen zu beheben und die Leistung zu verbessern. Es führte Änderungen am Trainingsprozess von BERT ein, die seine Leistung bei Aufgaben der Verarbeitung natürlicher Sprache verbessern.
Diese Änderungen umfassen:
Dynamische Maskierung
Entfernung von NSP
Größere Trainingsdaten und verlängerte Dauer
Erhöhung der Batch-Größen
Byte-Textkodierung
Dynamische Maskierung
Aus der Architektur von BERT erinnern wir uns, dass BERT während des Vortrainings Masked Language Modeling (MLM) durchführte, indem es versuchte, einen bestimmten Prozentsatz maskierter Tokens vorherzusagen. Diese ausgewählten maskierten Tokens waren in jeder Iteration dieselben (statisch).
RoBERTa ging dieses Problem an, indem es einen etwas besseren Ansatz namens dynamisches Maskieren implementierte. Dieser Ansatz ändert das Maskierungsschema jedes Mal, wenn während des Trainings eine Sequenz an BERT übergeben wird. Diese Änderung machte die Trainingsdaten vielfältiger, sodass das Modell ein breiteres Spektrum an Sprachmustern lernen konnte. Infolgedessen entwickelte RoBERTa ein tieferes Verständnis von Kontext, was die Leistung bei nachgelagerten Aufgaben verbesserte.
Statisches Maskieren vs. dynamisches Maskieren
Abbildung 3: Statisches Maskieren vs. dynamisches Maskieren
Die Forscher, die RoBERT entwickelt haben, implementierten auch den Ansatz des statischen Maskierens neu, indem sie die Trainingsdaten 10-mal duplizierten. Diese Duplizierung ermöglichte es, jede Sequenz über die 40 Trainingsepochen hinweg auf zehn verschiedene Arten zu maskieren. Somit wurde jede Trainingssequenz während des Trainings viermal mit derselben Maske gesehen. Die Leistung war ähnlich, wenn man die Neuimplementierung des statischen Maskierens mit dem ursprünglichen BERT-Modell verglich. Dynamisches Maskieren zeigt jedoch eine etwas bessere Leistung als statisches Maskieren.
Vergleich zwischen statischem und dynamischem Maskieren
Abbildung 4: Vergleich zwischen statischem und dynamischem Maskieren
Entfernung der Next-Sentence-Prediction (NSP)
Eine weitere wichtige Änderung in RoBERTa war die Entfernung der NSP-Aufgabe. Bei NSP erhielt das Modell Satzpaare und musste vorhersagen, ob der zweite Satz im ursprünglichen Text auf den ersten folgte. Bei der Entwicklung von RoBERTa stellte sich jedoch heraus, dass die NSP-Aufgabe nur minimal zur Leistung des Modells bei nachgelagerten Aufgaben beitrug.
RoBERTa verwendet einen FULL-SENTENCES-Ansatz (Packen von Sequenzen aus mehreren Dokumenten). Jede Eingabe in das Modell wird mit vollständigen Sätzen gepackt, die zusammenhängend aus einem oder mehreren Dokumenten bis zur maximalen Sequenzlänge von 512 Tokens entnommen werden. Dadurch kann das Modell langfristige Abhängigkeiten effektiver lernen.
BERT mit und ohne NSP
Abbildung 5: BERT mit und ohne NSP
Zusätzlich untersuchten die Forscher vier verschiedene Möglichkeiten, Eingabedaten für ein Sprachmodell zu formatieren. Sie verglichen zwei Hauptformate: das ursprüngliche SEGMENT-PAIR und SENTENCE-PAIR. Beide Formate verwenden NSP, aber das SENTENCE-PAIR-Format verwendet einzelne Sätze statt Paare. Die Forscher stellten fest, dass die Verwendung einzelner Sätze die Leistung des Modells bei Aufgaben verschlechterte, da es Schwierigkeiten hatte, Verbindungen zwischen Wörtern zu verstehen, die im Text weit voneinander entfernt sind.
Als Nächstes testeten sie das Modell, indem sie es ohne die NSP-Methode trainierten und Textblöcke aus einem Dokument namens DOC-SENTENCES verwendeten. In den meisten Fällen stellten sie fest, dass es besser abschnitt als das ursprüngliche BERT, und die Nichtverwendung des NSP-Verlusts beeinträchtigte die Leistung des Modells nicht.
Die Methode mit Text aus einem einzelnen Dokument (DOC-SENTENCES) war etwas besser als die aus mehreren Dokumenten (FULL-SENTENCES). Da DOC-SENTENCES jedoch während des Trainings zu unterschiedlichen Batch-Größen führte, entschieden sie sich, für den Rest ihrer Experimente FULL-SENTENCES zu verwenden. Diese Entscheidung erleichterte es, ihre Ergebnisse mit denen anderer verwandter Studien zu vergleichen.
Ergebnisse für Basismodelle, die über BOOK CORPUS und WIKIPEDIA vortrainiert wurden
Abbildung 6: Ergebnisse für Basismodelle, die über BOOK CORPUS und WIKIPEDIA vortrainiert wurden
Größere Trainingsdaten und längere Dauer
Die vielleicht naheliegendste Optimierung, aber nicht weniger wichtig, besteht einfach darin, länger mit mehr Daten zu trainieren. BERT wurde auf einem Datensatz von etwa 16 GB Text trainiert, und RoBERTa verwendete über 160 GB Text.
RoBERTa-Datensätze:
BOOK-CORPUS und WIKIPEDIA: Dasselbe wie BERT.
CC-NEWS: RoBERTa führt einen neuen Datensatz namens CC-NEWS ein, einen umfangreichen Nachrichtendatensatz mit zeitgenössischer Sprache und einer breiten Palette an Themen, Stilen und Perspektiven.
Zusätzliche Datensätze: RoBERTa kombiniert die oben genannten Datensätze mit drei weiteren im Paper beschriebenen privaten Datensätzen, wodurch die Leistung bei nachgelagerten Aufgaben verbessert wird.
Durch die Verwendung größerer Trainingsdaten, die Verlängerung der Trainingsdauer und das Ausführen über mehr Epochen und Iterationen zeigt RoBERTa eine deutliche Verbesserung von 4-6 % bei nachgelagerten Aufgaben im Vergleich zu den ursprünglich berichteten BERT-Ergebnissen (Devlin et al. im Jahr 2018).
Ergebnisse für RoBERTa gegenüber BERT
Abbildung 7: Ergebnisse für RoBERTa gegenüber BERT
Erhöhung der Batch-Größen
Frühere Arbeiten zur neuronalen maschinellen Übersetzung haben gezeigt, dass das Training mit sehr großen Mini-Batches die Perplexität für Masked Language Modeling verbessern kann. Dieser Ansatz verbessert die Leistung bei Endaufgaben, wenn die Lernrate entsprechend erhöht wird (Ott et al., 2018). Perplexität ist eine Metrik zur Messung der Leistung von Sprachmodellen. Sie quantifiziert die Unsicherheit (Wahrscheinlichkeitsverteilung), die ein Modell bei der Vorhersage des nächsten Wortes in einer Sequenz hat. Beispielsweise gilt: Je niedriger die Perplexität, desto genauer die Vorhersagen.
Basierend auf diesem Konzept verwendet RoBERTa während des Trainings deutlich größere Mini-Batches. Während BERT eine Batch-Größe von 256 Sequenzen für eine Million Schritte verwendete, erhöhte RoBERTa dies auf 8k Sequenzen für 31k Schritte mit einem Lernratenwert von 1e-3. Die optimale Leistung wurde jedoch mit 2k Sequenzen für 125k Schritte beobachtet.
Vergleich von Perplexität und Endaufgaben-Leistung von BERT vs. RoBERTa
Abbildung 8: Vergleich von Perplexität und Endaufgaben-Leistung von BERT vs. RoBERTa
Byte-Textkodierung
RoBERTa führte außerdem eine alternative Methode zum Umgang mit Out-of-Vocabulary-(OOV)-Wörtern ein, indem Byte-level Byte Pair Encoding (BPE) eingesetzt wurde. BERT verwendete ein Character-level Byte-Pair Encoding (BPE)-Vokabular mit 30K Einheiten. RoBERTa erweitert dies auf ein Byte-level BPE-Vokabular mit 50K Subword-Einheiten ohne zusätzliche Eingabevorverarbeitung oder Tokenisierung. Im Vergleich zu BERT ermöglichte diese Methode RoBERTa, nahezu jedes Wort oder Subword zu kodieren, ohne das unbekannte Token zu verwenden.
Byte-Textkodierung
Abbildung 9: Byte-Textkodierung
Experimentergebnisse
Nach der Modifizierung von BERT(Devlin et al. 2019) wurde RoBERTa auf NLP-Benchmarks getestet. Wir werden seine Leistung auf drei Benchmarks besprechen: GLUE, SQuAD und RACE.
GLUE (General Language Understanding Evaluation): Eine Sammlung von 9 Datensätzen für NLU-Aufgaben (Natural Language Understanding).
SQuAD (Stanford Question Answering Dataset): Ein Datensatz, der für das Training und die Bewertung von Frage-Antwort-Systemen entwickelt wurde. Er besteht aus echten Fragen, die von Menschen zu einer Reihe von Wikipedia-Artikeln gestellt wurden, wobei die Antwort auf jede Frage eine bestimmte Textspanne innerhalb des entsprechenden Artikels ist.
RACE (Reading Comprehension from Examinations): Ein umfangreicher Datensatz zum Leseverständnis wurde aus englischen Prüfungen gesammelt.
Testergebnisse auf dem GLUE-Datensatz
RoBERTa wurde mit zwei Fine-Tuning-Einstellungen getestet. In der ersten Einstellung (Single-Task) wurde RoBERTa separat für 10 Epochen für jede GLUE Aufgabe fine-getunt, wobei nur die Trainingsdaten für die entsprechende Aufgabe verwendet wurden. Es erzielte State-of-the-Art-Ergebnisse bei allen neun GLUE-Aufgaben und übertraf sowohl BERT als auch XLNet. In der zweiten Einstellung (Ensembles) erreichte RoBERTa 88.5 auf dem GLUE Leaderboard und erreichte damit den bisherigen State of the Art von XLNet. RoBERTa setzte neue State-of-the-Art-Ergebnisse bei 4 von 9 GLUE-Aufgaben: MNLI, QNLI, RTE und STS-B.
Ergebnisse auf GLUE
Abbildung 10: Ergebnisse auf GLUE
SQuAD
RoBERTa wurde mit den SQuAD-Trainingsdaten fine-getunt. Auf SQuAD v1.1 erreicht RoBERTa den von XLNet gesetzten State of the Art. Auf SQuAD v2.0 erzielte RoBERTa einen F1-Score von 89.4 und setzte damit einen neuen State of the Art für einzelne Modelle ohne Datenaugmentation. Dies ist besonders beeindruckend, da RoBERTa keine SQuAD-spezifischen Techniken verwendet und nur auf SQuAD-Daten fine-getunt wird.
Ergebnisse auf SQuAD
Abbildung 11: Ergebnisse auf SQuAD
Testergebnisse auf dem RACE-Datensatz
RACE ist ein anspruchsvoller Benchmark für Leseverständnis, der von Modellen verlangt, Multiple-Choice-Fragen auf der Grundlage von Passagen aus Englischprüfungen zu beantworten. Dieser Benchmark ist besonders schwierig, da er von Modellen verlangt, komplexe Passagen zu verstehen und die richtigen Antworten aus dem Kontext abzuleiten. RoBERTa erreichte eine Genauigkeit von 83.2% auf dem RACE-Benchmark und setzte neue State-of-the-Art-Standards.
Ergebnisse auf dem RACE-Testset
Abbildung 12: Ergebnisse auf dem RACE-Testset
Fine-Tuning von RoBERTa für Sentimentanalyse
Über seine Leistung auf Standard-Benchmarks hinaus hat sich RoBERTa auch als äußerst effektiv für das Fine-Tuning spezifischer Aufgaben erwiesen, wie etwa der Sentimentanalyse. Fine-Tuning bedeutet, ein vortrainiertes Modell zu nehmen und es an eine bestimmte Aufgabe anzupassen, indem es auf einem kleineren, aufgabenspezifischen Datensatz trainiert wird. Der in diesem Artikel verwendete Quellcode stammt von Hugging Face.
Importieren und Vorbereiten des Datensatzes
Wir verwenden den Datensatz, der bei der Kaggle Competition verfügbar ist, und beziehen uns nur auf die erste csv-Datei aus dem Datendump: train.tsv.
Importieren von Python-Bibliotheken:
!pip install transformers==3.0.2
Importieren Sie in diesem Schritt die Bibliotheken und Module, die zum Ausführen unseres Skripts benötigt werden.
# Importing the libraries needed
import pandas as pd
import numpy as np
import torch
import transformers
import json
from tqdm import tqdm
from torch.utils.data import Dataset, DataLoader
from transformers import RobertaModel, RobertaTokenizer
import logging
logging.basicConfig(level=logging.ERROR)
# Setting up the device for GPU usage
from torch import cuda
device = 'cuda' if cuda.is_available() else 'cpu'
Vorbereiten des Datensatzes
Laden Sie zunächst den Datensatz und lesen Sie ihn mit dem Pandas-Paket ein.
train = pd.read_csv('train.tsv', delimiter='\t')
new_df = train[['Phrase', 'Sentiment']]
Definieren wir einige Variablen:
MAX_LEN: Die maximale Länge des Eingabetextes (256).
TRAIN_BATCH_SIZE and VALID_BATCH_SIZE: Die Batch-Größen für Training und Validierung (8 bzw. 4).
LEARNING_RATE: Die Lernrate für das Modell (1e-05).
Tokenizer: Eine RobertaTokenizer-Instanz wird verwendet, um die Textdaten vorzuverarbeiten.
Die SentimentData-Klasse implementiert eine benutzerdefinierte Dataset-Klasse, die einen Dataframe, Tokenizer und eine maximale Länge als Eingaben entgegennimmt. Sie verarbeitet die Textdaten vor und gibt ein Dictionary zurück, das Eingabe-IDs, Attention-Masken, Token-Typ-IDs und Ziel-Sentiment-Labels enthält.
Die DataLoader-Klasse erstellt Data Loader für die Trainings- und Testsätze und iteriert während Training und Validierung in Batches über die Daten.
# Defining some key variables that will be used later on in the training
MAX_LEN = 256
TRAIN_BATCH_SIZE = 8
VALID_BATCH_SIZE = 4
LEARNING_RATE = 1e-05
tokenizer = RobertaTokenizer.from_pretrained('roberta-base', truncation=True, do_lower_case=True)
class SentimentData(Dataset):
def __init__(self, dataframe, tokenizer, max_len):
self.tokenizer = tokenizer
self.data = dataframe
self.text = dataframe.Phrase
self.targets = self.data.Sentiment
self.max_len = max_len
def __len__(self):
return len(self.text)
def __getitem__(self, index):
text = str(self.text[index])
text = " ".join(text.split())
inputs = self.tokenizer.encode_plus(
text,
None,
add_special_tokens=True,
max_length=self.max_len,
pad_to_max_length=True,
return_token_type_ids=True
)
ids = inputs['input_ids']
mask = inputs['attention_mask']
token_type_ids = inputs["token_type_ids"]
return {
'ids': torch.tensor(ids, dtype=torch.long),
'mask': torch.tensor(mask, dtype=torch.long),
'token_type_ids': torch.tensor(token_type_ids, dtype=torch.long),
'targets': torch.tensor(self.targets[index], dtype=torch.float)
}
train_size = 0.8
train_data=new_df.sample(frac=train_size,random_state=200)
test_data=new_df.drop(train_data.index).reset_index(drop=True)
train_data = train_data.reset_index(drop=True)
print("FULL Dataset: {}".format(new_df.shape))
print("TRAIN Dataset: {}".format(train_data.shape))
print("TEST Dataset: {}".format(test_data.shape))
training_set = SentimentData(train_data, tokenizer, MAX_LEN)
testing_set = SentimentData(test_data, tokenizer, MAX_LEN)
train_params = {'batch_size': TRAIN_BATCH_SIZE,
'shuffle': True,
'num_workers': 0
}
test_params = {'batch_size': VALID_BATCH_SIZE,
'shuffle': True,
'num_workers': 0
}
training_loader = DataLoader(training_set, **train_params)
testing_loader = DataLoader(testing_set, **test_params)
Erstellen des neuronalen Netzwerks für das Fine-Tuning
Wir werden ein neuronales Netzwerk mit RobertaClass erstellen.
Dieses Netzwerk wird das Roberta-Sprachmodell enthalten, gefolgt von einem Dropout und schließlich einer linearen Schicht, um die finalen Ausgaben zu erhalten.
Die Daten werden dem Roberta-Sprachmodell gemäß der Definition im Dataset zugeführt.
Die Ausgabe der finalen Schicht wird mit der Sentiment-Kategorie verglichen, um die Genauigkeit der Vorhersage des Modells zu bestimmen.
Wir werden eine Instanz des Netzwerks namens Model initialisieren. Diese Instanz wird für das Training verwendet.
class RobertaClass(torch.nn.Module):
def __init__(self):
super(RobertaClass, self).__init__()
self.l1 = RobertaModel.from_pretrained("roberta-base")
self.pre_classifier = torch.nn.Linear(768, 768)
self.dropout = torch.nn.Dropout(0.3)
self.classifier = torch.nn.Linear(768, 5)
def forward(self, input_ids, attention_mask, token_type_ids):
output_1 = self.l1(input_ids=input_ids, attention_mask=attention_mask, token_type_ids=token_type_ids)
hidden_state = output_1[0]
pooler = hidden_state[:, 0]
pooler = self.pre_classifier(pooler)
pooler = torch.nn.ReLU()(pooler)
pooler = self.dropout(pooler)
output = self.classifier(pooler)
return output
model = RobertaClass()
model.to(device)
Feinabstimmung des Modells
Nach all dem Aufwand, den Datensatz zu laden und vorzubereiten und das Modell zu erstellen, ist dies wahrscheinlich der einfachere Schritt im Prozess.
Hier definieren wir eine Trainingsfunktion, die das Modell für eine festgelegte Anzahl von Epochen auf dem obigen Trainingsdatensatz trainiert. Eine Epoche definiert, wie oft die vollständigen Daten durch das Netzwerk geleitet werden.
# Creating the loss function and optimizer
loss_function = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(params = model.parameters(), lr=LEARNING_RATE)
def calcuate_accuracy(preds, targets):
n_correct = (preds==targets).sum().item()
return n_correct
# Defining the training function on the 80% of the dataset for tuning the distilbert model
def train(epoch):
tr_loss = 0
n_correct = 0
nb_tr_steps = 0
nb_tr_examples = 0
model.train()
for _,data in tqdm(enumerate(training_loader, 0)):
ids = data['ids'].to(device, dtype = torch.long)
mask = data['mask'].to(device, dtype = torch.long)
token_type_ids = data['token_type_ids'].to(device, dtype = torch.long)
targets = data['targets'].to(device, dtype = torch.long)
outputs = model(ids, mask, token_type_ids)
loss = loss_function(outputs, targets)
tr_loss += loss.item()
big_val, big_idx = torch.max(outputs.data, dim=1)
n_correct += calcuate_accuracy(big_idx, targets)
nb_tr_steps += 1
nb_tr_examples+=targets.size(0)
if _%5000==0:
loss_step = tr_loss/nb_tr_steps
accu_step = (n_correct*100)/nb_tr_examples
print(f"Training Loss per 5000 steps: {loss_step}")
print(f"Training Accuracy per 5000 steps: {accu_step}")
optimizer.zero_grad()
loss.backward()
# # When using GPU
optimizer.step()
print(f'The Total Accuracy for Epoch {epoch}: {(n_correct*100)/nb_tr_examples}')
epoch_loss = tr_loss/nb_tr_steps
epoch_accu = (n_correct*100)/nb_tr_examples
print(f"Training Loss Epoch: {epoch_loss}")
print(f"Training Accuracy Epoch: {epoch_accu}")
return
EPOCHS = 1
for epoch in range(EPOCHS):
train(epoch)
Ausgabe:
Abbildung 13- Details des Modelltrainings
Validierung der Modellleistung
Während der Validierungsphase übergeben wir die ungesehenen Daten (den Testdatensatz) an das Modell. Dieser Schritt bestimmt, wie gut das Modell mit den ungesehenen Daten abschneidet, die 20 % von train.tsv ausmachen und während der Datensatzerstellungsphase abgetrennt wurden.
Die Validierungsphase überprüft die Generalisierungsfähigkeit des Modells auf neue, ungesehene Daten. Die Gewichte des Modells wurden nicht aktualisiert. Nur die endgültige Ausgabe wird mit dem tatsächlichen Wert verglichen, der dann zur Berechnung der Genauigkeit des Modells verwendet wird.
Die Funktion valid implementiert die Validierungsphase und nimmt das Modell und den Test-Loader als Eingaben. Sie versetzt das Modell in den Evaluierungsmodus, initialisiert Variablen zur Verfolgung korrekter und inkorrekter Vorhersagen und iteriert über den Test-Loader. Für jeden Batch berechnet sie den Verlust und die Genauigkeit und gibt den Validierungsverlust und die Validierungsgenauigkeit alle 5000 Schritte sowie am Ende der Epoche aus. Schließlich gibt sie die Epochen-Genauigkeit zurück.
def valid(model, testing_loader):
model.eval()
n_correct = 0; n_wrong = 0; total = 0; tr_loss=0; nb_tr_steps=0; nb_tr_examples=0
with torch.no_grad():
for _, data in tqdm(enumerate(testing_loader, 0)):
ids = data['ids'].to(device, dtype = torch.long)
mask = data['mask'].to(device, dtype = torch.long)
token_type_ids = data['token_type_ids'].to(device, dtype=torch.long)
targets = data['targets'].to(device, dtype = torch.long)
outputs = model(ids, mask, token_type_ids).squeeze()
loss = loss_function(outputs, targets)
tr_loss += loss.item()
big_val, big_idx = torch.max(outputs.data, dim=1)
n_correct += calcuate_accuracy(big_idx, targets)
nb_tr_steps += 1
nb_tr_examples+=targets.size(0)
if _%5000==0:
loss_step = tr_loss/nb_tr_steps
accu_step = (n_correct*100)/nb_tr_examples
print(f"Validation Loss per 100 steps: {loss_step}")
print(f"Validation Accuracy per 100 steps: {accu_step}")
epoch_loss = tr_loss/nb_tr_steps
epoch_accu = (n_correct*100)/nb_tr_examples
print(f"Validation Loss Epoch: {epoch_loss}")
print(f"Validation Accuracy Epoch: {epoch_accu}")
return epoch_accu
acc = valid(model, testing_loader)
print("Accuracy on test data = %0.2f%%" % acc)
Ausgabe:
Abbildung 14 – Details der Modellvalidierung
Wie Sie sehen können, sagt das Modell die richtige Kategorie einer gegebenen Stichprobe mit einer Genauigkeit von 69,47 % voraus, die durch weiteres Training noch verbessert werden kann.
Zukünftige Forschungsmöglichkeiten
Der Erfolg von RoBERTa hat neue Türen für die Forschung im Bereich NLP und Modelloptimierung geöffnet. Hier sind einige potenzielle Forschungsmöglichkeiten:
Skalierung von Datensätzen
Größere Datensätze und längere Trainingszeiten haben RoBERTa verbessert. Zukünftige Forschung könnte die dynamische Skalierung von Datensätzen untersuchen, bei der Modelle im Laufe der Zeit mit zunehmend größeren Datensätzen trainiert werden. Dieser Ansatz könnte uns helfen zu verstehen, wie das Modell aus neuen Daten lernt und ob es sich weiter verbessern kann, während seine Daten skaliert werden.
Multi-Task-Fine-Tuning
Die Leistung von RoBERTa könnte durch die Untersuchung fortschrittlicher Multi-Task-Fine-Tuning-Verfahren weiter verbessert werden. Derzeit ist es in vielen Dingen gut, ohne gleichzeitig auf mehrere Aufgaben trainiert zu werden. Forscher könnten jedoch untersuchen, wie die Integration mehrerer Aufgaben während der Fine-Tuning-Phase die Leistung über verschiedene Benchmarks hinweg verbessern könnte.
Untersuchung von Pre-Training-Zielen
Das Entfernen des NSP-Ziels und die Verwendung eines dynamischen Maskierungsansatzes anstelle einer statischen Maskierung in RoBERTa werfen Fragen dazu auf, ob es noch bessere Möglichkeiten gibt, Sprachmodelle zu trainieren. Zukünftige Forschung kann verschiedene Pre-Training-Methoden untersuchen, die beeinflussen, wie gut RoBERTa Aufgaben versteht und ausführt.
Fazit
Das RoBERTa-Paper leistet mehrere wichtige Beiträge zum Bereich NLP. Die Autoren stellen fest, dass das dynamische Ändern des Maskierungsmusters in den Trainingsdaten, das Training mit längeren Sequenzen und das Entfernen der NSP-Aufgabe die Leistung bei nachgelagerten Aufgaben verbessern können.
Darüber hinaus tragen auch die Verwendung einer größeren Batch-Größe und eines größeren Trainingsdatensatzes zu dieser Verbesserung bei. RoBERTa erzielt modernste Ergebnisse bei GLUE, RACE und SQuAD ohne Multi-Task-Fine-Tuning für GLUE oder zusätzliche Daten für SQuAD.
Außerdem geht es in der Debatte zwischen RoBERTa und BERT nicht nur darum, welches Modell besser ist. Es geht darum, die Abwägungen zwischen Rechenressourcen, Modellleistung und den ethischen Implikationen des Einsatzes dieser Modelle zu verstehen. Die Fortschritte von RoBERTa gegenüber BERT zeigen, dass der Bereich NLP keineswegs statisch ist, und öffnen die Tür zu einem Weg hin zu fortschrittlicheren und komplexeren Sprachverarbeitungsfähigkeiten.
Weitere Ressourcen
Weiterlesen

Zilliz Cloud Now Available in Azure North Europe: Bringing AI-Powered Vector Search Closer to European Customers
The addition of the Azure North Europe (Ireland) region further expands our global footprint to better serve our European customers.

Vector Databases vs. Time Series Databases
Use a vector database for similarity search and semantic relationships; use a time series database for tracking value changes over time.

What is the K-Nearest Neighbors (KNN) Algorithm in Machine Learning?
KNN is a supervised machine learning technique and algorithm for classification and regression. This post is the ultimate guide to KNN.



