Создание текстов песен Beatles с помощью машинного обучения

Учебник высокого уровня по языковым моделям и OpenAI's GPT-2.

Битлз были огромным культурным явлением. Их вневременная музыка до сих пор находит отклик у людей, как молодых, так и старых. Лично я большой поклонник. По моему скромному мнению, это величайшая группа из когда-либо существовавших ». Их песни полны интересных текстов и глубоких идей. Возьмем, к примеру, эти полоски:

Когда вы заглянули за пределы себя
Тогда вас ждет душевный покой²

Мощная штука. Однако то, что делало Beatles великими, - это их универсальность. Некоторые из их песен глубокие и задумчивые, а другие веселые и беззаботные. Неудивительно, что главная тема их текстов - это любовь. Вот один из таких стихов:

Моя милая, малышка, разве ты не видишь,
как это прекрасно, когда ты мой.
Если бы я только мог быть твоим любовником навсегда,
Я никогда не смогу заполучить свое сердце, я могу Понимаю.

На самом деле, эти тексты написаны не кем-либо из Beatles, которых вы, возможно, знаете. Ни Леннона, ни Маккартни, ни Харрисона, ни даже, не дай бог, Ринго Старра (шучу, Ринго в порядке). На самом деле они были созданы с помощью модели машинного обучения, а именно OpenAI GPT-2 [1]. Хотя здесь используется их самая маленькая модель, результаты довольно удивительны.

Но прежде чем мы забегаем слишком далеко, давайте сделаем шаг назад и посмотрим, как все это работает. Как всегда, полный рабочий код доступен на моем Github.

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

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

На высоком уровне языковая модель пытается предсказать следующее слово по последовательности предыдущих. Например, хорошая языковая модель может предсказать, что «молоко» является логическим завершением фразы «купить галлон ____».

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

где w_i - слова из нашего словаря.

Поскольку мы явно моделируем это распределение, мы можем делать с ним некоторые интересные вещи, например использовать его для генерации слов, которых мы раньше не видели. Мы можем это сделать, многократно выбирая следующее слово из этого распределения, затем используя это как условное выражение, когда мы выбираем следующее-следующее слово, и так далее. Чтобы конкретизировать, давайте посмотрим, как это может выглядеть в Python. Если бы у нас был объект model с методом sample, то мы можем сгенерировать новые образцы, выполнив что-то вроде этого:

Конечно, я пропускаю некоторые детали, но, надеюсь, они станут яснее по мере продолжения. А пока давайте рассмотрим простейшую языковую модель в мире - униграмму.

Модель униграммы игнорирует любые условные обозначения и просто случайным образом выбирает следующее слово из обучающих данных. Все это сводится к тому, что наши тренировочные данные загружаются в блендер и выливаются содержимое после 10-минутного смешивания на высоком уровне. Само собой разумеется, что мы не собираемся генерировать ничего похожего на английский (если, конечно, у нас не было триллиона обезьян с триллионом блендеров, или это были пишущие машинки).

Модель Биграммы

На ступеньку выше униграммы находится модель биграмм. Как вы могли догадаться по названию, модель биграмм изучает распределение, которое обусловлено только предыдущим словом, т. Е.

Модель биграмм настолько проста, что ее легко реализовать в Python, и она даст нам более глубокое понимание того, как работают языковые модели.

Сбор данных

Прежде чем мы перейдем к реализации, нам сначала понадобятся некоторые данные. Наша конечная цель - создавать песни, которыми The Beatles гордились бы, поэтому давайте начнем с сбора всех известных текстов.

Я нашел этот сайт, где собраны тексты всех песен, которые они когда-либо выпускали. У него также есть полезная индексная страница со ссылками на отдельные песни, которые мы можем использовать для очистки сайта. Я написал простой сценарий, чтобы перебирать каждую ссылку на странице, анализировать ее HTML-код для извлечения текста и выгружать текст в файл, по одной песне в строке. Если вы планируете следовать за вами или просто хотите сами тексты песен Beatles, я настоятельно рекомендую использовать его, поскольку очистка HTML-кода довольно утомительна и раздражает даже с такими инструментами, как Beautiful Soup.

