Мы анализируем влияние классификации настроений обзоров фильмов на основе языковой модели, обученной с нуля, или предварительно обученной модели с использованием корпуса wikitext-103.

Задний план

В различных классификационных работах с НЛП мы использовали ULMFiT. Мы можем найти две отличные статьи по этой методологии в Передаточном обучении в НЛП для классификации позиции твита и Тонкая настройка универсальной языковой модели для классификации текста - ULMFiT.

ULMFiT реализован в версии 1 библиотеки fastai¹, и они разработали некоторые методы, которые делают очень удобным переносное обучение.

В исходной статье ULMFiT состоит из трех этапов:

  • Обучение языковой модели на корпусе, который фиксирует высокоуровневые функции естественного языка с использованием набора данных общей предметной области.
  • Отрегулируйте и уточните языковую модель, созданную на первом этапе, и, используя трансферное обучение, создайте новый язык модели на целевом наборе данных.
  • Создайте и настройте классификатор с помощью изучения модельного языка, настроенного на втором этапе.

Основная цель этой статьи - измерить разницу и влияние между стартом на третьем этапе (классификатор), с предварительно обученной языковой модели (второй этап) или непосредственно с нуля.

Другими словами, модель второго этапа создается с трансфертным обучением и без него, сравнивая первоначальные результаты.

В первой части этой статьи мы собираемся импортировать набор данных и выполнить необходимые операции преобразования данных.

Затем мы измерим влияние использования языковой модели, которая получает переносное обучение от другой уже обученной модели, или создания языковой модели непосредственно из набора данных, и сравним оба результата.

Наконец, мы собираемся использовать лучшие языковые модели, созданные в предыдущем разделе, для разработки классификатора настроений в НЛП.

Набор данных

Набор данных для бинарной классификации настроений был подготовлен Эндрю Маас² и др. и содержит в общей сложности 100 000 обзоров на IMDB³. 25 000 из них отмечены как положительные и отрицательные для тренировок; еще 25000 помечены для тестирования.

Есть еще 50 000 дополнительных немаркированных данных, которые мы будем использовать для создания нашей модели изучения языка.

df = pd.read_csv(path/'texts.csv')
df.head()

Часть 1. Импорт набора данных и проектирования объектов

«Поскольку текст состоит из слов и не может напрямую применять к ним математические функции, мы сначала должны преобразовать их в числа. В fastai это делается в два разных этапа: токенизация и числовая обработка. В fastai API TextDataBunch делает это за нас *.

%reload_ext autoreload
%autoreload 2
%matplotlib inline
from fastai.text import *
path = untar_data(URLs.IMDB_SAMPLE)
data_lm = TextDataBunch.from_csv(path, 'texts.csv')

Токенизация

data = TextClasDataBunch.from_csv(path, 'texts.csv')
data.show_batch()

Оцифровка

Когда у нас есть токены из наших текстов, TextDataBunch преобразует их в целые числа, создавая список всех используемых слов. Максимальный размер словаря по умолчанию составляет 60 000 и заменяет те, которые не урезаны неизвестным токеном UNK.

Соответствие идентификаторов токенам хранится в атрибуте словаря, в словаре, называемом itos.

data.vocab.itos[:10]

Теперь, если мы посмотрим на наши наборы данных, мы увидим токенизированный текст как:

data.train_ds[0][0]

И если мы посмотрим al train_ds, все будут числа:

data.train_ds[0][0].data[:10]

Часть 2 - Создание языковой модели обучения

Языковое моделирование

«Языковая модель пытается изучить структуру естественного языка через иерархические представления и, таким образом, содержит как низкоуровневые функции (представления слов), так и высокоуровневые функции (семантическое значение). Ключевой особенностью языкового моделирования является то, что оно является генеративным, что означает, что оно нацелено на предсказание следующего слова с учетом предыдущей последовательности слов. Это возможно, потому что языковые модели обычно обучаются на очень больших наборах данных неконтролируемым образом, и, следовательно, модель может «изучать» синтаксические особенности языка гораздо глубже, чем встраивание слов.

В своем посте Себастьян Рудер очень элегантно показывает, почему языковое моделирование так эффективно для широкого круга задач НЛП. Языковые данные без меток получить относительно легко (они доступны бесплатно в виде больших текстовых корпусов), поэтому, снабдив языковую модель достаточно большим набором данных, теперь можно выполнять неконтролируемое предварительное обучение миллиардов слов при включении более глубокое знание синтаксиса языка ». ⁴

Мы будем использовать из API fastai, language_model_learner, который является типом учащегося ⁵, который принимает языковую модель из набора данных, принимая набор конфигураций.

Language_model_learner допускает свойство «предварительно обучено (Bool)», значение которого по умолчанию равно True, и предполагает, что модель является переносным обучением для каждого языка.

