Мотивация Music VAE:

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

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

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

1. Традиционные LSTM не могут декодировать длинные последовательности, как в Music, из-за проблемы сужения задней части.

2. Апостериорный коллапс: исчезающее влияние скрытого состояния при генерации выходной последовательности.

Решение:

Иерархические декодеры:

• Дискретные скрытые векторы, прошедшие через несколько уровней декодера, а не через плоский декодер.

  • Уменьшите объем базового декодера нижнего уровня путем распространения состояния только внутри каждой подпоследовательности / полосы, как показано на схеме ниже:

  • Набор данных и предварительная обработка данных:
  • Модель MusicVAE принимает файлы MIDI, которые являются широко используемым форматом для музыки.
  • Каждый музыкальный семпл квантован до 16 нот на такт (шестнадцатые ноты). Чтобы представить некоторую предысторию этого:
  • В музыке 1 целая нота представляет 4 удара по времени, что равняется 1 такту, т. Е. 1 целая нота = 4 удара = 1 такт.
  • Затем восьмая нота проигрывается в течение одной восьмой от всей ноты, т. Е. 1 восьмая нота = 1/8 часть из 4 долей = ½ удара.
  • Точно так же 16-я нота воспроизводится в течение половины продолжительности восьмой ноты, т. Е. 1 шестнадцатая нота = 1/16 из 4 долей = ¼ долей.
  • Теперь, поскольку 1 такт состоит из 4 долей, потребуется 16 таких 16-ых нот, чтобы поглотить 1 такт музыки.
  • Для мелодии из 16 тактов MusicVAE использует двунаправленный кодировщик LSTM и иерархические однонаправленные декодеры LSTM.

Кодировщик:

Ввод в кодировщик:

16 тактовых музыкальных сэмплов, которые будут отправлены на кодировщик, могут быть представлены в виде трехмерной матрицы.

[batch_size, max_sequence_length, input_depth]

Здесь,

Batch_size: количество выборок во время обучения, равное 512.

Max_sequence length: максимально возможная длина последовательности, равная 16X16 = 256.

Input_depth: размер каждой проигрываемой ноты. Например. В монофонической фортепианной музыкальной последовательности может быть 90 типов событий на каждом временном шаге (88 нажатий клавиш, 1 отпускание, 1 пауза).

Таким образом, из мелодии из 16 тактов мы можем сгенерировать 90 ² возможных последовательностей.

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

примечания {высота: 69, скорость: 80, время начала: 1,25, время окончания: 1,5}

примечания {высота: 66, скорость: 80, start_time: 1.5, end_time: 1.75}

Здесь высота тона и скорость кодируют ноту, сыгранную на инструменте, например, на фортепиано.

Этот вход [512 X 256 X 4] подается в двунаправленный кодировщик LSTM.

Конфигурации и сведения о кодировщике:

Кодировщик rnn представляет собой двунаправленный LSTM из 2 уровней. Каждый уровень имеет размер состояния 2048, что означает, что в полносвязных слоях, которые образуют каждую ячейку LSTM, имеется 2048 скрытых узлов.

Входной тензор размеров [512 X 256 X 4], который сначала преобразуется в мажор времени (преобразование во мажор времени важно перед передачей в LSTM) с размерами [256 X 512 X 4], подается на первый уровень кодировщика rnn . Вывод с 1-го уровня передается на второй уровень, который дает нам вывод скрытых состояний в обоих направлениях - (Ht- fwd) и (Ht- bkwd).

Каждая ячейка в кодировщике получает ноту из последовательности относительно времени. Следовательно, имеется 256 ячеек LSTM для ввода мелодии с 16 тактами. Таким образом, размер ввода в 1-ю ячейку LSTM будет [1 X 512 X 4] и так далее.

Ниже приведен фрагмент кода:

Теперь мы берем только векторы конечных состояний (HT- fwd) и (HT- bkwd) из ячеек прямого и обратного направления, которые затем объединяются. Причина объединения двух скрытых состояний заключается в том, что скрытая функция должна описывать в обоих направлениях. Если используется одно из них, будет использоваться только информация с одной стороны, чего не должно быть в случае музыкальной интерполяции.

Размеры (HT- fwd) и (HT- bkwd) составляют [1 X 512 X 4] соответственно. Эти объединенные состояния, которые являются выходными данными кодировщика, затем проходят через 2 разных полностью связанных слоя с функцией активации softplus. Это дает нам параметры скрытого распределения mu и sigma для получения многомерного гауссовского нормального распределения, которое представляет апостериорное распределение каждой последовательности. Мю и сигма могут быть представлены как:

