Настройте функцию потерь для генерации музыки с помощью LSTM (?)

Вопрос или проблема

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

введите описание изображения здесь

Я планирую иметь вход LSTM для каждого временного шага в виде векторизованного события из трех переменных:

x_t = [нота, громкость, временная метка]

нота: категориальная переменная, поскольку она может принимать только одно целое значение в диапазоне [0:127], соответствующее высоте звука.

громкость: я думаю, что она тоже категориальная, так как она также принимает одно целое значение в диапазоне [0:127], которое соответствует силе, с которой играется нота.

временная метка: непрерывная переменная, которая соответствует количеству секунд (в основном миллисекундам) или ударам, которые прошли между текущими и предыдущими событиями.

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

  • Можно ли выполнить one-hot-кодирование ноты и громкости, оставив временную метку без изменений?
  • Должен ли я дополнительно стандартизировать временную метку?
  • Могу ли я использовать кастомную функцию потерь (сумму потерь кросс-энтропии для ноты/громкости плюс среднеквадратичную ошибку для временной метки), или это испортит мою модель?

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

Спасибо!!!

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

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

Лучше зафиксировать темп так, чтобы, скажем, одна четвертная нота длилась 125 мс, а ваша временная переменная была целочисленным фактором этого. Вы можете сократить диапазон до [1, 16], так что самая короткая нота будет 125 мс, а самая длинная — 2000 мс (125 * 16).

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

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

Таким образом, с четырьмя октавами у вас остается две переменные $t \in [1,16]$ для времени и $p \in [1,48]$ для высоты. Вы можете либо предположить, что они независимы (хотя это не так, но сгенерированная музыка может все равно звучать хорошо!), и моделировать их отдельно, получая последовательность пар дискретных значений:
$$
(t_1, p_1), (t_2, p_2), …
$$

Либо вы можете перемножить $t$ и $p$, так что каждый вход в сеть будет целым числом в диапазоне [1,16*48]:
$$
t_1p_1, t_2p_2, …
$$

Вы также можете чередовать входные данные так, чтобы каждый второй элемент последовательности содержал информацию о времени и высоте:
$$
t_1, p_1, t_2, p_2, …
$$

Я не знаю, какой из способов лучше – вам нужно будет экспериментировать.

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

Ответ или решение

Настройка функции потерь для генерации музыки с использованием LSTM: Подходы и Рекомендации

При разработке проекта по генерации музыки с помощью LSTM в PyTorch, стоит уделить особое внимание выбору функции потерь, если ваши данные представляют собой наборы категориальных и непрерывных значений. Важно учитывать как структуру данных, так и особенности музыки, которую вы намерены генерировать. Давайте рассмотрим ваши вопросы по порядку.

1. Кодирование и нормализация данных

Кодирование:
Правильное кодирование переменных имеет большое значение. Захватывая ваш вопрос по поводу использования one-hot кодирования для переменных "нота" и "сила звука" (velocity), это действительно подходящее решение. Однако стоит учитывать следующее:

  • Нота (note): Однозначно стоит использовать one-hot кодирование, поскольку эта переменная относится к конечному множеству значений (от 0 до 127).
  • Сила звука (velocity): Вам стоит задуматься, насколько эта переменная влияет на качество генерируемой музыки. В большинстве случаев игнорировать её вполне допустимо, так как это упрощает модель и повышает её устойчивость. Если вы всё же решите её использовать, то one-hot кодирование также будет уместным.

Нормализация:
Что касается переменной "время" (timestamp), рекомендуется заменить её на дискретное значение, чтобы избежать проблемы с музыкальными ритмами. Например, можно ввести правильные временные доли, где каждая доля соответствует определённому интервалу. Это поможет избежать ошибок, связанных с неправильным восприятием музыки.

2. Нужно ли стандартизировать timestamp?

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

3. Настройка функции потерь

Ваше предложение о создании кастомной функции потерь, которая объединила бы перекрестную энтропию для "ноты" и "свойства звука" с среднеквадратической ошибкой для "времени", теоретически возможно. Однако стоит помнить, что это может вызвать сложности из-за различий в масштабах и типах переменных.

Оптимальным решением будет следующее:

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

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

Заключение

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

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

Оцените материал
Добавить комментарий

Капча загружается...