Создание нашей языковой модели обучения с нуля

Этот метод был использован для создания языковой модели для разных идиом, вот статья с отличным примером на вьетнамском языке⁶.

path = untar_data(URLs.IMDB)
data_lm = (TextList.from_folder(path)
.filter_by_folder(include=['train', 'test', 'unsup'])
.split_by_rand_pct(0.1)
.label_for_lm()
.databunch(bs=bs))
data_lm.save('data_lm.pkl')

«Мы должны использовать особый вид TextDataBunch для языковой модели, который игнорирует метки (поэтому мы ставим 0 везде), будет перемешивать тексты в каждую эпоху, прежде чем объединять их все вместе (только для обучения, мы не перемешиваем для набора проверки) и будут отправлять пакеты, которые читают этот текст по порядку с целями, которые являются следующим словом в предложении. * »

data_lm = load_data(path, 'data_lm.pkl', bs=bs)
data_lm.show_batch()

Здесь мы указываем API, что мы намерены «изучить» модель, чтобы не брать веса по умолчанию из предварительно обученного трансферного обучения, а начинать без предварительного обучения:

learn = language_model_learner(data_lm, AWD_LSTM, pretrained=False, drop_mult=0.3)

После корректировки скорости обучения и тренировки мы получаем точность 0,284114

Использование предварительно обученной модели для трансферного обучения

Модель, предварительно обученная на более крупном наборе данных, используемом в fastai, представляет собой очищенное подмножество Википедии под названием wikitext-103.

«Мы собираемся использовать это« знание »английского языка для создания нашего классификатора, но сначала, как и в случае с компьютерным зрением, нам нужно точно настроить предварительно обученную модель для нашего конкретного набора данных. Поскольку английский язык отзывов, оставленных людьми на IMDB, не совпадает с английским языком википедии, нам нужно будет немного скорректировать параметры нашей модели. Кроме того, могут быть некоторые слова, которые будут чрезвычайно распространены в наборе данных обзоров, но едва ли будут присутствовать в Википедии и, следовательно, могут не быть частью словаря, на котором обучалась модель. * ”

learn = language_model_learner(data_lm, AWD_LSTM, drop_mult=0.3)
learn.lr_find()
learn.recorder.plot(skip_end=15)

Подготовка модели к использованию в классификаторе

Для следующей части следует сохранить не только модель, но и ее кодировщик. Эта часть важна, потому что для повторного использования этой модели список слов и их идентификаторы должны быть одинаковыми.

learn.save_encoder('fine_tuned_enc')

Часть 3 - Фильм рассматривает классификатор настроений: взятие модели

path = untar_data(URLs.IMDB)
data_clas = (TextList.from_folder(path, vocab=data_lm.vocab)
.split_by_folder(valid='test')
.label_from_folder(classes=['neg', 'pos'])
.databunch(bs=bs))
data_clas.save('data_clas.pkl')
data_clas = load_data(path, 'data_clas.pkl', bs=bs)

Создаем классификатор и назначаем ему кодировщик предыдущего этапа.

learn = text_classifier_learner(data_clas, AWD_LSTM, drop_mult=0.5)
learn.load_encoder('fine_tuned_enc')

Результаты…

Слева - модель языка с нуля, справа - модель с трансферным обучением:

Наконец, после корректировки скорости обучения и некоторых дополнительных частей обучения мы получаем классификатор настроений по набору данных обзоров фильмов с точностью 0,943960.

Резюме

Мы экспериментировали с применением предварительно обученной языковой модели из предыдущего массива данных и языковой модели с нуля, получив лучшие результаты при использовании трансферного обучения.

Используя инструменты fastai и UMLFiT, мы можем применить это через корпус данных Википедии для предварительного обучения на любом языке, что в NLP является большим преимуществом из-за смещения инструментов и наборов данных на английском языке.

Наконец, помните, что важно держать кодировщик между языковой моделью и классификатором текста. В основе этого упражнения лежал токен из курса fastai, урок 3 и 4, где вы можете найти полный код и доступ к набору данных.

Я надеюсь, что статья была полезной, чтобы увидеть положительное влияние использования трансферного обучения в НЛП, аналогичного тому, которое используется в компьютерном зрении. Любые исправления, комментарии или идеи будут приветствоваться.

использованная литература

[1] https://course.fast.ai/

[2] http://ai.stanford.edu/~amaas/

[3] https://www.imdb.com/

[4] https://towardsdatascience.com/transfer-learning-in-nlp-for-tweet-stance-classification-8ab014da8dde

[5] https://docs.fast.ai/basic_train.html#Learner

[6] https://towardsdatascience.com/pre-trained-language-model-in-any-language-7531ea7217d4

[*] Многие концепции из этой статьи взяты непосредственно из уроков 3 и 4 курса fast.ai