где W - матрицы весов, а b - векторы смещения. Это многомерное гауссовское распределение с 512 измерениями.

Объяснение однонаправленного и двунаправленного LSTM:

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

Обычно ячейка LSTM имеет 4 входа:

  1. Забудьте о воротах:
  2. Входные ворота
  3. Отборочные ворота
  4. Ворота внимания (необязательно)

Забыть шлюз: самый первый шлюз в ячейке LSTM, он решает, какую часть накопленной предыдущей информации, хранящейся в состоянии ячейки, следует забыть. Уравнение задается следующим образом:

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

Состояние ячейки после входа и выхода из забвения задается следующим образом:

Шлюз выбора: этот шлюз выбирает, какая часть текущей информации будет выводиться как:

Двунаправленная ячейка LSTM:

Двунаправленные LSTM - это всего лишь 2 однонаправленных LSTM, которые работают в противоположном направлении входной последовательности.

Описание потока кодировщика:

Объяснение кода кодировщика:

Пользователь может запустить команду music_vae_generate, указанную на веб-сайте Magenta VAE (https://github.com/tensorflow/magenta/tree/master/magenta/models/music_vae):

Music_vae_genarate.py - это скрипт Python, который определяет различные параметры, такие как:

  1. Режим: выборка или интерполяция

2. Num_outputs: количество выборок или количество шагов для интерполяции, включая конечные точки.

3. Checkpoint_file: место, где находится предварительно обученная модель.

4. Output_dir: место для сохранения фактического вывода.

5. Input_midi_1, input_midi2: входные файлы для интерполяции между ними. (Только для режима = интерполировать)

Команда Magenta создала «музыкальную» библиотеку, которая преобразует входные MIDI-файлы, предоставленные пользователем, в последовательности нот, как в приведенном ниже фрагменте кода, который можно найти в методе run configs.py:

Lstm_utils.py:

В этом скрипте есть метод cudnn_lstm_layer, который строит уровень LSTM в соответствии с переданными параметрами.

Layer_sizes: это список количества единиц на каждом уровне LSTM. В нашем случае есть 2 слоя LSTM, каждый с размером блока 2048. Однако, если вы посмотрите на lstm_models.py, метод BidirectionalLstmEncoder (описанный в следующем разделе), мы вызываем этот метод cudnn_lstm_layer по одному для каждого слоя.

Другой важный метод, о котором стоит упомянуть, - это get_final:

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

Lstm_models.py:

Основной интерес представляет BidirectionalLstmEncoder.

Первый метод в этом классе - build, который создает двунаправленную сеть LSTM:

Cells_fw: список, содержащий 2 однонаправленных уровня LSTM прямой сети

Cells_bw: список, содержащий 2 однонаправленных уровня LSTM обратной сети.

Обратите внимание, что мы вызываем cudnn_lstm_layer в lstm_utils.py, как описано выше.

Затем мы обсудим метод кодирования, который выполняет фактическое кодирование:

Кодировать:

  1. Согласно коду, мы можем видеть, что входной тензор сначала транспонируется в основной формат времени. Он имеет размер [256 X 512 X 4], который передается в прямые lstm-ячейки. Для обратных ячеек последовательность сначала меняется на обратную и затем передается в обратные ячейки lstm.
  2. Затем мы берем окончательный вывод скрытого состояния из передних ячеек lstm и первое скрытое состояние из обратных ячеек lstm, поскольку входной тензор для него был ранее инвертирован.
  3. Наконец, оба скрытых состояния размерности [512 X 4] объединяются, чтобы сформировать выходной сигнал кодировщика [1024 X 4] на два разных полностью подключенных слоя. Это дает нам параметры нормального распределения, как показано в приведенном ниже коде.

4) Softplus используется в качестве функции активации для плотного слоя, который дает нам сигма-значения для распределения.

5) Это дает нам параметры скрытого распределения mu и sigma для получения многомерного нормального распределения, которое представляет апостериорное распределение каждой последовательности.

Иерархический декодер:

Обзор:

