Русский
Русский
English
Статистика
Реклама

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


Сегодня попробуем создать простую музыку при помощи сетей 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 npimport matplotlib.pyplot as pltimport tensorflow as tf

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

Прослушивание песни


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


!apt-get install -y -qq abcmidi timidity

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


#этот шаг зависит от входных данных, тут нужен гибкий подходsong = text.split('\n\n')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 AudioAudio('my_song.wav')#ссылка#https://github.com/fuwiak/Habr/blob/master/my_song.wav

Время на LSTM


Результат 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\nT: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 = 100step = 10sequences = 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])

LSTM


from tensorflow.keras.models import Modelfrom tensorflow.keras.layers import Input, LSTM, Dense, Embeddingvocab_size = len(vocab)#new valueembedding_dim = 256*2rnn_units = 1024*2x = 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 Adammodel.compile(optimizer=Adam(), loss='sparse_categorical_crossentropy')EP=5BS = 128hist = 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
К списку статей
Опубликовано: 23.06.2020 22:21:05
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Data mining

Python

Машинное обучение

Lstm

Machine learning

Категории

Последние комментарии

© 2006-2020, personeltest.ru