ИСПОЛЬЗОВАНИЕ МАШИННОГО ОБУЧЕНИЯ И ЦЕПИ МАРКОВА В СОЗДАНИИ МУЗЫКИ

МЕНЮ


Искусственный интеллект
Поиск
Регистрация на сайте
Помощь проекту
Архив новостей

ТЕМЫ


Новости ИИРазработка ИИВнедрение ИИРабота разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика

Авторизация



RSS


RSS новости


Сегодня мы поговорим об исследовании (http://vk.cc/55rMgp), рассматривающем звук и музыку с точки зрения математики и программирования. Такой подход позволяет оценить многогранную природу всего того, что мы привыкли слушать по дороге на работу или дома. Постараемся изложить основные моменты простыми словами.

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

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

1. Основная идея

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

Ноты (128 из них) - это вероятностные состояния. Для реализации всего процесса я буду использовать цепь Маркова второго порядка, а это означает, что следующее состояние системы будет строиться на основании двух предыдущих (нот). Все вероятности хранятся в матрице размерностью 2^14x2^7. На входе синтезатор получает два целых числа (0 <= n, m <= 127), выступающих в качестве начальных нот.

На их основании алгоритм вычисляет/генерирует следующую ноту и продолжает процесс вычисления до бесконечности (до тех пор, пока вы его не остановите). Для упрощения задачи, громкость звучания всех нот будет одинаковой (127), как и временной интервал между ними (300 мс).

Для корректной работы такого подхода необходима матрица весов, которую получают с использованием трех нот. Для каждой комбинации из трех нот первые две всегда являются «начальным» состоянием, а третья «конечным»; результатом всегда является инкрементация соответствующего поля в матрице весов [первая нота*127+вторая нота][третья нота].

Далее матрица весов «нормализуется» (или конвертируется) в матрицу переходов путем замены целых чисел на их процентное отношение к сумме всех значений в строке.

2. Процесс обучения

Алгоритм, описываемый в статье, использует для обучения MIDI-файлы (с расширением .mid), он обрабатывает аудиофайл нота за нотой, параллельно обновляя матрицу весов с помощью инструмента Java под названием Sequencer. Пример кода:

public Learn(String midiName) {

try {

Sequence sequence = MidiSystem.getSequence(new File(midiName));

int id[] = {0, 0, 0};

int nArr[][] = new int[2][2];

for(Track track : sequence.getTracks()) {

for(int i = 0; i < track.size(); i++) {

MidiEvent event = track.get(i);

MidiMessage message = event.getMessage();

if(message instanceof ShortMessage) {

ShortMessage sm = (ShortMessage) message;

if(sm.getCommand() == NOTE_ON) {

int key = sm.getData1();

for(int j = 0; j < 2; j++) {

if(id[j] == 2) {

id[j] = 0;

Score.updateWeight(nArr[j][0], nArr[j][1], key);

} else {

nArr[j][id[j]++] = key;

}

}

}

}

}

}

cnt++;

} catch(InvalidMidiDataException|IOException e) {

e.printStackTrace();

}

}

3. Выбор правильной ноты

Данный процесс основан на случайных величинах: текущем состоянии (последние две ноты последовательности) и матрице переходов, полученной ранее. Вероятность генерируется случайно, с помощью функции Java Math.random(). Затем алгоритм просматривает матрицу переходов и возвращает ту вероятность, которая совпала (или оказалась наиболее близка) с вероятностью, сгенерированной функцией Math.random().

Результат воспроизводится с помощью инструмента Synthesizer - результат определяется двумя начальными нотами, сгенерированными случайным образом или выбранными пользователем.

Вот пример композиции, созданной программой Markov composer: http://zx.rs/mp3/Piano1.mp3


Источник: github.com

Комментарии: