附代码 你想用深度学习谱写自己的音乐吗?这篇指南来帮助你!( 四 )


附代码 你想用深度学习谱写自己的音乐吗?这篇指南来帮助你!

文章插图
 
LSTM的优点:
  • 捕获输入序列中出现的顺序信息
【附代码 你想用深度学习谱写自己的音乐吗?这篇指南来帮助你!】LSTM的缺点:
  • 由于它是按顺序处理输入信息的 , 所以它在训练上会花费大量的时间
实现-使用Python进行自动音乐生成
等待结束了!让我们开发一个用于自动生成音乐的端到端模型 。启动你的Jupyter
notebook或Colab(或任何你喜欢的IDE) 。
下载数据集:
我从众多资源中下载并组合了多个数字钢琴(译者注:Digital piano与电钢琴Electric Piano的区别在于音源的产生方式)的古典音乐文件 。你可以从这里下载最终的数据集 。
(https://drive.google.com/file/d/1qnQVK17DNVkU19MgVA4Vg88zRDvwCRXw/view)
导入库:
Music 21是MIT开发的用于理解音乐数据的Python库 。MIDI是存储音乐文件的一种标准格式 。MIDI代表乐器数字接口 。MIDI文件包含说明而不是实际的音频 。因此 , 它只占用很少的内存 。这就是为什么它在传输文件时通常是首选的 。
1. #library for understanding music2. from music21 import *读取音乐文件:
我们直接定义一个函数来读取MIDI文件 。它返回音乐文件中存在的音符和和弦的数组 。
1. #defining function to read MIDI files2. def read_midi(file):3.4.print("Loading Music File:",file)5.6.notes=[]7.notes_to_parse = None8.9.#parsing a midi file10.midi = converter.parse(file)11.12.#grouping based on different instruments13.s2 = instrument.partitionByInstrument(midi)14.15.#Looping over all the instruments16.for part in s2.parts:17.18.#select elements of only piano19.if 'Piano' in str(part):20.21.notes_to_parse = part.recurse()22.23.#finding whether a particular element is note or a chord24.for element in notes_to_parse:25.26.#note27.if isinstance(element, note.Note):28.notes.append(str(element.pitch))29.30.#chord31.elif isinstance(element, chord.Chord):32.notes.append('.'.join(str(n) for n in element.normalOrder))33.34.return np.array(notes)现在 , 将MIDI文件加载到我们的环境中
1. #for listing down the file names2. import os3.4. #Array Processing5. import numpy as np6.7. #specify the path8. path='schubert/'9.10. #read all the filenames11. files=[i for i in os.listdir(path) if i.endswith(".mid")]12.13. #reading each midi file14. notes_array = np.array([read_midi(path+i) for i in files])理解数据:
在本节中 , 我们将探索数据集并对其进行详细了解 。
1. #converting 2D array into 1D array2. notes_ = [element for note_ in notes_array for element in note_]3.4. #No. of unique notes5. unique_notes = list(set(notes_))6. print(len(unique_notes))输出:304
如你所这里见 , 不重复音符的数量是304 。现在 , 让我们看一下音符的分布 。
1. #importing library2. from collections import Counter3.4. #computing frequency of each note5. freq = dict(Counter(notes_))6.7. #library for visualiation8. import matplotlib.pyplot as plt9.10. #consider only the frequencies11. no=[count for _,count in freq.items()]12.13. #set the figure size14. plt.figure(figsize=(5,5))15.16. #plot17. plt.hist(no)输出:
附代码 你想用深度学习谱写自己的音乐吗?这篇指南来帮助你!

文章插图
 
从上图可以看出 , 大多数音符的频率都很低 。因此 , 我们保留最常用的音符 , 而忽略低频率的音符 。在这里 , 我将阈值定义为50 。不过 , 这个参数是可以更改的 。
1. frequent_notes = [note_ for note_, count in freq.items() if count>=50]2. print(len(frequent_notes))输出:167
如你在这里看到的 , 经常出现的音符大约有170个 。现在 , 让我们准备新的音乐文件 , 其中仅包含最常见的音符
1. new_music=[]2.3. for notes in notes_array:4.temp=[]5.for note_ in notes:6.if note_ in frequent_notes:7.temp.append(note_)8.new_music.append(temp)9.10. new_music = np.array(new_music)准备数据:
如文章中所述准备输入和输出序列:
1. no_of_timesteps = 322. x = []3. y = []4.5. for note_ in new_music:6.for i in range(0, len(note_) - no_of_timesteps, 1):7.8.#preparing input and output sequences9.input_ = note_[i:i + no_of_timesteps]10.output = note_[i + no_of_timesteps]11.12.x.append(input_)13.y.append(output)14.15. x=np.array(x)16. y=np.array(y)现在 , 我们将为每个音符分配一个唯一的整数:
1. unique_x = list(set(x.ravel()))2. x_note_to_int = dict((note_, number) for number, note_ in enumerate(unique_x))


推荐阅读