Когда у нас есть данные в красивом, чистом формате, все остальное легко. Но не верьте мне на слово, возьмите это из этой диаграммы:

Построение модели

Как упоминалось выше, модель биграмм просто выбирает следующее слово, обусловленное предыдущим. Один простой способ сделать это - отслеживать, какие слова следуют за текущим и с какой частотой. То есть мы ведем словарь для каждого слова current_word в наших обучающих данных, а затем каждый раз, когда видим next_word, мы обновляем current_word[next_word] += 1. Затем, чтобы генерировать слова, мы просто просматриваем все слова и их количество в current_word словаре и выбираем слово с вероятностью, пропорциональной его количеству. Вот набросок³ того, как будет выглядеть полная модель в Python:

И последнее, что следует отметить, это то, что мы, вероятно, хотим предварительно обработать текст, добавив некоторые специальные токены для обозначения начала / конца строк и песен. Это сделано для того, чтобы наша модель сохраняла некоторую структуру песни при создании новых текстов, иначе модель будет просто выплевывать большие кляксы текста без конца. В моем коде я использую XXSL, XXEL, XXSS, и XXES для обозначения начальной строки, конечной строки, начальной песни и конечной песни соответственно.

Наконец, чтобы сгенерировать песни, мы можем начать с токена XXSS и продолжать вызывать model.predict(), пока не достигнем токена XXES.

Теоретически, как только цикл остановится, мы создадим никогда ранее не публиковавшуюся песню Beatle. Но хорошо ли это?

Никогда прежде не публиковавшаяся песня Beatles

Вот небольшой фрагмент одной из песен, которые генерирует модель биграмм:

Она такая, что я люблю ее сердце.
Ну, они есть; они сказали, что меня так много,
Она не удивляет
Когда ты моя
Грустная и Амстердамский Хилтон
они пробираются,
Да, я жду мальчик родился у богатого человека,
все делят

Сгенерированные сэмплы звучат как бред сумасшедшего и имеют смысл только в том случае, если нам очень повезет.

Мы можем продолжить расширять модель биграмм, чтобы учесть предыдущие два слова. Это известно как модель триграммы. Вы можете обнаружить, что модель триграммы на самом деле создает более звучащие тексты. Это связано с тем, что здесь меньше трех словосочетаний, поэтому у модели меньше вариантов на каждом этапе, а на некоторых этапах есть только один вариант. В общем, мы можем создать произвольную модель n-граммов, рассматривая предыдущие n слов. Когда n равно длине полной песни, вы можете обнаружить, что модель идеально подходит для создания песен Beatles. К сожалению, песни, которые он генерирует, уже существуют.

К лучшей модели

Одна из наиболее вопиющих проблем модели биграмм заключается в том, что она будет использовать только слова и фразы, которые она видела в обучающих данных. Хотя мы хотим создавать тексты, которые звучат так, как будто они были написаны Beatles, мы не хотим ограничивать себя только теми словами, которые они использовали. Например, если Битлз никогда не использовали слово парад, то модель биграмм не будет генерировать песни о парадах. Конечно, поскольку мы тренируемся только на лирике Битлз, мы не можем ожидать, что наша модель будет использовать слова, которых она никогда не видела. Что нам нужно, так это тренироваться на огромных корпусах, таких как Википедия или Reddit.