В документе описывается использование дополнительного слоя, называемого проводником, для изучения более длинных последовательностей из скрытого пространства. Этот проводник - не что иное, как слой LSTM. Количество блоков LSTM в слое определяется гиперпараметром в зависимости от типа используемой музыки. Скрытые переменные, полученные от кодировщика, передаются через полностью связанную плотную сеть с функцией активации tanh. Затем он упаковывается в две блочные ячейки LSTM, которые используются для инициализации первого уровня входов LSTM декодера. Декодирование по глубине выполняется для получения окончательных результатов.

Архитектура

Уровень LSTM:

Длина уровня LSTM определяет количество блоков LSTM, присутствующих на каждом уровне. Он устанавливается как гиперпараметр и различается от модели к модели. Один блок LSTM на одном уровне уложил LSTM в стек каждый по 1024 единиц. Рассмотрим данный рисунок. Для level_length = [16,16]. Есть два уровня. На первом уровне есть 16 блоков LSTM, а на втором уровне - 16 блоков LSTM для каждого блока уровня 1. Общее количество блоков во втором уровне = количество блоков в слое 1 * количество блоков в слое 2 для каждого блока в слое. 1 = 16 * 16 = 256. Количество ячеек внутри одного блока LSTM зависит от гиперпараметра dec_rnn_size. На рисунке, показанном ниже, внутри одного блока расположены две стопки по 1024 ячейки. Другими словами, мультицентр состоит последовательно из 2 ячеек блока LSTM размером 1024 каждая. Затем второй уровень подключается к выходному слою LSTM.

Фрагмент кода:

Дирижер:

Первый уровень однонаправленного слоя LSTM - это то, что называется проводником. Только первая блочная ячейка в проводнике инициализируется вложениями из скрытого пространства. Это устанавливает скрытое состояние и состояние ячейки. Входные данные инициализируются нулями в зависимости от размера партии. Размер пакета задается гиперпараметром. Когда размер пакета равен 512, тензор формы 512 * 1, установленный все как нули, передается в качестве входных данных в первую блочную ячейку. Учитывая входные данные, состояние ячейки и скрытое состояние, он предоставляет следующее состояние ячейки, скрытое состояние и выходные данные. Значения состояния передаются в следующий LSTM.

Фрагмент кода:

Декодер:

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

Фрагмент кода:

Рекурсивное декодирование выполняется сначала в глубину. Внутри рекурсивной функции
декодирования,

Основной декодер:

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

Работает:

Это основано на модели «иерархического трио».

  1. Z of передается в плотный слой с функцией активации как tanh. Форма вывода - это размер сглаженного состояния первого блока LSTM на первом уровне (First Conductor). Если блок имеет 1024 + 1024 единиц LSTM, как упоминалось ранее, размер состояния будет c = 1024, h = 1024 для каждого из двух составных LSTM. Таким образом, размер сглаженного состояния будет [1024, 1024, 1024, 1024]
  2. Форма вывода плотного слоя - это сумма размеров сплющенного состояния (4096). Таким образом, плотный слой имеет форму 512 * 4096.
  3. Затем он разбивается на последовательность, дающую четыре разбиения (len (размер сглаженного состояния)), каждое из которых имеет форму 512 * 1024.
  4. Затем четыре разбиения упаковываются в два кортежа состояний lstm. Каждая из форм c = 512 * 1024, h = 512 * 1024. Где c - это состояние ячейки, а h - скрытое состояние lstm.
  5. Это становится начальным состоянием для первого проводника.
  6. На основе начального состояния выполняется декодирование по глубине, передавая выходные данные на нижележащие уровни и, наконец, на базовый декодер.
  7. Выход из проводника 1 становится входом для декодера следующего уровня (Core decoder).
  8. Декодер опять же однонаправленный LSTM как проводник.
  9. Состояния из декодера 1 передаются в качестве начальных состояний в декодер 2 для предоставления выходных данных и состояний, которые передаются следующему и т. Д.
  10. После того, как проводник 1 завершил декодирование, та же процедура начинается для проводников 2, 3 и так далее до длины уровня (в данном случае 16). Таким образом, каждый из проводников сначала декодирует рекурсивно идущую глубину, а проводники не зависят от выходов основного декодера, что заставляет его использовать скрытые векторы и тем самым помогает изучать более длинные последовательности.
  11. Затем выходные данные всех декодеров объединяются для получения окончательного результата. На рисунке ниже показан процесс декодирования.
  12. Потери при реконструкции рассчитываются путем сравнения окончательного результата с фактическим. Используется перекрестная энтропия
  13. Оптимизатор Adam используется для обучения

HVAE для создания текста:

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

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

Https://arxiv.org/pdf/1803.05428.pdf