关于机器学习:自成一派这个作曲大师确实名副其实

5次阅读

共计 6797 个字符,预计需要花费 17 分钟才能阅读完成。

AWS DeepComposer 是一项教育型的 AWS 服务,能够训练出生成式人工智能,并利用 GAN(Generative Adversarial Network)转换输出的旋律,创作出残缺的原创乐曲。

之前咱们曾有篇文章具体介绍过该服务,感兴趣的童鞋能够在这里查看:当音乐遇上人工智能 — 歌手们都在「云竞演」,作曲家就不想试试「云谱曲」?

简略来说,借助 AWS DeepComposer,咱们能够应用事后训练好的音乐流派模型(如爵士、摇滚、风行、交响乐等)将咱们提供的旋律转换为相应流派的曲子。那么当你玩转这个服务后,有没有想过本人也「开宗立派」,通过肯定的参数训练出本人的流派选项?

当然能够!咱们只须要将音乐数据文件存储在 NumPy 对象中,随后联合 GitHub 上的 Lab 2—— 训练一套自定义 GAN 模型中的训练步骤进行操作即可。下文将介绍如何将 MIDI 文件转换为实用于 AWS Deepomposer 的格局,而训练出本人的流派模型。

在下文中,咱们能够应用本人的 MIDI 文件训练出雷鬼音乐流派模型。雷鬼音乐诞生于牙买加岛,罕用乐器包含高音吉他、鼓以及各类打击乐器。不过本文介绍的办法也是通用的,大家齐全能够借此训练任何其余音乐流派。

数据处理:生成训练数据

MIDI(.mid)文件是训练数据的最初始状态。MIDI 文件由软件生成(并读取),文件中包含对于音符及声音回放的数据。在数据处理过程中,咱们须要将 MIDI 文件转换为 NumPy 数组,并将其长久化保留成磁盘上的一个独自的.npy 文件。下图展现了数据的转换过程:

只管机器学习广泛应用.csv 文件存储数据,但.npy 文件是为减速训练过程中的读取速度高度优化的。.npy 文件的最终状态应为(x, 32, 128, 4),其含意别离为(样本数量, 每个样本的工夫步数, 音高范畴, 乐器)。

若将 MIDI 文件转换为适当的格局,咱们须要实现以下步骤:

  1. 读取 MIDI 文件以生成一个 Multitrack 对象。
  2. 确定要应用的四条乐器音轨。
  3. 检索各音轨中的 Pianoroll 矩阵,并将其调整为正确的格局。
  4. 将 Pianoroll 对象与给定的乐器相匹配,并将其存储在.npy 文件中。

读取 MIDI 文件以生成一个 Multitrack 对象

数据处理的第一步,是解析各 MIDI 文件并生成一个 Multitrack 对象。下图即为 Multitrack 对象的根本构造。

这个过程用须要用到 Pypianoroll 库,它以 Python 代码实现读取及写入 MIDI 文件的性能。具体参见以下代码:

#init with beat resolution of 4
music_tracks = pypianoroll.Multitrack(beat_resolution=4)
#Load MIDI file using parse_midi
#returns Multitrack object containing Track objects
music_tracks.parse_midi(your_midi_file_directory + your_midi_filename)

music_tracks 是一个 Mulitrack 对象,蕴含一个从 MIDI 文件中读取到的 Track 对象列表。每个 Mulitrack 对象都蕴含速度(Tempo)、节奏(Downbeat)、节奏分辨率(Beat resolution)以及名称(Name),具体如以下代码所示:

tracks: [FRETLSSS, ORGAN 2, CLAVINET, MUTED GTR, CLEAN GTR, VIBRAPHONE, DRUMS],
tempo: [120. 120. 120. ... 120. 120. 120.],
downbeat: [ True False False False False False False False False . . .
 False False False False False False False False False False False False],
beat_resolution: 4,
name:“reggae1”

确定要应用的四条乐器音轨

如果要解析的 Mulitrack 对象中恰好蕴含四种乐器,则能够间接跳过此步骤。

咱们之前解析的 Mulitrack 对象共蕴含 7 条乐器音轨(Fretless 电贝司、风琴、竖笛、静音电吉他、浊音电吉他、颤音琴和鼓)。模型须要学习的乐器品种越多,训练工夫就越长,老本天然也越高。有鉴于此,这里咱们抉择的 GAN 只反对最多 4 种乐器。如果 MIDI 文件中的音轨蕴含 4 种以上乐器,请间接从所抉择的音乐流派中抉择最重要的 4 种乐器进行模型训练。相应的,如果乐器数量有余 4 种,则须要裁减 MIDI 文件。乐器数量谬误会导致 NumPy 的形制呈现谬误。