Однако даже если бы мы изучили всю Википедию и увидели каждое слово на английском языке, наша модель биграмм все равно была бы слишком жесткой. Например, возьмите фразу «высокий мужчина». Каждый, кто хоть немного владеет английским языком, поймет, что «высокий» - это просто модификатор слова «мужчина» и не привязан к нему. Вместо этого «высокий» можно использовать для модификации бесчисленного множества других вещей, таких как «женщина», «мальчик», «здание», «жираф» и т. Д. Наша модель биграммы, однако, не может этому научиться и вместо этого должна видеть какое-либо применение «высокий» хотя бы один раз, прежде чем он сможет его использовать. Так что, если модель когда-либо видела только «высокого мужчину», «высокого мальчика», «высокую женщину», но не «высокую девушку», то в ее понимании фразы «высокая девушка» даже не существует.

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

Модель GPT-2

Модель OpenAI GPT-2 [1] недавно попала в заголовки как «слишком опасна для выпуска». Модель сгенерировала настолько убедительный текст, что авторы посчитали, что она может быть использована в злонамеренных целях ». Вместо этого они выпустили две уменьшенные версии, чтобы люди могли поиграть и поэкспериментировать. Мы будем использовать наименьший из двух для написания текстов наших песен Beatles.

GPT-2 - это модель на основе трансформатора, которая была обучена на огромных объемах данных Reddit за сотни часов работы графического процессора. Во время обучения он смог выучить очень хорошую модель английского языка (или, по крайней мере, ту версию английского языка, которая использовалась на Reddit). Это означает, что он способен понимать, что понятие высокий применимо к людям, зданиям или жирафам. Кроме того, поскольку он прошел обучение на огромной части Reddit, вполне вероятно, что он видел 99,9% слов и фраз на английском языке. Это отличная новость для нас, поскольку это именно то, что мы искали: обширный словарный запас и глубокое понимание того, как использовать этот словарный запас.

Однако, если бы мы включили модель и попросили ее сгенерировать что-нибудь, очень маловероятно, что в ней получится текст, напоминающий тексты Beatles (даже если r / beatles существует). Это потому, что модель не знает, что нас волнует, это создание текстов Beatles, в конце концов, это было не то, чему ее научили. Вместо этого нам нужно подтолкнуть модель к тому, чтобы она делала то, что мы хотим. Один из способов сделать это - трансферное обучение.

Трансферное обучение

Трансферное обучение - это идея, согласно которой мы можем использовать полученную информацию, выполняя одно действие, и применять ее для решения связанных задач. Например, когда вы начали читать эту статью, вам не нужно было заново учить, что такое слова, какие слова следуют за какими другими словами или как они сочетаются друг с другом, чтобы образовать предложения. Представьте, как это было бы утомительно. Вместо этого вы использовали все те часы, которые потратили на чтение книг AP Literature, чтобы понять, о чем я говорю сейчас (думаю, Huck Fin в конце концов пригодился).

Аналогичным образом мы можем использовать знания, которые GPT-2 уже усвоил за сотни часов чтения сообщений Reddit, и перенести их на нашу задачу по созданию текстов песен Beatles. Идея высокого уровня состоит в том, чтобы взять предварительно обученную модель и продолжить ее обучение еще немного. Однако вместо сообщений Reddit мы будем использовать отсканированные тексты песен Beatles только. Это сильно смещает модель в сторону создания песен, подобных Beatles.

Я пропущу, как именно это сделать, поскольку для объяснения всего потребуется еще один пост такой же длины. Вместо этого, если вас интересуют точные сведения, я отсылаю вас к [2]. Это отличное сообщение в блоге с пошаговыми инструкциями о том, как перенести модель GPT-2 на любую интересующую вас языковую задачу. Это также то, чем я следил, чтобы получить результаты, представленные здесь.

Новые Битлз

Как и все хорошие результаты глубокого обучения, тексты, которые я опубликовал во введении, были тщательно отобраны. Сгенерированные песни не так хороши, и их качество зависит от того, на каком этапе тонкой настройки вы находитесь. Вот что вы можете получить после точной настройки для ~ 100 мини-пакетов, когда модель все еще сильно не соответствует обучающим данным:

