deepjazz 是一个使用theano 和keras的基于深度学习的jazz music 生成器.我在编程马拉松(hackathon)使用36个小时建立了deepjazz.它使用了theano和keras这两个库来生成jazz music.具体地说,它构建了两层的LSTM,从midi files 中学习.它使用了深度学习技术,以及AI技术,这个技术创造了著名的google AlphaGo和IBM的Watson,来产生音乐.而音乐被认为是很是human的.html
"melody_voice.insert(0, key.KeySignature(sharps=1,mode='major'))TypeError: init() got an unexpected keyword argument 'mode'
这里咱们只须要将mode = 'major'移除就能够了,后面还须要将generator.py中的 _sample 函数修改成:python
def __sample(a, temperature=1.0): a = np.log(a) / temperature # a = np.exp(a) / np.sum(np.exp(a)) # return np.argmax(np.random.multinomial(1, a, 1)) dist = np.exp(a)/np.sum(np.exp(a)) choices = range(len(a)) return np.random.choice(choices, p=dist)
作了如上的修改以后,再运行python generator.py 应该就能够正常run起来了,运行结束以后,在midi 文件夹下,会多出一个deepjazz_on_metheny...128_epochs.midi 文件,这个就是咱们经过 original_metheny.mid 训练学习获得的生成文件了.须要注意的是,不管咱们训练仍是生成的都不是常见的.mp3,.wav格式的音频文件,而是.mid(或者.midi)格式的文件.那么这二者有什么区别呢?这里引用百度百科的定义简单说明一下:git
与波形文件不一样,MIDI文件不对音乐进行抽样,而是对音乐的每一个音符记录为一个数字,因此与波形文件相比文件要小得多,能够知足长时间音乐的须要。MIDI标准规定了各类音调的混合及发音,经过输出装置能够将这些数字从新合成为音乐。
MIDI音乐的主要限制是它缺少重现真实天然声音的能力,所以不能用在须要语音的场合。此外,MIDI只能记录标准所规定的有限种乐器的组合,并且回放质量受到声音卡的合成芯片的限制。近年来,国外流行的声音卡广泛采用波表法进行音乐合成,使MIDI的音乐质量大大提升。
MIDI文件有几个变通格式,如RMI和CIF等。其中CMF文件(creative music format)是随声霸卡一块儿使用的音乐文件。RMI文件是Windows使用的RIFF(resource interchange file format)文件的一种子格式,称为RMID,即包含MIDI文件的格式。
简单来讲就是:常见的.mp3,.wav格式的文件记录的都是真实的音频内容,所以通常体积会比较大(几兆到几十兆不等),而midi格式的文件没有记录真实的音频信息,它只是记录了一种表明格式的数字,计算机能够按照必定的标准识别出这种数字,而后把它转化为对应的音频播放出来.所以通常.midi格式的文件体积很是小,这是它的一个很大的优势,其缺点就是对于真实的声音还原较差(由于它只能经过有限种指定的乐器来模拟声音).github
言归正传,在获得生成的midi文件以后,咱们固然须要播放它好好欣赏一番啦.在windows下有很多软件能够播放midi格式的文件,可是我使用的系统是ubuntu16.04,默认的播放器不支持midi格式,在查阅了资料之后发现须要安装timidity,在ubuntu 下
直接sudo apt-get install timidity 便可.我找了一个python脚本play_midi.py(基于pygame),能够播放midi 文件,代码以下:编程
import pygame import pygame as pg def play_music(music_file): ''' stream music with mixer.music module in blocking manner this will stream the sound from disk while playing ''' clock = pg.time.Clock() try: pg.mixer.music.load(music_file) print("Music file {} loaded!".format(music_file)) except pygame.error: print("File {} not found! {}".format(music_file, pg.get_error())) return pg.mixer.music.play() # check if playback has finished while pg.mixer.music.get_busy(): clock.tick(30) # pick a midi or MP3 music file you have in the working folder # or give full pathname music_file = input("Please input the midi file path:") #music_file = "Drumtrack.mp3" freq = 44100 # audio CD quality bitsize = -16 # unsigned 16 bit channels = 2 # 1 is mono, 2 is stereo buffer = 2048 # number of samples (experiment to get right sound) pg.mixer.init(freq, bitsize, channels, buffer) # optional volume 0 to 1.0 pg.mixer.music.set_volume(0.8) try: play_music(music_file) except KeyboardInterrupt: # if user hits Ctrl/C then exit # (works only in console mode) pg.mixer.music.fadeout(1000) pg.mixer.music.stop() raise SystemExit
运行python play_midi.py ,而后输入midi文件的路径,就能够播放啦.试着播放咱们生成的midi文件,你会发现听起来是至关不错的!
固然其实安装了timidity以后,咱们就能够直接播放midi文件了,直接运行 timidity xxx.midi 就能够了.可是有可能会出问题,由于咱们还须要一些额外的配置文件,运行命令'sudo apt-get install fluid-soundfont-gm fluid-soundfont-gs' 安装好soundfont(声音字体,用于解析midi,而且播放),而后打开/etc/timidity/timidity.cfg 文件,将最后一行'source freepats.cfg' 注释掉,若是是ubuntu系统的话改成:
dir /usr/share/sounds/sf2/
soundfont FluidR3_GM.sf2
若是是centos系统的话改成:
dir /usr/share/soundfonts/
soundfont FluidR3_GM.sf2
而后重启timidity,执行命令:sudo /etc/init.d/timidity restart
这样咱们再执行timidity xxx.midi应该就能够正常播放啦!ubuntu
如今咱们能够正常播放midi文件了.可是还有一个问题,通常咱们使用的音频格式是wav,mp3这种格式的,由于它们更易于被通常的播放器识别而且播放.那么有没有上面办法能够将midi文件转化为这样的格式呢?固然是有办法的,最简单的办法就是使用timidity(以前咱们已经安装过啦),运行下面的命令:
timidity --output-24bit --output-mono -A120 source.mid -Ow -o source.wav
就能够把source.mid 转化为source.wav 了.其中 --output指定输出的格式,-A指定音量(volume),-Ow 表示转化为RIFF WAVE file输出格式,-o指定输出音频文件的名字,具体能够timidity --help 查看各个参数的含义.
若是没有问题的话,咱们就获得一个.wav文件啦,这样你使用任何一个音乐播放器均可以播放它啦!
顺便提一个小问题.wav文件通常体积比较大(质量较好),而在网络上更常见的是mp3文件,那么这二者该如何转化呢?这里我提供两种解决办法:
1.使用ffmpeg 这个音视频库来进行转化.运行命令
ffmpeg -i source.wav -acodec libmp3lame source.mp3
就能够将source.wav 转化为source.mp3了.这里 -i 表示输入音频,-acodec 表示设置 audio codec(音频编码)格式,是"-codec:a"的别名,更多的信息能够输入 ffmpeg --help 或者 man ffmpeg查看
2.也能够安装python的音频库pydub进行转化,这个我在以前的博客介绍几个python的音频处理库介绍过,有兴趣能够自行查看.windows
这个问题我一开始觉得是挺容易实现的一个任务,哪知道查了资料之后才发现是一个很hard的问题,目前仍然有不少人研究music transcription(音乐转换)的问题.我没有找到一个很好地解决这个问题的api,具体能够参看stackoverflow的这个讨论,目前也有不少的plugin能够作这个事情,好比Sonic Annotator等,可是就涉及到很专业的知识了,我想了一个仍是放弃了...总之若是要作批量的从wav,mp3到midi的转化仍是很困难的,特别是要求比较高的质量的话,若是有兴趣,你们能够自行研究了.可是若是不要求大规模的自动转换,仍是有很多软件能够完成wav(mp3)到midi的转化的,好比这个网址能够在线将mp3转换为midi格式.centos
以前咱们是拿做者给的一个original_metheny.mid文件进行训练而后生成mid文件的.那么咱们能够拿本身的mid文件进行训练吗?这里有一个网址能够打包下载不少的midi文件,或者访问这个网址能够下载本身喜欢的流行音乐的midi格式.咱们发现咱们下载的midi文件的format,tracks,divisions都和deepjazz做者提供的original_metheny.mid格式不一样,因此若是只是把mid文件换成咱们本身的是没有办法顺利train的,老是会报错.我大概看了一下代码,主要是使用music21处理midi格式转换的代码部分有问题.我尝试了半天,由于本身对于music21以及midi格式不是很熟悉,因此这个问题暂时没有解决.若是我后面有时间了会好好再分析一下deepjazz的源码,解决这个问题.api
---------------------------------------------------------------------------Part II magenta ---------------------------------------------------------------浏览器
下面是magenta官方github的介绍.
magenta是一个旨在探索使用机器学习来创造艺术和音乐的研究项目.目前它主要使用新兴的深度学习技术以及强化学习技术来产生歌曲,绘画,图片等等.同时它也旨在探索构建智能化的工具和接口,这样艺术家可使用这些模型来扩展(而不是取代)他们的部分工做.
magenta最初是由Google Brain 的一些研究员发起的,可是其余的不少研究人员也为这个项目作出了巨大的贡献.咱们使用tensorflow在github上发布咱们的模型和代码.若是你想要了解更多关于magenta的事情,你能够查看咱们的博客,咱们在那里介绍了不少技术上的细节.你也能够加入讨论组.
安装magenta很是简单,能够直接使用pip install magenta 安装,可是要注意在此以前你须要安装好了tensorflow.
magenta支持gpu加速(你只须要安装gpu版本的tensorflow),使用pip install magenta-gpu 安装便可.magenta其实提供了很是多的models,包含了语音,图片等.这里咱们主要关注音乐生成方面的模型.
这是一个训练获得drums 风格音乐的模型.这个模型使用了LSTM将语言模型应用在drum track 生成上.和melodies不同,drum tracks是多音的,多个drums可能会同时存在.尽管这样,咱们仍是经过如下手段将drum track 做为一个single sequence 来处理:
a)将全部不一样的midi drums 映射到一个更小的drum classes上去
b)将每个event表达为一个单一值,该值表明了该次struck(敲击)所属的drums classes 类别
这里model 提供了两个configurations:one drum 和drum kit.具体能够参考原网址的说明
下面来讲明如何训练drums_rnn model.magenta其实已经提供了pre trained model,咱们能够首先快速来inference一下.首先下载drum_kit文件,而后将下载的drum_kit_rnn.mag文件放入某一个文件夹下(好比model/下).而后咱们写一个脚本generate_drums_rnn.sh:
#!/bin/bash drums_rnn_generate \ --config='drum_kit' \ --bundle_file=../data/drum_kit_rnn.mag \ --output_dir=../output \ --num_outputs=5 \ --num_steps=256 \ --primer_drums="[(36,)]"
这里 --config 是配置 configuration,有'drum_kit'和'one_drum'两个选项
--bundle_file 指定咱们bundle file的地址(就是刚才下载的drum_kit_rnn.mag文件)
--output_dir 指定输出midi文件的地址
--num_outputs 指定输出midi文件的个数(默认是10个)
--num_steps 指定训练的epochs(训练轮数)
--primer_drums 指定开始的一些音节(必填)
上面的脚本会以一个bass drum hit(低音)开始,若是你愿意的话,你也可使用其余的字符串形式的python list,可是list中的元素必须是一个tuple,并且必需要是表明drum 的midi 音节的整数.好比说:--primer_drums="[(36, 42), (), (42,)]"表示的意思就是一个bass 和一个hit-hat,而后是一个silence,最后是一个hit-hat.若是你不使用--primer_drums参数,你也可使用--primer_midi参数,来使用一个drum midi 文件来做为primer(开头).
若是按照上面的方式来进行尝试的话,你会获得一些midi文件.而后播放它吧,有些仍是至关不错的!
上面咱们使用了pre trained model,而后能够直接获得生成的midi文件,那么该如何来训练本身的model呢?训练本身的model有些复杂,咱们能够按照以下的steps 进行操做:
参考网址首先咱们须要准备本身的midi datasets,能够在这个网址打包下载,或者在这个midiworld本身手动下载,而后咱们须要将这些midi files 转化为NoteSequences.使用以下的脚本convert_midi.sh进行转换:
#!/bin/bash convert_dir_to_note_sequences \ --input_dir=$INPUT_DIRECTORY \ --output_file=$SEQUENCES_TFRECORD \ --recursive
上面的参数:
--input_dir表示输入midi files 的文件夹地址(能够包含子文件夹)
--output_file 表示输出.tfrecord文件的地址
--recursive 表示递归遍历midi files
注意若是你使用的是前一个midi datasets的话,因为这个数据集很是大(有1.6G左右),包含了很是多的midi文件,因此训练起来可能会很是耗时,我大概训练了两个小时还没训练完最后提早终止了,固然若是你的计算机性能很是好,你也能够尝试训练完.
训练完以后,咱们会获得一个lmd_matched_notesequences.tfrecord文件.接下来进入step2
注意咱们输入模型进行训练和评估的是SequenceExamples.每个SequenceExample都会包含一个序列输入和一个序列标签,表明了一个drum track.能够运行下面的命令将以前获得的NoteSequences 转化为SequenceExamples.这样将会产生两个部分的SequenceExamples,一个用于training,一个用于evaluation.具体可使用--eval_ratio来指定二者的比例.好比指定eval_ratio = 0.1(或者10%),会将提取出的drums tracks 的10%用于evaluation,剩下的90%用于training.
drums_rnn_create_dataset \ --config=<one of 'one_drum' or 'drum_kit'> \ --input=/tmp/notesequences.tfrecord \ --output_dir=/tmp/drums_rnn/sequence_examples \ --eval_ratio=0.10
上面的参数中:
--config 只能取值为'one_drum'或者'drum_kit'
--input 为step1获得的tfrecord文件地址
--output_dir 为输出SequenceExamples的文件夹地址
--eval_ratio 指定evaluation 和training的比例
运行下面的代码(train.sh)就能够进行train了.
#!/bin/bash drums_rnn_train \ --config=drum_kit \ --run_dir=/tmp/drums_rnn/logdir/run1 \ --sequence_example_file=/tmp/drums_rnn/sequence_examples/training_drum_tracks.tfrecord \ --hparams="batch_size=64,rnn_layer_sizes=[64,64]}" \ --num_training_steps=20000
各个参数的含义以下:
--config:'one_drum' or 'drum_kit'
--run_dir 是运行tensorflow训练模型checkpoints存放的文件夹地址
--sequence_example_file是用于训练模型的SequenceExamples tfrecord文件地址
--num_training_steps 指定训练的steps(轮数),若是不指定的话,会一直运行直到手动终止(CTRL-C或者CTRL-Z)
--hparams 用于指定其余的超参数,好比这里咱们指定了batch_size = 64,而不是默认的128.使用更小的batch size 有助于下降OOM(内存溢出)的风险,固然,若是你的内存够大,也能够设置较大的batch_size.这里还设定使用2 layers的RNN,每个layer 的hidden units都是64,而不是默认的3 layers,每一个layer有256个hidden units.这样能够加速训练(固然损失了必定的精度),若是你的计算机性能很高,你能够尝试更大的hidden units以得到更好的结果.咱们还能够设定--attn_length 参数来指定多少个steps进行一次attention machanism.这里咱们使用的是默认值32.
运行下面的代码(eval.sh)就能够进行evaluation.
!/bin/bash drums_rnn_train \ --config=drum_kit \ --run_dir=/tmp/drums_rnn/logdir/run1 \ --sequence_example_file=/tmp/drums_rnn/sequence_examples/eval_drum_tracks.tfrecord \ --hparams="batch_size=64,rnn_layer_sizes=[64,64]" \ --num_training_steps=20000 \ --eval
和train.sh差很少,惟一区别是--sequence_example_file须要指定eval的tfrecord file 了,还有就是多了一个--eval 用于指定这是一个eval过程,而不是train.注意eval过程不会改变任何一个参数,它只是用于评估模型的性能.
固然咱们也能够运行:tensorboard --logdir=/tmp/drums_rnn/logdir 来使用tensorboard来查看train 和eavl的结果,只要在浏览器打开:
http://localhost:6006 就能够了.
完成了step1~step3以后咱们就能够来产生本身的midi 文件了.运行的脚本为:
#!/bin/bash drums_rnn_generate \ --config=drum_kit \ --run_dir=/tmp/drums_rnn/logdir/run1 \ --hparams="batch_size=64,rnn_layer_sizes=[64,64]" \ --output_dir=/tmp/drums_rnn/generated \ --num_outputs=10 \ --num_steps=128 \ --primer_drums="[(36,)]"
大部分参数上面都已经解释了,这里再也不赘述.
melody_rnn model 和上面的 drums_rnn 很是相似,只不过这里产生的是melody,而上面产生的是drums.这里再也不赘述,具体能够参见melody_rnn
除了上面说的drums_rnn 和melody_rnn以外,magenta还有不少其余有趣的模型,好比neural style transfer(神经风格迁移,能够产生指定风格的图片)等,有兴趣的能够去magenta详细了解.
------------------------本文完,感谢阅读!-----------------------------------------------------------------------