给定音轨上的每一种乐器都领有本人的编号。编号由通用 MIDI 标准规定,相当于乐器的惟一标识符。以下代码示例就用相干编号提取到钢琴、风琴、贝司以及吉他四种乐器:

instrument1_program_numbers = [1,2,3,4,5,6,7,8] #Piano
instrument2_program_numbers = [17,18,19,20,21,22,23,24] #Organ
instrument3_program_numbers = [33,34,35,36,37,38,39,40] #Bass
instrument4_program_numbers = [25,26,27,28,29,30,31,32] #Guitar
if track.program in instrument1_program_numbers:
 collection['Piano'].append(track)
elif track.program in instrument2_program_numbers:
 collection['Organ'].append(track)
elif track.program in instrument3_program_numbers:
 collection['Bass'].append(track)
elif track.program in instrument4_program_numbers:
 collection['Guitar'].append(track)

检索每条音轨中的 Pianoroll 矩阵,并将其调整为正确的格局

Multitrack 对象为每种乐器提供一个 Track 对象。每个 Track 对象中都蕴含一个 Pianoroll 矩阵、一个编号、人个示意音轨是否为鼓的布尔值以及一个名称。

以下代码,为繁多 Track 的具体示例:


pianoroll:
[[0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 ...
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]],
program: 7,
is_drum: False,
name: CLAVINET

在训练当中,繁多 Pianoroll 对象应具备 32 个离散的工夫步长,代表一首歌曲的片段与 128 个音高。所选乐器音轨的 Pianoroll 对象的起始状态为(512,128),咱们须要将其调整为正确的格局。每个 Pianoroll 对象将从新调整为 2 个大节(32 个工夫步长)、音高为 128。输出以下代码后,繁多 Pianoroll 对象的最终形制为 (16, 32, 128):

#loop through chosen tracks
for index, track in enumerate(chosen_tracks): 
 try:
 #reshape pianoroll to 2 bar (i.e. 32 time step) chunks 
 track.pianoroll = track.pianoroll.reshape(-1, 32, 128)
 #store reshaped pianoroll per instrument
 reshaped_piano_roll_dict = store_track(track, reshaped_piano_roll_dict) 
 except Exception as e:
 print("ERROR!!!!!----> Skipping track #", index, "with error", e)

为了简洁起见,以下代码示例仅显示钢琴音轨的制作示例:

{'Piano': [Track(pianoroll=array([[[0, 0, 0, ..., 0, 0, 0],
 [0, 0, 0, ..., 0, 0, 0],
 [0, 0, 0, ..., 0, 0, 0],
 ...,
 [0, 0, 0, ..., 0, 0, 0],
 [0, 0, 0, ..., 0, 0, 0],
 [0, 0, 0, ..., 0, 0, 0]],
 ...,
 [0, 0, 0, ..., 0, 0, 0],
 [0, 0, 0, ..., 0, 0, 0],
 [0, 0, 0, ..., 0, 0, 0]]], dtype=uint8), program=7, is_drum=False, name=CLAVINET)]

将 Pianoroll 对象与给定乐器相匹配,并将其存储在.npy 文件中。

下一步是按乐器将所有音轨连结起来,并将其存储在.npy 训练文件当中。咱们能够将这个过程了解为各 Pianoroll 对象间的彼此重叠。咱们须要为 4 种所选乐器别离反复这个过程,具体请参见以下代码:


def get_merged(music_tracks, filename):
...
#will hold all merged instrument tracks
merge_piano_roll_list = []
for instrument in reshaped_piano_roll_dict:
 try:
 merged_pianorolls = np.empty(shape=(0,32,128))
 #concatenate/stack all tracks for a single instrument
 if len(reshaped_piano_roll_dict[instrument]) > 0:
 if reshaped_piano_roll_dict[instrument]: 
 merged_pianorolls = np.stack([track.pianoroll for track in reshaped_piano_roll_dict[instrument]], -1)
 merged_pianorolls = merged_pianorolls[:, :, :, 0]
 merged_piano_rolls = np.any(merged_pianorolls, axis=0)
 merge_piano_roll_list.append(merged_piano_rolls)
 except Exception as e:
 print("ERROR!!!!!----> Cannot concatenate/merge track for instrument", instrument, "with error", e)
merge_piano_roll_list = np.stack([track for track in merge_piano_roll_list], -1)
return merge_piano_roll_list.reshape(-1,32,128,4)

当初,咱们将合并后的 Pianoroll 存储在.npy 文件当中,详见以下代码:

