RoBERTa : une méthode optimisée pour le préentraînement des systèmes de TAL auto-supervisés
Les modèles de langage préentraînés ont obtenu un succès remarquable en traitement du langage naturel (NLP), entraînant un changement de paradigme, de l’apprentissage supervisé vers le préentraînement suivi d’un affinage. L’objectif de la modélisation du langage est de prédire le prochain token dans une séquence, à partir d’un historique de textes non annotés, qui sont de grandes quantités de données textuelles brutes n’ayant pas été étiquetées avec des informations spécifiques. BERT (Bidirectional Encoder Representations from Transformers) établit de nouvelles références pour ce concept en permettant une compréhension bidirectionnelle du langage, car il examine la phrase entière, et pas seulement un mot à la fois. Il prend en compte les mots avant et après afin de mieux comprendre leur sens.
Cependant, le principal problème constaté avec BERT était son sous-entraînement, qui limitait ses performances sur les tâches de NLP. Cette limite a conduit les chercheurs à explorer des méthodologies d’entraînement améliorées dans des modèles ultérieurs, comme RoBERTa.
RoBERTa (A Robustly Optimized BERT Pretraining Approach) est une version améliorée de BERT conçue pour remédier à ses limites. RoBERTa a introduit plusieurs améliorations clés qui renforcent ses performances sur divers problèmes de NLP.
Cet article présentera les méthodologies et technologies utilisées dans le développement de RoBERTa, notamment son approche d’entraînement, les résultats qu’il a obtenus et les perspectives potentielles de recherche future qu’il ouvre.
Brève introduction à BERT (Bidirectional Encoder Representations from Transformers)
Pour comprendre RoBERTa, il est essentiel de comprendre son prédécesseur, BERT, et les défis auxquels il a été confronté. BERT a introduit le concept de transformers bidirectionnels, permettant aux modèles d’apprentissage profond de comprendre le contexte d’une manière auparavant inaccessible.
Mais, pour vraiment comprendre le fonctionnement de BERT, nous devons le décomposer. Examinons donc de plus près son architecture et la façon dont il a été entraîné.
Architecture de BERT et processus de préentraînement
L’architecture de BERT repose sur les transformers, introduits par Devlin et al. en 2018. Elle utilise un encodeur bidirectionnel multicouche (de gauche à droite et de droite à gauche) pour pondérer l’importance des différents mots dans une phrase.
Architecture de BERT
Figure 1 : Architecture de BERT
Un mot commence par sa représentation d’embedding issue de la couche d’embedding ; un embedding est un vecteur dense (représentation numérique) d’un mot ou d’un token dans un espace de grande dimension. La couche d’embedding est la première couche d’un réseau neuronal qui convertit les mots d’entrée en ces vecteurs denses. Chaque couche effectue des calculs d’attention multi-têtes sur la représentation des mots de la couche précédente afin de générer une nouvelle représentation intermédiaire. Toutes ces représentations intermédiaires sont de taille égale. Dans la figure ci-dessus, E1 est la représentation d’embedding, T1 est la sortie finale, et Trm est la représentation intermédiaire du token.
Le processus de préentraînement de BERT comprend deux tâches principales :
Modélisation du langage masqué (MLM)
Prédiction de la phrase suivante (NSP)
La modélisation du langage prédit le mot suivant à partir d’une séquence de mots. Dans la tâche MLM, toutefois, au lieu de prédire chaque token suivant, un pourcentage des tokens d’entrée est masqué aléatoirement, et seuls ces tokens masqués sont prédits. La tâche NSP, quant à elle, est une tâche de classification binaire qui prédit si deux phrases données se suivent dans le texte original. Cette approche aide le modèle à comprendre les relations entre les phrases.
Next Sentence Prediction
Figure 2 : Next Sentence Prediction
Le processus de pré-entraînement de BERT présentait des limites qui l’empêchaient d’atteindre son plein potentiel. L’un des principaux problèmes était l’utilisation d’un schéma de masquage statique dans la tâche MLM. Dans BERT, une fois qu’un mot était masqué pendant l’entraînement, les mêmes mots étaient masqués à toutes les itérations. Cette approche statique limitait le modèle à divers scénarios de masquage, réduisant sa capacité de généralisation. En outre, la taille des données d’entraînement et la durée de l’entraînement étaient également limitées.
Ces limites ont entraîné des incohérences dans les performances de BERT sur des tâches propres à un domaine, telles que l’analyse de textes juridiques ou médicaux, et dans des scénarios complexes de compréhension du langage, comme l’analyse des sentiments ou le raisonnement en plusieurs étapes. Remédier à ces lacunes nécessite davantage de recherche et de développement.
L’émergence de RoBERTa
La principale motivation derrière le développement de RoBERTa était de relever les défis observés dans le processus de pré-entraînement de BERT. Cependant, RoBERTa conserve la même architecture de base que Bert Large, qui se compose de 24 couches, 1024 unités cachées et 16 têtes d’attention, pour un total de 355 millions de paramètres.
Les défis que RoBERTa visait à relever étaient les suivants :
Schéma de masquage statique : Le masquage statique de BERT entraînait des scénarios d’entraînement limités, provoquant un surapprentissage. Le surapprentissage se produit lorsqu’un modèle fonctionne très bien sur les données d’entraînement, mais obtient de mauvais résultats avec les données de test (nouvelles données). RoBERTa a introduit le masquage dynamique, générant de nouveaux masques pour chaque époque et améliorant sa capacité à traiter de nouvelles données.
Données d’entraînement insuffisantes : L’entraînement de BERT reposait sur un jeu de données d’environ 16 Go de texte, ce qui est insuffisant pour capturer toute la diversité du langage. RoBERTa a augmenté l’échelle des données d’entraînement, en utilisant plus de 160 Go de texte provenant de diverses sources.
Durée d’entraînement courte : Le modèle BERT original a été entraîné pendant une durée relativement courte, mais RoBERTa a considérablement prolongé la durée d’entraînement, en exécutant davantage d’époques et d’itérations.
Petites tailles de lots et taux d’apprentissage conservateurs : Le pré-entraînement de BERT utilisait des tailles de lots relativement petites et des taux d’apprentissage conservateurs, ce qui était une approche sûre mais limitante. En revanche, RoBERTa a expérimenté avec des tailles de lots plus grandes et des taux d’apprentissage plus agressifs, ce qui a conduit à de meilleures performances du modèle.
Qu’est-ce que RoBERTa et comment fonctionne-t-il ?
RoBERTa (A Robustly Optimized BERT Pretraining Approach) est une version améliorée de BERT conçue pour remédier à ses limites et améliorer ses performances. Il a introduit des modifications au processus d’entraînement de BERT qui améliorent ses performances dans les tâches de traitement du langage naturel.
Ces modifications comprennent :
Masquage dynamique
Suppression du NSP
Données d’entraînement plus volumineuses et durée prolongée
Augmentation des tailles de lots
Encodage du texte en octets
Masquage dynamique
D’après l’architecture de BERT, nous nous souvenons que, pendant le pré-entraînement, BERT effectuait la modélisation du langage masqué (MLM) en essayant de prédire un certain pourcentage de tokens masqués. Ces tokens masqués choisis étaient les mêmes (statiques) à chaque itération.
RoBERTa a résolu ce problème en mettant en œuvre une approche légèrement meilleure appelée masquage dynamique. Cette approche modifie le schéma de masquage chaque fois qu’une séquence est transmise à BERT pendant l’entraînement. Ce changement a rendu les données d’entraînement plus variées, permettant au modèle d’apprendre un éventail plus large de schémas linguistiques. En conséquence, RoBERTa a développé une compréhension plus approfondie du contexte, ce qui a amélioré les performances sur les tâches en aval.
Masquage statique vs masquage dynamique
Figure 3 : Masquage statique vs masquage dynamique
Les chercheurs qui ont développé RoBERT ont également réimplémenté l’approche de masquage statique en dupliquant les données d’entraînement 10 fois. Cette duplication a permis à chaque séquence d’être masquée de dix manières différentes au cours des 40 époques d’entraînement. Ainsi, chaque séquence d’entraînement a été vue avec le même masque quatre fois pendant l’entraînement. Les performances étaient similaires lorsque l’on comparait la réimplémentation du masquage statique au modèle BERT original. Cependant, le masquage dynamique montre des performances légèrement meilleures que le masquage statique.
Comparaison entre masquage statique et dynamique
Figure 4 : Comparaison entre masquage statique et dynamique
Suppression de la prédiction de la phrase suivante (NSP)
Une autre modification clé dans RoBERTa a été la suppression de la tâche NSP. Dans NSP, le modèle recevait des paires de phrases et devait prédire si la deuxième phrase suivait la première dans le texte original. Cependant, le développement de RoBERTa a montré que la tâche NSP contribuait peu aux performances du modèle sur les tâches en aval.
RoBERTa utilise une approche FULL-SENTENCES (regroupement de séquences provenant de plusieurs documents). Chaque entrée du modèle est constituée de phrases complètes échantillonnées de manière contiguë à partir d’un ou de plusieurs documents, jusqu’à la longueur maximale de séquence de 512 tokens. Cela permet au modèle d’apprendre plus efficacement les dépendances à longue portée.
BERT avec et sans NSP
Figure 5 : BERT avec et sans NSP
De plus, les chercheurs ont examiné quatre façons différentes de formater les données d’entrée pour un modèle de langage. Ils ont comparé deux formats principaux : le SEGMENT-PAIR original et SENTENCE-PAIR. Les deux formats utilisent NSP, mais le format SENTENCE-PAIR utilise des phrases uniques au lieu de paires. Les chercheurs ont constaté que l’utilisation de phrases uniques dégradait les performances du modèle sur les tâches, car il avait du mal à comprendre les connexions entre des mots éloignés dans le texte.
Ensuite, ils ont testé le modèle en l’entraînant sans la méthode NSP et en utilisant des blocs de texte provenant d’un document appelé DOC-SENTENCES. Dans la plupart des cas, ils ont constaté qu’il faisait mieux que le BERT original, et que ne pas utiliser la perte NSP ne nuisait pas aux performances du modèle.
La méthode utilisant le texte d’un seul document (DOC-SENTENCES) était légèrement meilleure que celle utilisant plusieurs documents (FULL-SENTENCES). Cependant, comme DOC-SENTENCES entraînait des tailles de lots différentes pendant l’entraînement, ils ont décidé d’utiliser FULL-SENTENCES pour le reste de leurs expériences. Ce choix a facilité la comparaison de leurs résultats avec ceux d’autres études connexes.
Résultats pour les modèles de base pré-entraînés sur BOOK CORPUS et WIKIPEDIA
Figure 6 : Résultats pour les modèles de base pré-entraînés sur BOOK CORPUS et WIKIPEDIA
Données d’entraînement plus volumineuses et durée prolongée
L’optimisation la plus simple, peut-être, mais non moins importante, consiste simplement à s’entraîner sur davantage de données pendant plus longtemps. BERT a été entraîné sur un jeu de données d’environ 16 Go de texte, et RoBERTa a utilisé plus de 160 Go de texte.
Jeux de données RoBERTa :
BOOK-CORPUS et WIKIPEDIA : Identiques à BERT.
CC-NEWS : RoBERTa introduit un nouveau jeu de données appelé CC-NEWS, un jeu de données d’actualités à grande échelle présentant un langage contemporain ainsi qu’un large éventail de sujets, de styles et de perspectives.
Jeux de données supplémentaires : RoBERTa combine les jeux de données ci-dessus avec trois autres jeux de données privés décrits dans l’article, améliorant les performances sur les tâches en aval.
Grâce à des données d’entraînement plus volumineuses, à l’extension de la durée d’entraînement et à l’exécution sur davantage d’époques et d’itérations, RoBERTa montre une forte amélioration de 4 à 6 % sur les tâches en aval par rapport aux résultats initialement rapportés pour BERT (Devlin et al. en 2018).
Résultats de RoBERTa par rapport à BERT
Figure 7 : Résultats de RoBERTa par rapport à BERT
Augmentation des tailles de lots
Des travaux antérieurs en traduction automatique neuronale ont montré que l’entraînement avec de très grands mini-lots peut améliorer la perplexité pour la modélisation du langage masqué. Cette approche améliore les performances sur les tâches finales lorsque le taux d’apprentissage est augmenté de manière appropriée (Ott et al., 2018). La perplexité est une métrique utilisée pour mesurer les performances des modèles de langage. Elle quantifie l’incertitude (distribution de probabilité) qu’un modèle présente lorsqu’il prédit le mot suivant dans une séquence. Par exemple, plus la perplexité est faible, plus les prédictions sont précises.
Sur la base de ce concept, RoBERTa utilise des mini-lots beaucoup plus grands pendant l’entraînement. Alors que BERT utilisait une taille de lot de 256 séquences pendant un million d’étapes, RoBERTa l’a portée à 8k séquences pendant 31k étapes avec une valeur de taux d’apprentissage de 1e-3. Cependant, les performances optimales ont été observées avec 2k séquences pendant 125k étapes.
Comparaison de la perplexité et des performances sur les tâches finales de BERT vs. RoBERTa
Figure 8 : Comparaison de la perplexité et des performances sur les tâches finales de BERT vs. RoBERTa
Encodage du texte en octets
RoBERTa a également introduit une méthode alternative pour gérer les mots hors vocabulaire (OOV) en employant le Byte Pair Encoding (BPE) au niveau des octets. BERT utilisait un vocabulaire Byte-Pair Encoding (BPE) au niveau des caractères de 30K unités. RoBERTa étend cela à un vocabulaire BPE au niveau des octets de 50K unités de sous-mots sans prétraitement supplémentaire des entrées ni tokenisation. Par rapport à BERT, cette méthode a permis à RoBERTa d’encoder presque n’importe quel mot ou sous-mot sans utiliser le token inconnu.
Encodage du texte en octets
Figure 9 : Encodage du texte en octets
Résultats expérimentaux
Après avoir modifié BERT(Devlin et al. 2019), RoBERTa a été testé sur des benchmarks NLP. Nous examinerons ses performances sur trois benchmarks : GLUE, SQuAD, et RACE.
GLUE (General Language Understanding Evaluation) : Une collection de 9 jeux de données pour les tâches de NLU (compréhension du langage naturel).
SQuAD (Stanford Question Answering Dataset) : Un jeu de données conçu pour l’entraînement et l’évaluation de systèmes de question-réponse. Il se compose de questions réelles posées par des humains sur un ensemble d’articles de Wikipedia, où la réponse à chaque question est un segment de texte spécifique dans l’article correspondant.
RACE (Reading Comprehension from Examinations) : Un jeu de données de compréhension de lecture à grande échelle collecté à partir d’examens d’anglais.
Résultats des tests sur le jeu de données GLUE
RoBERTa a été testé à l’aide de deux configurations de fine-tuning. Dans la première configuration (tâche unique), RoBERTa a été fine-tuné séparément pendant 10 époques pour chaque tâche GLUE , en utilisant uniquement les données d’entraînement de la tâche correspondante. Il a obtenu des résultats de pointe sur les neuf tâches GLUE, surpassant à la fois BERT et XLNet. Dans la deuxième configuration (ensembles), RoBERTa a obtenu un score de 88.5 sur le classement GLUE, égalant le précédent état de l’art établi par XLNet. RoBERTa a établi de nouveaux résultats de pointe sur 4 des 9 tâches GLUE : MNLI, QNLI, RTE et STS-B.
Résultats sur GLUE
Figure 10 : Résultats sur GLUE
SQuAD
RoBERTa a été fine-tuné à l’aide des données d’entraînement SQuAD. Sur SQuAD v1.1, RoBERTa égale l’état de l’art établi par XLNet. Sur SQuAD v2.0, RoBERTa a atteint un score F1 de 89.4, établissant un nouvel état de l’art pour les modèles uniques sans augmentation de données. C’est particulièrement impressionnant étant donné que RoBERTa n’utilise aucune technique spécifique à SQuAD et n’est fine-tuné que sur les données SQuAD.
Résultats sur SQuAD
Figure 11 : Résultats sur SQuAD
Résultats des tests sur le jeu de données RACE
RACE est un benchmark exigeant de compréhension de lecture qui nécessite que les modèles répondent à des questions à choix multiple à partir de passages tirés d’examens d’anglais. Ce benchmark est particulièrement difficile parce qu’il exige des modèles qu’ils comprennent des passages complexes et infèrent les bonnes réponses à partir du contexte. RoBERTa a atteint une précision de 83.2% sur le benchmark RACE et a établi de nouvelles normes de pointe.
Résultats sur l’ensemble de test RACE
Figure 12 : Résultats sur l’ensemble de test RACE
Fine-tuning de RoBERTa pour l’analyse des sentiments
Au-delà de ses performances sur les benchmarks standard, RoBERTa s’est également révélé très efficace pour le fine-tuning de tâches spécifiques, telles que l’analyse des sentiments. Le fine-tuning consiste à prendre un modèle pré-entraîné et à l’adapter à une tâche spécifique en l’entraînant sur un jeu de données plus petit et spécifique à la tâche. Le code source utilisé dans cet article provient de Hugging Face.
Importation et préparation du jeu de données
Nous utiliserons le jeu de données disponible sur le concours Kaggle et nous référerons uniquement au premier fichier csv de l’export de données : train.tsv.
Importation des bibliothèques Python :
!pip install transformers==3.0.2
Importez les bibliothèques et modules nécessaires pour exécuter notre script à cette étape.
# 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'
Préparation du jeu de données
Tout d’abord, chargez le jeu de données et lisez-le à l’aide du package Pandas.
train = pd.read_csv('train.tsv', delimiter='\t')
new_df = train[['Phrase', 'Sentiment']]
Définissons quelques variables :
MAX_LEN : La longueur maximale du texte d’entrée (256).
TRAIN_BATCH_SIZE et VALID_BATCH_SIZE : Les tailles de batch pour l’entraînement et la validation (8 et 4, respectivement).
LEARNING_RATE: Le taux d’apprentissage du modèle (1e-05).
Tokenizer: Une instance de RobertaTokenizer est utilisée pour prétraiter les données textuelles.
La classe SentimentData implémente une classe de jeu de données personnalisée, prenant en entrée un data frame, un tokenizer et une longueur maximale. Elle prétraite les données textuelles, en renvoyant un dictionnaire contenant les ID d’entrée, les masques d’attention, les ID de type de token et les étiquettes de sentiment cibles.
La classe DataLoader crée des chargeurs de données pour les ensembles d’entraînement et de test, en parcourant les données par lots pendant l’entraînement et la validation.
# 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)
Création du réseau neuronal pour le fine-tuning
Nous allons créer un réseau neuronal avec RobertaClass.
Ce réseau comprendra le modèle de langage Roberta, suivi d’un dropout, puis enfin d’une couche linéaire pour obtenir les sorties finales.
Les données seront fournies au modèle de langage Roberta comme défini dans le jeu de données.
La sortie de la couche finale sera comparée à la catégorie de sentiment afin de déterminer l’exactitude de la prédiction du modèle.
Nous initialiserons une instance du réseau appelée Model. Cette instance sera utilisée pour l’entraînement.
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)
Ajustement fin du modèle
Après tous les efforts de chargement et de préparation de l’ensemble de données et de création du modèle. C’est probablement l’étape la plus facile du processus.
Ici, nous définissons une fonction d’entraînement qui entraîne le modèle pendant un nombre spécifié d’époques sur l’ensemble de données d’entraînement ci-dessus. Une époque définit la fréquence à laquelle les données complètes seront passées à travers le réseau.
# 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)
Sortie :
Figure 13- Détails de l’entraînement du modèle
Validation des performances du modèle
Pendant l’étape de validation, nous passons les données inédites (l’ensemble de données de test) au modèle. Cette étape détermine dans quelle mesure le modèle fonctionne sur les données inédites, qui représentent 20 % de train.tsv, séparées lors de l’étape de création de l’ensemble de données.
L’étape de validation vérifie la capacité de généralisation du modèle à de nouvelles données inédites. Les poids du modèle n’ont pas été mis à jour. Seule la sortie finale est comparée à la valeur réelle, qui est ensuite utilisée pour calculer la précision du modèle.
La fonction valid implémente l’étape de validation, en prenant le modèle et le chargeur de test comme entrées. Elle met le modèle en mode évaluation, initialise des variables pour suivre les prédictions correctes et incorrectes, puis itère sur le chargeur de test. Pour chaque lot, elle calcule la perte et la précision, en affichant la perte de validation et la précision toutes les 5000 étapes ainsi qu’à la fin de l’époque. Enfin, elle renvoie la précision de l’époque.
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)
Sortie :
Figure 14- Détails de la validation du modèle
Comme vous pouvez le voir, le modèle prédit la catégorie correcte d’un échantillon donné avec une précision de 69,47 %, qui peut être encore améliorée par davantage d’entraînement.
Opportunités de recherche futures
Le succès de RoBERTa a ouvert de nouvelles perspectives pour la recherche en NLP et l’optimisation des modèles. Voici quelques opportunités de recherche potentielles :
Mise à l’échelle des jeux de données
Des jeux de données plus volumineux et des temps d’entraînement plus longs ont amélioré RoBERTa. Les recherches futures pourraient étudier la mise à l’échelle dynamique des jeux de données, où les modèles sont entraînés sur des jeux de données progressivement plus grands au fil du temps. Cette approche pourrait nous aider à comprendre comment le modèle apprend à partir de nouvelles données et s’il peut continuer à s’améliorer à mesure que ses données augmentent.
Fine-tuning multitâche
Les performances de RoBERTa pourraient être encore améliorées en explorant des procédures avancées de fine-tuning multitâche. Pour l’instant, il est performant dans de nombreux domaines sans être entraîné sur plusieurs tâches à la fois. Cependant, les chercheurs pourraient étudier comment l’intégration de plusieurs tâches pendant la phase de fine-tuning pourrait améliorer les performances sur différents benchmarks.
Exploration des objectifs de pré-entraînement
La suppression de l’objectif NSP et l’utilisation d’une approche de masquage dynamique plutôt que d’un masquage statique dans RoBERTa soulèvent des questions quant à l’existence de moyens encore meilleurs d’enseigner aux modèles de langage. Les recherches futures peuvent explorer différentes méthodes de pré-entraînement qui influencent la capacité de RoBERTa à comprendre et à accomplir des tâches.
Conclusion
L’article sur RoBERTa apporte plusieurs contributions importantes au domaine du NLP. Les auteurs constatent que la modification dynamique du schéma de masquage dans les données d’entraînement, l’entraînement sur des séquences plus longues et la suppression de la tâche NSP peuvent améliorer les performances sur les tâches en aval.
De plus, l’utilisation d’une taille de lot plus grande et d’un jeu de données d’entraînement plus vaste contribue également à cette amélioration. RoBERTa obtient des résultats de pointe sur GLUE, RACE et SQuAD sans fine-tuning multitâche pour GLUE ni données supplémentaires pour SQuAD.
En outre, le débat entre RoBERTa et BERT ne porte pas seulement sur le modèle qui est le meilleur. Il s’agit de comprendre les compromis entre les ressources de calcul, les performances des modèles et les implications éthiques du déploiement de ces modèles. Les avancées de RoBERTa par rapport à BERT montrent que le domaine du NLP est loin d’être statique et ouvrent la voie à des capacités de traitement du langage plus avancées et plus complexes.
Ressources supplémentaires
L’article BERT : BERT : Pré-entraînement de Transformers bidirectionnels profonds pour la compréhension du langage
Les modèles d’IA les plus performants pour vos applications GenAI
Que sont les bases de données vectorielles et comment fonctionnent-elles ?
Qu’est-ce que le RAG (génération augmentée par récupération) ?
Continuer à lire

Migrating Self-Managed Milvus to Zilliz Cloud for >99% Latency Reduction
Step-by-step guide to migrating 50M vectors from self-managed Milvus to Zilliz Cloud using milvus-backup. Achieve >99% query latency reduction with zero data loss.

Zilliz Cloud Audit Logs Goes GA: Security, Compliance, and Transparency at Scale
Zilliz Cloud Audit Logs are now GA, giving enterprises real-time visibility, compliance-ready trails, and stronger security across AWS, GCP, and Azure.

The Great AI Agent Protocol Race: Function Calling vs. MCP vs. A2A
Compare Function Calling, MCP, and A2A protocols for AI agents. Learn which standard best fits your development needs and future-proof your applications.



