Введение
Сегодня мы попробуем создать простую музыку с помощью сетей LSTM. Цель этой статьи — указать практические возможности сетей. Пожалуйста, оставляйте ссылки на свои результаты в комментариях; было бы интересно посмотреть, какой результат получат читатели.
Минимальные навыки, которые должен иметь читатель, чтобы сделать свою собственную версию:
- Python3
- БАШ
- Юпитер-блокнот.
В первой части я покажу, как читать песню с помощью Jupyter-ноутбука.
В следующем абзаце я покажу сгенерированную музыку (в формате midi) сетью LSTM.
Я не вдавался здесь во все математические/технические вопросы машинного обучения. Для более подробной информации прикрепляю ссылки в футере.
Подготовка данных и прослушивание образцов музыки.
Используем входные данные в формате 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,
Примеры наборов данных в формате ABC можно скачать здесь.
Прочитать файл с песней
Я предлагаю использовать Jupyter-ноутбук для вашего удобства, но это не обязательно. Вы также можете попробовать совместную работу с Google или просто скрипт Python.
import numpy as np import matplotlib.pyplot as plt import tensorflow as tf #read the data my_song.abc with open('my_song.abc', 'r') as f: text = f.read()
Прослушивание песни
Чтобы прослушать песню, нам нужно установить некоторые дополнительные инструменты в нашей среде:
#in jupyter notebook
!apt-get install -y -qq abcmidi timidity
Как сохранить песню в файл?
#this step depends on format of input data, you should be careful song = text.split('\n\n') with open('my_song.abc', "w") as f: f.write(song)
Чтобы получить музыку в формате волны:
#in jupyter notebook
!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') #link to generated music #https://github.com/fuwiak/Habr/blob/master/my_song.wav
Время до LSTM
Чтобы проверить потенциал LSTM, нам нужно правильно подготовить обучающий набор, включая кодирование входных данных в числовые значения и преобразование входных данных в правильную форму.
#unique symbols vocab = set(text) #char encoding 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_text: строка из 100 символов.
- target_text: строка из 100 символов, сдвинутая на 1 символ.
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])
LSTM-модель
from tensorflow.keras.models import Model from tensorflow.keras.layers import Input, LSTM, Dense, Embedding vocab_size = len(vocab) 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 # you could try with other value BS = 128 # you could try with other value 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([ind_to_char[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) #in jupyter notebook !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
Результат можно было послушать здесь.
Используя LSTM, мы смогли легко создать неплохую музыку. Но это только одна из возможностей. Вы также можете использовать этот код для создания коротких текстов, таких как сообщения в Twitter, Facebook и т. д. Небо или, по крайней мере, ваше воображение — это предел.
Ссылки:
- https://www.analyticsvidhya.com/blog/2020/01/how-to-perform-automatic-music-generation/
- https://en.wikipedia.org/wiki/MIDI
- https://colah.github.io/posts/2015-08-Понимание-LSTMs/
- https://towardsdatascience.com/how-to-generate-music-using-a-lstm-neural-network-in-keras-68786834d4c5
- https://en.wikipedia.org/wiki/ABC_notation
- http://abcplus.sourceforge.net
- https://www.tensorflow.org/tutorials/text/text_generation
Первоначально опубликовано на https://habr.com.