RoBERTa: оптимизированный метод предобучения самоконтролируемых NLP-систем
Предварительно обученные языковые модели добились впечатляющего успеха в обработке естественного языка (NLP), что привело к смене парадигмы от обучения с учителем к предварительному обучению с последующей тонкой настройкой. Цель языкового моделирования — предсказать следующий токен в последовательности, учитывая историю неразмеченных текстов, то есть большие объемы необработанных текстовых данных, которые не были помечены конкретной информацией. BERT (Bidirectional Encoder Representations from Transformers) устанавливает новые стандарты для этой концепции, обеспечивая двунаправленное понимание языка, поскольку он рассматривает всё предложение целиком, а не только одно слово за раз. Он учитывает слова до и после, чтобы лучше понять их значение.
Однако основной проблемой, обнаруженной у BERT, было его недостаточное обучение, что ограничивало его производительность в задачах NLP. Это ограничение побудило исследователей изучить улучшенные методологии обучения в последующих моделях, таких как RoBERTa.
RoBERTa (A Robustly Optimized BERT Pretraining Approach) — это улучшенная версия BERT, разработанная для устранения его ограничений. RoBERTa представила несколько ключевых улучшений, которые повышают ее производительность в различных задачах NLP.
В этой статье будут рассмотрены методологии и технологии, использованные при разработке RoBERTa, включая ее подход к обучению, достигнутые результаты и потенциальные возможности для будущих исследований, которые она открывает.
Краткое введение в BERT (Bidirectional Encoder Representations from Transformers)
Чтобы понять RoBERTa, важно понять ее предшественника, BERT, и проблемы, с которыми он столкнулся. BERT представил концепцию двунаправленных трансформеров, позволяя моделям глубокого обучения понимать контекст способом, ранее недостижимым.
Но, чтобы действительно понять, как работает BERT, нам нужно разобрать его по частям. Итак, давайте подробнее рассмотрим его архитектуру и то, как он обучался.
Архитектура BERT и процесс предварительного обучения
Архитектура BERT основана на трансформерах, представленных Devlin et al. in 2018. Она использует многослойный двунаправленный (слева направо и справа налево) энкодер для взвешивания важности разных слов в предложении.
Архитектура BERT
Рисунок 1: Архитектура BERT
Слово начинается со своего представления эмбеддинга из слоя эмбеддингов; эмбеддинг — это плотный вектор (числовое представление) слова или токена в многомерном пространстве. Слой эмбеддингов — это первый слой в нейронной сети, который преобразует входные слова в эти плотные векторы. Каждый слой выполняет вычисления multi-headed attention над представлением слова из предыдущего слоя, чтобы сгенерировать новое промежуточное представление. Все эти промежуточные представления имеют одинаковый размер. На рисунке выше E1 — это представление эмбеддинга, T1 — итоговый выход, а Trm — промежуточное представление токена.
Процесс предварительного обучения BERT включает две основные задачи:
Masked Language Modeling (MLM)
Next-Sentence Prediction (NSP)
Языковое моделирование предсказывает следующее слово по заданной последовательности слов. Однако в задаче MLM вместо предсказания каждого следующего токена случайным образом маскируется процент входных токенов, и предсказываются только эти замаскированные токены. Задача NSP, с другой стороны, является задачей бинарной классификации, которая предсказывает, следуют ли два заданных предложения друг за другом в исходном тексте. Такой подход помогает модели понимать отношения между предложениями.
Next Sentence Prediction
Рисунок 2: Next Sentence Prediction
Процесс предварительного обучения BERT имел ограничения, которые не позволяли ему полностью раскрыть свой потенциал. Одной из основных проблем было использование статического шаблона маскирования в задаче MLM. В BERT после того как слово было замаскировано во время обучения, одни и те же слова маскировались во всех итерациях. Этот статический подход ограничивал модель разнообразными сценариями маскирования, снижая ее способность к обобщению. Кроме того, размер обучающих данных и продолжительность обучения также были ограничены.
Эти ограничения приводили к нестабильности производительности BERT в задачах, специфичных для предметной области, таких как анализ юридических или медицинских текстов, а также в сложных сценариях понимания языка, например анализе тональности или многошаговом рассуждении. Устранение этих недостатков требует дальнейших исследований и разработок.
Появление RoBERTa
Основной мотивацией разработки RoBERTa было решение проблем, наблюдавшихся в процессе предварительного обучения BERT. Однако RoBERTa сохраняет ту же базовую архитектуру, что и Bert Large, которая состоит из 24 слоев, 1024 скрытых блоков и 16 голов внимания, всего 355 миллионов параметров.
Проблемы, которые RoBERTa стремилась решить, были следующими:
Статический шаблон маскирования: Статическое маскирование BERT приводило к ограниченным сценариям обучения, вызывая переобучение. Переобучение происходит, когда модель очень хорошо работает на обучающих данных, но плохо работает с тестовыми данными (новыми данными). RoBERTa ввела динамическое маскирование, создавая новые маски для каждой эпохи и улучшая свою способность работать с новыми данными.
Недостаточный объем обучающих данных: Обучение BERT основывалось на наборе данных примерно из 16 ГБ текста, чего недостаточно для охвата всего разнообразия языка. RoBERTa увеличила объем обучающих данных, используя более 160 ГБ текста из различных источников.
Короткая продолжительность обучения: Исходная модель BERT обучалась в течение относительно короткого времени, но RoBERTa значительно увеличила продолжительность обучения, выполняя больше эпох и итераций.
Малые размеры батчей и консервативные скорости обучения: Предварительное обучение BERT использовало относительно малые размеры батчей и консервативные скорости обучения, что было безопасным, но ограничивающим подходом. С другой стороны, RoBERTa экспериментировала с большими размерами батчей и более агрессивными скоростями обучения, что привело к лучшей производительности модели.
Что такое RoBERTa и как она работает?
RoBERTa (A Robustly Optimized BERT Pretraining Approach) — это улучшенная версия BERT, разработанная для устранения его ограничений и повышения производительности. Она внесла изменения в процесс обучения BERT, которые улучшают его производительность в задачах обработки естественного языка.
Эти изменения включают:
Динамическое маскирование
Удаление NSP
Увеличение объема обучающих данных и продолжительности обучения
Увеличение размеров батчей
Байтовое кодирование текста
Динамическое маскирование
Из архитектуры BERT мы помним, что во время предварительного обучения BERT выполнял Masked Language Modeling (MLM), пытаясь предсказать определенный процент замаскированных токенов. Эти выбранные замаскированные токены были одинаковыми (статическими) в каждой итерации.
RoBERTa решила эту проблему, реализовав немного более совершенный подход под названием динамическое маскирование. Этот подход изменяет схему маскирования каждый раз, когда последовательность передается в BERT во время обучения. Это изменение сделало обучающие данные более разнообразными, позволяя модели изучать более широкий спектр языковых паттернов. В результате RoBERTa получила более глубокое понимание контекста, что улучшило производительность в последующих задачах.
Статическое маскирование и динамическое маскирование
Рисунок 3: Статическое маскирование и динамическое маскирование
Исследователи, разработавшие RoBERT, также повторно реализовали подход статического маскирования, продублировав обучающие данные 10 раз. Это дублирование позволило маскировать каждую последовательность десятью различными способами на протяжении 40 эпох обучения. Таким образом, каждая обучающая последовательность встречалась с одной и той же маской четыре раза во время обучения. Производительность была схожей при сравнении повторной реализации статического маскирования с исходной моделью BERT. Однако динамическое маскирование показывает немного лучшую производительность, чем статическое маскирование.
Сравнение статического и динамического маскирования
Рисунок 4: Сравнение статического и динамического маскирования
Удаление предсказания следующего предложения (NSP)
Еще одной ключевой модификацией в RoBERTa стало удаление задачи NSP. В NSP модели давались пары предложений, и она должна была предсказать, следует ли второе предложение за первым в исходном тексте. Однако в ходе разработки RoBERTa было обнаружено, что задача NSP вносила минимальный вклад в производительность модели в последующих задачах.
RoBERTa использует подход FULL-SENTENCES (упаковка последовательностей из нескольких документов). Каждый вход модели упаковывается полными предложениями, выбранными непрерывно из одного или нескольких документов до максимальной длины последовательности в 512 токенов. Это позволяет модели более эффективно изучать дальние зависимости.
BERT с NSP и без NSP
Рисунок 5: BERT с NSP и без NSP
Кроме того, исследователи рассмотрели четыре разных способа форматирования входных данных для языковой модели. Они сравнили два основных формата: исходный SEGMENT-PAIR и SENTENCE-PAIR. Оба формата используют NSP, но формат SENTENCE-PAIR использует отдельные предложения вместо пар. Исследователи обнаружили, что использование отдельных предложений ухудшало производительность модели в задачах, потому что ей было трудно понимать связи между словами, находящимися далеко друг от друга в тексте.
Затем они протестировали модель, обучая ее без метода NSP и используя блоки текста из документа, называемые DOC-SENTENCES. В большинстве случаев они обнаружили, что она работает лучше, чем исходный BERT, а отказ от потерь NSP не ухудшал производительность модели.
Метод текста из одного документа (DOC-SENTENCES) был немного лучше, чем метод из нескольких документов (FULL-SENTENCES). Однако, поскольку DOC-SENTENCES приводил к различным размерам батчей во время обучения, они решили использовать FULL-SENTENCES для остальных экспериментов. Этот выбор упростил сравнение их результатов с результатами других связанных исследований.
Результаты для базовых моделей, предварительно обученных на BOOK CORPUS и WIKIPEDIA
Рисунок 6: Результаты для базовых моделей, предварительно обученных на BOOK CORPUS и WIKIPEDIA
Более крупные обучающие данные и увеличенная продолжительность
Пожалуй, самая простая оптимизация, но не менее важная, — это просто обучение на большем объеме данных в течение более длительного времени. BERT был обучен на наборе данных объемом примерно 16 ГБ текста, а RoBERTa использовала более 160 ГБ текста.
Наборы данных RoBERTa:
BOOK-CORPUS и WIKIPEDIA: То же, что и BERT.
CC-NEWS: RoBERTa представляет новый набор данных под названием CC-NEWS, крупномасштабный новостной набор данных, содержащий современный язык и широкий спектр тем, стилей и точек зрения.
Дополнительные наборы данных: RoBERTa объединяет вышеуказанные наборы данных с тремя другими частными наборами данных, описанными в статье, улучшая производительность в последующих задачах.
Используя больший объем обучающих данных, увеличивая продолжительность обучения и выполняя больше эпох и итераций, RoBERTa показывает значительное улучшение на 4–6% в последующих задачах по сравнению с первоначально опубликованными результатами BERT (Devlin et al. in 2018).
Результаты RoBERTa по сравнению с BERT
Рисунок 7: Результаты RoBERTa по сравнению с BERT
Увеличение размеров батчей
Предыдущие работы в области нейронного машинного перевода показали, что обучение с очень большими мини-батчами может улучшить перплексию для моделирования языка с маскированием. Этот подход улучшает производительность в конечных задачах, когда скорость обучения увеличивается соответствующим образом (Ott et al., 2018). Перплексия — это метрика, используемая для измерения производительности языковых моделей. Она количественно оценивает неопределенность (распределение вероятностей), которую модель имеет при предсказании следующего слова в последовательности. Например, чем ниже перплексия, тем точнее предсказания.
Основываясь на этой концепции, RoBERTa использует гораздо более крупные мини-батчи во время обучения. В то время как BERT использовал размер батча 256 последовательностей на миллион шагов, RoBERTa увеличила его до 8 тыс. последовательностей на 31 тыс. шагов со значением скорости обучения 1e-3. Однако оптимальная производительность наблюдалась при 2 тыс. последовательностей на 125 тыс. шагов.
Сравнение перплексии и производительности в конечных задачах BERT и RoBERTa
Рисунок 8: Сравнение перплексии и производительности в конечных задачах BERT и RoBERTa
Байтовое кодирование текста
RoBERTa также представила альтернативный метод обработки слов вне словаря (OOV), используя Byte Pair Encoding (BPE) на уровне байтов. BERT использовал словарь Byte-Pair Encoding (BPE) на уровне символов из 30 тыс. единиц. RoBERTa расширяет его до словаря BPE на уровне байтов из 50 тыс. подсловных единиц без дополнительной предварительной обработки входных данных или токенизации. По сравнению с BERT, этот метод позволил RoBERTa кодировать почти любое слово или подслово без использования неизвестного токена.
Байтовое кодирование текста
Рисунок 9: Байтовое кодирование текста
Результаты экспериментов
После модификации BERT(Devlin et al. 2019), RoBERTa была протестирована на бенчмарках NLP. Мы обсудим ее производительность на трех бенчмарках: GLUE, SQuAD, и RACE.
GLUE (General Language Understanding Evaluation): Коллекция из 9 наборов данных для задач NLU (понимание естественного языка).
SQuAD (Stanford Question Answering Dataset): Набор данных, предназначенный для обучения и оценки систем вопросно-ответного взаимодействия. Он состоит из реальных вопросов, заданных людьми по набору статей Wikipedia, где ответ на каждый вопрос представляет собой конкретный фрагмент текста в соответствующей статье.
RACE (Reading Comprehension from Examinations): Крупномасштабный набор данных для проверки понимания прочитанного, собранный из экзаменов по английскому языку.
Результаты тестирования на наборе данных GLUE
RoBERTa тестировалась с использованием двух настроек дообучения. В первой настройке (single-task) RoBERTa отдельно дообучалась в течение 10 эпох для каждой задачи GLUE , используя только обучающие данные для соответствующей задачи. Она достигла результатов уровня state-of-the-art на всех девяти задачах GLUE, превзойдя как BERT, так и XLNet. Во второй настройке (ensembles) RoBERTa набрала 88.5 в таблице лидеров GLUE, сравнявшись с предыдущим уровнем state-of-the-art, установленным XLNet. RoBERTa установила новые результаты state-of-the-art на 4 из 9 задач GLUE: MNLI, QNLI, RTE и STS-B.
Результаты на GLUE
Рисунок 10: Результаты на GLUE
SQuAD
RoBERTa была дообучена с использованием обучающих данных SQuAD. На SQuAD v1.1 RoBERTa соответствует уровню state-of-the-art, установленному XLNet. На SQuAD v2.0 RoBERTa достигла F1-оценки 89.4, установив новый уровень state-of-the-art для одиночных моделей без аугментации данных. Это особенно впечатляет, учитывая, что RoBERTa не использует никаких специфичных для SQuAD техник и дообучается только на данных SQuAD.
Результаты на SQuAD
Рисунок 11: Результаты на SQuAD
Результаты тестирования на наборе данных RACE
RACE — это сложный бенчмарк понимания прочитанного, требующий от моделей отвечать на вопросы с несколькими вариантами ответов на основе отрывков из экзаменов по английскому языку. Этот бенчмарк особенно сложен, поскольку требует от моделей понимания сложных отрывков и вывода правильных ответов на основе контекста. RoBERTa достигла точности 83.2% на бенчмарке RACE и установила новые стандарты state-of-the-art.
Результаты на тестовом наборе RACE
Рисунок 12: Результаты на тестовом наборе RACE
Дообучение RoBERTa для анализа тональности
Помимо своей производительности на стандартных бенчмарках, RoBERTa также доказала высокую эффективность при дообучении для конкретных задач, таких как анализ тональности. Дообучение — это использование предварительно обученной модели и ее адаптация к конкретной задаче путем обучения на меньшем, специфичном для задачи наборе данных. Исходный код, использованный в этой статье, взят из Hugging Face.
Импорт и подготовка набора данных
Мы будем использовать набор данных, доступный на Kaggle Competition, и будем ссылаться только на первый csv-файл из выгрузки данных: train.tsv.
Импорт библиотек Python:
!pip install transformers==3.0.2
Импортируйте библиотеки и модули, необходимые для запуска нашего скрипта на этом этапе.
# 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'
Подготовка набора данных
Сначала загрузите набор данных и прочитайте его с помощью пакета Pandas.
train = pd.read_csv('train.tsv', delimiter='\t')
new_df = train[['Phrase', 'Sentiment']]
Давайте определим некоторые переменные:
MAX_LEN: Максимальная длина входного текста (256).
TRAIN_BATCH_SIZE and VALID_BATCH_SIZE: Размеры батчей для обучения и валидации (8 и 4 соответственно).
LEARNING_RATE: Скорость обучения для модели (1e-05).
Tokenizer: Экземпляр RobertaTokenizer используется для предварительной обработки текстовых данных.
Класс SentimentData реализует пользовательский класс набора данных, принимая на вход фрейм данных, токенизатор и максимальную длину. Он предварительно обрабатывает текстовые данные, возвращая словарь, содержащий идентификаторы входных данных, маски внимания, идентификаторы типов токенов и целевые метки тональности.
Класс DataLoader создает загрузчики данных для обучающего и тестового наборов, выполняя итерацию по данным батчами во время обучения и валидации.
# 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)
Создание нейронной сети для дообучения
Мы создадим нейронную сеть с RobertaClass.
Эта сеть будет содержать языковую модель Roberta, за которой следует dropout и, наконец, линейный слой для получения итоговых выходных данных.
Данные будут передаваться в языковую модель Roberta так, как определено в наборе данных.
Выходные данные финального слоя будут сравниваться с категорией тональности, чтобы определить точность предсказания модели.
Мы инициируем экземпляр сети под названием Model. Этот экземпляр будет использоваться для обучения.
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)
Тонкая настройка модели
После всех усилий по загрузке и подготовке набора данных и созданию модели это, вероятно, более простой этап процесса.
Здесь мы определяем функцию обучения, которая обучает модель в течение заданного количества эпох на указанном выше обучающем наборе данных. Эпоха определяет, как часто полный набор данных будет пропущен через сеть.
# 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)
Вывод:
Рисунок 13 — сведения об обучении модели
Проверка производительности модели
На этапе проверки мы передаем модели невиданные данные (тестовый набор данных). Этот этап определяет, насколько хорошо модель работает с невиданными данными, которые составляют 20% от train.tsv и были отделены на этапе создания набора данных.
Этап проверки оценивает способность модели к обобщению на новых, невиданных данных. Веса модели не обновлялись. Только итоговый вывод сравнивается с фактическим значением, которое затем используется для расчета точности модели.
Функция valid реализует этап проверки, принимая модель и testing loader в качестве входных данных. Она переводит модель в режим оценки, инициализирует переменные для отслеживания правильных и неправильных предсказаний и выполняет итерацию по testing loader. Для каждого батча она вычисляет потери и точность, выводя потери и точность проверки каждые 5000 шагов и в конце эпохи. Наконец, она возвращает точность эпохи.
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)
Вывод:
Рисунок 14 — Подробности проверки модели
Как видите, модель предсказывает правильную категорию заданного образца с точностью 69,47%, которую можно дополнительно улучшить, увеличив объем обучения.
Возможности для будущих исследований
Успех RoBERTa открыл новые возможности для исследований в области NLP и оптимизации моделей. Вот некоторые потенциальные направления исследований:
Масштабирование наборов данных
Более крупные наборы данных и более длительное время обучения улучшили RoBERTa. Будущие исследования могли бы изучить динамическое масштабирование наборов данных, при котором модели со временем обучаются на постепенно увеличивающихся наборах данных. Такой подход мог бы помочь нам понять, как модель обучается на новых данных и может ли она продолжать улучшаться по мере масштабирования данных.
Многозадачная донастройка
Производительность RoBERTa можно было бы дополнительно улучшить, исследуя продвинутые процедуры многозадачной донастройки. Сейчас она хорошо справляется со множеством задач, не обучаясь сразу на нескольких задачах одновременно. Однако исследователи могут изучить, как интеграция нескольких задач на этапе донастройки может повысить производительность на разных бенчмарках.
Исследование целей предварительного обучения
Удаление цели NSP и использование в RoBERTa динамического маскирования вместо статического вызывают вопросы о том, существуют ли еще более эффективные способы обучения языковых моделей. Будущие исследования могут изучить различные методы предварительного обучения, которые влияют на то, насколько хорошо RoBERTa понимает и выполняет задачи.
Заключение
Статья о RoBERTa вносит несколько важных вкладов в область NLP. Авторы обнаружили, что динамическое изменение шаблона маскирования в обучающих данных, обучение на более длинных последовательностях и удаление задачи NSP могут улучшить производительность в последующих задачах.
Кроме того, использование большего размера батча и обучающего набора данных также способствует этому улучшению. RoBERTa достигает результатов уровня state-of-the-art на GLUE, RACE и SQuAD без многозадачной донастройки для GLUE или дополнительных данных для SQuAD.
Кроме того, спор между RoBERTa и BERT заключается не только в том, какая модель лучше. Он касается понимания компромиссов между вычислительными ресурсами, производительностью модели и этическими последствиями развертывания этих моделей. Улучшения RoBERTa по сравнению с BERT показывают, что область NLP далека от статичности и открывает путь к более продвинутым и сложным возможностям обработки языка.
Дополнительные ресурсы
Читать далее

Introducing Loon: A New Storage Engine for Vector Data That Never Stops Changing
Loon is a new storage engine for Milvus 3.0 and Zilliz Vector Lakebase, built to manage evolving vector datasets with ColumnGroups, row ID alignment, and Manifests.

Zilliz Cloud Launches in AWS Australia, Expanding Global Reach to Australia and Neighboring Markets
We're thrilled to announce that Zilliz Cloud is now available in the AWS Sydney, Australia region (ap-southeast-2).

Announcing the General Availability of Zilliz Cloud BYOC on Google Cloud Platform
Zilliz Cloud BYOC on GCP offers enterprise vector search with full data sovereignty and seamless integration.



