Генерация классической музыки с помощью рекуррентной нейросети
В наше время обучаемые нейросети творят удивительные вещи, но эксперименты в этой области продолжают открывать нечто новое. Например, программист Даниэль Джонсон (Daniel Johnson) опубликовал результаты своих экспериментов по применению нейросетей для генерации классической музыки.
К сожалению, на GT нельзя встроить аудиофайл, поэтому приходится давать прямую ссылку, чтобы послушать один из результатов: http://hexahedria.com/files/nnet_music_2.mp3.
Как у него это получилось?
Даниэль Джонсон говорит, что основное внимание уделил такому свойству как инвариантность. Большинство существующих нейросетей для генерации музыки инвариантны по времени, но не инвариантны по нотам. Поэтому транспонирование всего на один шаг приведет к совершенно другому результату. Для большинства других применений такой подход хорошо работает, но не в музыке. Здесь хотелось бы достичь гармонии созвучий.
Даниэль нашел только один тип популярных нейросетей, где есть инвариантность по нескольким направлениям: это сверточные нейронные сети для распознавания изображений.
Автор адаптировал сверточную модель, добавив для каждого пикселя рекуррентную нейросеть с собственной памятью, и заменив пиксели на ноты. Таким образом, он получил систему, которая инвариантна и по времени, и по нотам.
Но в такой сети нет механизма получения гармоничных аккордов: на выходе каждая нота совершенно независима от других.
Чтобы добиться сочетания нот, Джонсон использовал модель типа RNN-RBM, где одна часть нейросети отвечает за время, а другая часть — за созвучные аккорды. Чтобы обойти ограничения RBM, он придумал внедрить две оси: для времени и для нот (и псевдоось для направления вычислений).
С помощью библиотеки Theano автор сгенерировал нейросеть по своей модели. Первый слой с осью по времени принимал на входе следующие параметры: позиция, высота звука, значение окружающих нот, предыдущий контекст, ритм. Затем срабатывали самогенерирующие блоки на основе кратко-долговременной памяти (LSTM): в одном рекуррентные соединения направлены по оси времени, в другом — по оси нот. После завершающего блока LSTM находится простой нерекуррентный слой для выдачи конечного результата, у него два значения на выходе: вероятность воспроизведения для конкретной ноты и вероятность артикуляции (то есть вероятность того, что нота будет сочетаться с другой).
Во время тренировки использовался случайным образом выбранный набор коротких музыкальных фрагментов из MIDI-коллекции Classical Piano Midi Page. Затем слегка поиграли с логарифмами, чтобы параметр кросс-энтропии на выдаче был хотя бы не слишком низким. Для гарантированной специализации слоев применили такой прием как dropout, когда на каждом шаге тренировке случайно исключали половину скрытых узлов.
Практическая модель состояла из двух скрытых слоев по времени, каждый из 300 узлов, и двух слоев по оси нот, на 100 и 50 узлов, соответственно. Тренировка проводилась в виртуальной машине g2.2xlarge в облаке Amazon Web Services.
Результаты
Исходный код программы опубликован на Github.