#holds final reshaped tracks that will be saved to training .npy file
track_list = np.empty(shape=(0,32,128,4))
. . .
#merge pianoroll objects by instrument
merged_tracks_to_add_to_training_file = get_merged(music_tracks, filename)
#concatenate merged pianoroll objects to final training data track list
track_list = np.concatenate((merged_tracks_to_add_to_training_file, track_list))
# binarize data
track_list[track_list == 0] = -1
track_list[track_list >= 0] = 1
#save the training data to reggae-train.npy
save(train_dir + '/reggae-train.npy', np.array(track_list))

后果

以上代码将一组存储在 your_midi_file_directory 中的 MIDI 文件生成 reggae-train.npy。相应 Jupyter notebook 与残缺代码可通过 GitHub repo 获取。

当初,咱们曾经领有了训练数据文件,接下来就能够依据 AWS DeepComposer 示例 notebook 中 Lab 2—— 训练自定义 GAN 模型提出的步骤训练自定义音乐流派模型。

本文在 SoundCloud 上提供两个由 AI 生成的雷鬼格调音轨:Summer Breeze 与 Mellow Vibe。

技巧与秘诀

咱们能够应用以下技巧与秘诀了解你的数据内容,并生成更悦耳的 AI 乐曲。

在 GarageBand 中查看及收听 MIDI 文件

如果你应用 Mac 设施,能够应用 GarageBand 收听 MIDI 文件并查看其中应用的乐器。如果没有 Mac 设施,则可应用任何其余反对 MIDI 文件的 Digital Audio Workstation(DAW)。在通过 GarageBand 收听 AI 生成的乐曲时,音质要显著更好,甚至能够连贯专业级扬声器以取得极好的听觉成果。

应用乐器编号更改伴奏的乐器

在运行 Lab 2—— 训练自定义 GAN 模型提供的推理代码时,大家可能会留神到,所有由 AI 生成的音轨都会在 GarageBand 中显示为“Steinway Grand Piano”。如果相熟 AWS DeepComposer 控制台,则可随时调整乐器品种。要在训练自定义模型时更改伴奏的乐器品种,请在调用 midi_utils 中的 save_pianoroll_as_midi 函数时应用 programs 参数,具体请见以下代码:

#use programs to provide the program numbers for the instruments I care about
#17 = Drawbar Organ, 28 = Electric Guitar, 27 = Electric Guitar, 11 = Music Box
midi_utils.save_pianoroll_as_midi(fake_sample_x[:4], programs=[17, 28, 27, 11], destination_path=destination_path)

应用 GarageBand 增加其余伴奏

在应用 AI 生成一首乐曲(带伴奏)之后,咱们能够应用 GarageBand(或者其余相似的工具)进一步增加更多伴奏。咱们能够调整音轨的速度,甚至让某些乐器静音。咱们也能够增加任意数量的其余伴奏乐器以发明出独特的声音体现。

在 AWS DeepComposer 管制台上创立推理旋律

在运行推理时,咱们须要一段 MIDI 格局的自定义旋律。咱们还能够增加伴奏乐器配合该自定义旋律生成一首独特的乐曲。在训练自定义模型时,最简略的旋律创立办法就是应用 AWS DeepComposer 控制台。咱们能够应用虚构键盘或者 AWS DeepComposer 键盘记录下旋律,而后抉择“Download”将其下载为 MIDI 文件。

应用 Matplotlib 绘制 Pianoroll

大家能够应用 Track 上的 Plot 函数绘制 Pianoroll 对象,这样就能直观查看 Pianoroll 对象了。具体请参见以下代码:

import matplotlib.pyplot as plt
...
fig, ax = track.plot()
plt.show()

下图所示,为 Pianoroll 对象的根本观感。

数据二值化

代码蕴含了一段对数据进行二进制化的局部。这项更新十分重要,因为在解决二进制化输出时,该模型理论解决的是 - 1 与 1(而非 0 与 1)。Track_list 中蕴含最终训练数据,在持续应用 Reggae-train.npy 之前,应将其设置为 - 1 或者 1。具体请参见以下代码:

# binarize data
track_list[track_list == 0] = -1
track_list[track_list >= 0] = 1

总结

AWS DeepComposer 不只是一款一般的键盘,同时也是一种乏味的互动形式,帮忙咱们理解生成式的 AI 与 GAN 的复杂性。咱们能够在它的帮忙下学习演奏简略的旋律,甚至可能激发出创作全新乐曲的灵感、训练出本人的自定义音乐流派模型、最终发明出前所未有的声音。咱们也能够将两种流派交融起来以发明出新的音乐类型!

正文完
 0