Я тебя люблю
Леннон и Маккартни
Я всегда буду
Ты меня любишь.
Ты меня любишь,
Ты тоже меня любишь.
Я всегда буду

И так продолжается еще 10–15 строк. По крайней мере, лучше, чем Lil’ Pump .

Шутя в сторону, мне очень интересны первые две строчки. В обучающих данных каждая песня начинается с названия в первой строке, автора (авторов) во второй и фактического текста в следующих строках. Даже на этой ранней стадии модели удалось изучить структуру наших данных: первая и вторая строки особенные; во второй строке есть только несколько возможных комбинаций слов, наиболее вероятными из которых являются Леннон и Маккартни.

Если мы настроим примерно 350 мини-партий, модель начнет генерировать гораздо более правдоподобные тексты, такие как текст во вступлении или этот:

Женщина в черном
Леннон и Маккартни
Я устрою сцену
Если ты не хочешь, чтобы я появлялся
Ты можешь оставить меня в покое.
Я Я близок к смерти, и я влюблен

Не идеально, но неплохо. Наконец, вот что произойдет, если мы будем продолжать тонкую настройку слишком долго (~ 2800 мин-пакетов):

Возвращайся (возвращайся)
Леннон и Маккартни
Желтая подводная лодка
Леннон и Маккартни
В субботу вечером, когда солнце светит на меня
Солнце уже вышло, Паруса чистые
Солнце уже, паруса чистые
Ооо - Эй

Модель начинает переобучаться, и сгенерированные образцы - это вещи, которые с большой вероятностью будут присутствовать в обучающих данных, такие как повторяющиеся строки «Леннон и Маккартни», «Желтая подводная лодка» и т. Д. Я обнаружил эту тонкую настройку для ~ 300– 500 шагов создали лучшие тексты.

Заключение

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

При этом еще так много предстоит изучить с моделью GPT-2. В образцах, которые я сгенерировал, использовались (вероятно) субоптимальные гиперпараметры по умолчанию. Было бы интересно посмотреть, насколько лучше могут быть сгенерированные тексты, если на точную настройку будет потрачено больше времени. Я также использовал только самые маленькие из выпущенных моделей, так как тренировался на своем ноутбуке. Я уверен, что более крупная модель даст еще более впечатляющие результаты. Наконец, OpenAI недавно выпустил MuseNet, способный генерировать довольно реалистично звучащую музыку. Насколько удивительно было бы соединить GPT-2 и MuseNet (по сути, это одна и та же модель) и создать и текст, и сопутствующую музыку? Если бы у меня было больше времени, денег или хоть какое-то представление о том, что я делаю, я бы с удовольствием сгенерировал полноценную песню с помощью машинного обучения, а затем попросил бы кого-нибудь с настоящим талантом исполнить ее.

Спасибо за прочтение!

Евгений Хотай,
30 июня 2019 г.

P.S. Если вам понравилась эта статья, подпишитесь на меня, чтобы получать уведомления о новых сообщениях! Как всегда, весь код и данные доступны на моем GitHub.

Сноски

¹ Хотя я думаю, что лучшим сольным музыкантом может стать еще одна легенда 60-х, Боб Дилан. Его сингл Like a Rolling Stone, возможно, лучшая песня из когда-либо написанных, и это не только мое мнение.

² Из Within You Without You моей любимой песни Beatles из моего любимого альбома Beatles. Это так странно, но так хорошо.

³ Для краткости я пропустил несколько мелких деталей. Все кровавые подробности вы можете найти на моем GitHub.

⁴ Некоторые люди считают, что это был просто грандиозный рекламный ход, но это ни к чему.

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

[1] А. Рэдфорд и др., Языковые модели - это многозадачные ученики без учителя (2019)

[2] С. Тодоров, Генерация фальшивых разговоров путем точной настройки OpenAI GPT-2 на данных из Facebook Messenger (2019)