Рекуррентные нейронные сети — пример генерации музыки

МЕНЮ


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

ТЕМЫ


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

Авторизация



RSS


RSS новости


Сегодня попробуем создать простую музыку при помощи сетей LSTM.

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

  • Python3
  • BASH
  • jupyter-notebook.

Не буду одобрять комментарии, в которых есть суть только:

  • причинить досаду автору, примерно про опечатки(я не являюсь носителем русского языка).
  • несущественные замечания и комментарии.
  • все что не касается сути стати.

Мы используем входные данные в формате ABC Примерные строки:

[V: S] (BA) !p!G2 |z AGA|(FG) A2| w: ple -na, Do-mi-nus te -cum, [V: A] F2       E2|z FEC|(DE) F2 | w: ple-na, Do-mi-nus te -cum, [V: T] (dc)     c2|z ccA|(Ac) c2 | w: ple -na, Do-mi-nus te -cum, [V: B] (B,,F,) C,2|z F,C,F,|(D,C,) F,2 | w: ple -na, Do-mi-nus te -cum,

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

Для вашего удобства, используйте jupyter notebook .

import numpy as np import matplotlib.pyplot as plt import tensorflow as tf 

with open('my_song.abc', 'r') as f:     text = f.read()


Чтобы прослушать песню, мы должны установить в нашу среду несколько дополнительных инструментов

!apt-get install -y -qq abcmidi timidity

Сохраняем выбранную песню в файл:

#этот шаг зависит от входных данных, тут нужен гибкий подход song = text.split('  ') with open('my_song.abc', "w") as f:     f.write(song)

Мы конвертируем в файл mid, а затем wav.

!abc2midi "my_song.abc" -o "my_song.mid" && timidity "my_song.mid" -Ow "my_song.wav"


from IPython.display import Audio Audio('my_song.wav') #ссылка #https://github.com/fuwiak/Habr/blob/master/my_song.wav


Результат my_song.wav оказывается неплохим, сейчас попробуем сделать свой вариант при помощи LSTM.

#уникальные символы, найденные в песнях. vocab = set(text)  # словарь: ключ=символ, значение=индекс, указав символ, мы получаем его индекс char_to_index = {char_ :ind for ind, char_  in enumerate (vocab)} ind_to_char = np.array(vocab) text_as_int = np.array([char_to_index[c] for c in text])  #'X:1 T:dfkjds ' ----- > [49 22 13  0 45 22 26 67 60 79 56 69 59] 


Создаются обучающие последовательности

  • input: строка из 100 символов
  • target: строка из 100 символов, но сдвинутая на 1.

Нашей модели будет поручено научиться прогнозировать следующий знак на основе 100 предыдущих. Это будет модель RNN версии "many to many", которая на самом деле будет прогнозировать один следующий символ, но в процессе обучения ошибка будет учитываться по всей последовательности (100 предсказаний).

 seq_length = 100 step = 10  sequences = np.array([text_as_int[i:i+seq_length+1] for i in range(0, len(text_as_int)-seq_length-1,step)]) input_text = np.array([seq[:-1] for seq in sequences])  target_text = np.array([seq[1:] for seq in sequences]) 


from tensorflow.keras.models import Model from tensorflow.keras.layers import Input, LSTM, Dense, Embedding  vocab_size = len(vocab)  #new value embedding_dim = 256*2 rnn_units = 1024*2  x = Input(shape=(seq_length,)) e = Embedding(vocab_size, embedding_dim)(x) l = LSTM(rnn_units, return_sequences=True)(e) d = Dense(vocab_size, activation='softmax')(l) model = Model(inputs=x, outputs=d) model.summary()


from tensorflow.keras.optimizers import Adam model.compile(optimizer=Adam(), loss='sparse_categorical_crossentropy')  EP=5 BS = 128  hist = model.fit(input_text, target_text, batch_size=BS, epochs=EP)


def generate_text(model, start_string, generation_length=100):    input_eval = np.array([char_to_index[s] for s in start_string])   x = np.zeros((1, seq_length))   x[0,-len(input_eval):] = input_eval[:]   text_generated = []    model.reset_states()   for i in range(generation_length):       predictions = model.predict(x)[0,-1]        predictions = predictions.astype(np.float64)       predictions = predictions/np.sum(predictions)           predicted_id = np.argmax(np.random.multinomial(1, predictions))       x[0,:-1] = x[0,1:]       x[0,-1] = predicted_id       text_generated.append([predicted_id])     return (start_string + ''.join(text_generated))

new_song = generate_text(model, "X:", generation_length=500) 


with open('new_song.abc', "w") as f:     f.write(new_song)

!abc2midi "new_song.abc" -o "new_song.mid" && timidity "new_song.mid" -Ow "new_song.wav"

 Audio('new_song.wav') #https://github.com/fuwiak/Habr/blob/master/new_song.wav


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


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

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