如何用 TensorFlow 教机器人作曲?秘诀原来是这样

作者: 杨熹 2017-05-09 15:39:33

今天想来看看 AI 是怎样作曲的。

本文会用 TensorFlow 来写一个音乐生成器。

当你对一个机器人说: 我想要一种能够表达出希望和奇迹的歌曲时,发生了什么呢?

计算机会首先把你的语音转化成文字,并且提取出关键字,转化成词向量。然后会用一些打过标签的音乐的数据,这些标签就是人类的各种情感。接着通过在这些数据上面训练一个模型,模型训练好后就可以生成符合要求关键词的音乐。程序最终的输出结果就是一些和弦,他会选择最贴近主人所要求的情感关键词的一些和弦来输出。当然你不只是可以听,也可以作为创作的参考,这样就可以很容易地创作音乐,即使你还没有做到刻意练习1万小时。

机器学习其实是为了扩展我们的大脑,扩展我们的能力。

DeepMind 发表了一篇论文,叫做WaveNet, 这篇论文介绍了音乐生成和文字转语音的艺术。

通常来讲,语音生成模型是串联。这意味着如果我们想从一些文字的样本中来生成语音的话,是需要非常大量的语音片段的数据库,通过截取它们的一部分,并且再重新组装到一起,来组成一个完整的句子。

生成音乐也是同样的道理,但是它有一个很大的难点:就是当你把一些静止的组件组合到一起的时候,生成声音需要很自然,并且还要有情感,这一点是非常难的。

一种理想的方式是,我们可以把所有生成音乐所需要的信息存到模型的参数里面。也就是那篇论文里讲的事情。

我们并不需要把输出结果传给信号处理算法来得到语音信号,而是直接处理语音信号的波。

他们用的模型是 CNN。这个模型的每一个隐藏层中,每个扩张因子,可以互联,并呈指数型的增长。每一步生成的样本,都会被重新投入网络中,并且用于产生下一步。

我们可以来看一下这个模型的图。输入的数据,是一个单独的节点,它作为粗糙的音波,首先需要进行一下预处理,以便于进行下面的操作。

接着我们对它进行编码,来产生一个 Tensor,这个 Tensor 有一些 sample 和 channel。然后把它投入到 CNN 网络的***层中。这一层会产生 channel 的数量,为了进行更简单地处理。然后把所有输出的结果组合在一起,并且增加它的维度。再把维度增加到原来的 channel 的数量。把这个结果投入到损失函数中,来衡量我们的模型训练的如何。***,这个结果会被再次投入到网络中,来生成下一个时间点所需要的音波数据。重复这个过程就可以生成更多的语音。这个网络很大,在他们的 GPU 集群上需要花费九十分钟,并且仅仅只能生成一秒的音频。

接下来我们会用一个更简单的模型在 TensorFlow 上来实现一个音频生成器。

1.引入packaGEs:

数据科学包 Numpy ,数据分析包 Pandas,tqdm 可以生成一个进度条,显示训练时的进度。

  1. import numpy as np 
  2.  
  3. import pandas as pd 
  4.  
  5. import msgpack 
  6.  
  7. import glob 
  8.  
  9. import tensorflow as tf 
  10.  
  11. from tensorflow.python.ops import control_flow_ops 
  12.  
  13. from tqdm import tqdm 
  14.  
  15. import midi_manipulation 

我们会用到一种神经网络的模型 RBM-Restricted Boltzmann Machine 作为生成模型。

它是一个两层网络:***层是可见的,第二层是隐藏层。同一层的节点之间没有联系,不同层之间的节点相互连接。每一个节点都要决定它是否需要将已经接收到的数据发送到下一层,而这个决定是随机的。

2.定义超参数:

先定义需要模型生成的 note 的 range

  1. lowest_note = midi_manipulation.lowerBound #the index of the lowest note on the piano roll 
  2.  
  3. highest_note = midi_manipulation.uPPerBound #the index of the highest note on the piano roll 
  4.  
  5. note_range = highest_note-lowest_note #the note range 

接着需要定义 timestep ,可见层和隐藏层的大小。

  1. num_timesteps = 15 #This is the number of timesteps that we will create at a time 
  2.  
  3. n_visible = 2*note_range*num_timesteps #This is the size of the visible layer. 
  4.  
  5. n_hiDDen = 50 #This is the size of the hidden layer 

训练次数,批量处理的大小,还有学习率。

  1. num_epochs = 200 #The number of training epochs that we are going to run. For each epoch we go through the entire data set
  2.  
  3. BAtch_size = 100 #The number of training examples that we are going to send through the RBM at a time
  4.  
  5. lr = tf.constant(0.005, tf.float32) #The learning rate of our model 

3.定义变量:

x 是投入网络的数据

w 用来存储权重矩阵,或者叫做两层之间的关系

此外还需要两种 bias,一个是隐藏层的 bh,一个是可见层的 bv

  1. x = tf.placeholder(tf.float32, [None, n_visible], name="x") #The placeholder variable that holds our data 
  2.  
  3. W = tf.Variable(tf.random_normal([n_visible, n_hidden], 0.01), name="W") #The weightMATrix that stores the edge weights 
  4.  
  5. bh = tf.Variable(tf.zeros([1, n_hidden], tf.float32, name="bh")) #The bias vector for the hidden layer 
  6.  
  7. bv = tf.Variable(tf.zeros([1, n_visible], tf.float32, name="bv")) #The bias vector for the visible layer 

接着,用辅助方法 gibbs_sample 从输入数据 x 中建立样本,以及隐藏层的样本:

gibbs_sample 是一种可以从多重概率分布中提取样本的算法。

它可以生成一个统计模型,其中,每一个状态都依赖于前一个状态,并且随机地生成符合分布的样本。

  1. #The sample of x 
  2.  
  3. x_sample = gibbs_sample(1) 
  4.  
  5. #The sample of the hidden nodes, starting from the visible state of x 
  6.  
  7. h = sample(tf.sigmoid(tf.matMUl(x, W) + bh)) 
  8.  
  9. #The sample of the hidden nodes, starting from the visible state of x_sample 
  10.  
  11. h_sample = sample(tf.sigmoid(tf.matmul(x_sample, W) + bh)) 

4.更新变量:

  1. size_bt = tf. CA 
  2.  
  3. st(tf.shape(x)[0], tf.float32) 
  4.  
  5. W_adder = tf.mul(lr/size_bt, tf.sub(tf.matmul(tf.transpose(x), h), tf.matmul(tf.transpose(x_sample), h_sample))) 
  6.  
  7. bv_adder = tf.mul(lr/size_bt, tf.reduce_sum(tf.sub(x, x_sample), 0, True)) 
  8.  
  9. bh_adder = tf.mul(lr/size_bt, tf.reduce_sum(tf.sub(h, h_sample), 0, True)) 
  10.  
  11. #When we do sess.run(updt), TensorFlow will run all 3 update steps 
  12.  
  13. updt = [W.assign_add(W_adder), bv.assign_add(bv_adder), bh.assign_add(bh_adder)] 

5.运行 Graph 算法图:

1.先初始化变量

  1. with tf.Session() as sess: 
  2.  
  3. #First, we train the model 
  4.  
  5. #initialize the variables of the model 
  6.  
  7. init = tf.initialize_all_variables() 
  8.  
  9. sess.run(init) 

首先需要 reshape 每首歌,以便于相应的向量表示可以更好地被用于训练模型。

  1. for epoch in tqdm(range(num_epochs)): 
  2.  
  3. for song in sonGS: 
  4.  
  5. #The songs are stored in a time x notes format. The size of each song is timesteps_in_song x 2*note_range 
  6.  
  7. #Here we reshape the songs so that each training example is a vector with num_timesteps x 2*note_range elements 
  8.  
  9. song = np.array(song) 
  10.  
  11. song = song[:np.floor(song.shape[0]/num_timesteps)*num_timesteps] 
  12.  
  13. song = np.reshape(song, [song.shape[0]/num_timesteps, song.shape[1]*num_timesteps]) 

2.接下来就来训练 RBM 模型,一次训练一个样本

  1. for i in range(1, len(song), batch_size): 
  2.  
  3. tr_x = song[i:i+batch_size] 
  4.  
  5. sess.run(updt, feed_dict={x: tr_x}) 

模型完全训练好后,就可以用来生成 music 了。

3.需要训练 Gibbs chain

其中的 visible nodes 先初始化为0,来生成一些样本。

然后把向量 reshape 成更好的格式来 playback。

  1. sample = gibbs_sample(1).eval(session=sess, feed_dict={x: np.zeros((10, n_visible))}) 
  2.  
  3. for i in range(sample.shape[0]): 
  4.  
  5. if not any(sample[i,:]): 
  6.  
  7. continue 
  8.  
  9. #Here we reshape the vector to be time x notes, and then save the vector as a midi file 
  10.  
  11. S = np.reshape(sample[i,:], (num_timesteps, 2*note_range)) 

4.***,打印出生成的和弦

  1. midi_manipulation.noteStateMatrixToMidi(S, "generated_chord_{}".format(i))1212 

综上,就是用 CNN 来参数化地生成音波,

用 RBM 可以很容易地根据训练数据生成音频样本,

Gibbs 算法可以基于概率分布帮我们得到训练样本。

***送上Siraj 的原始视频和源代码链接。

ensorFlow 机器人 机器学习
上一篇:使用 Node.js 对文本内容分词和关键词抽取 下一篇:你可能正在制造一个人工智能,而你却不知道
评论
取消
暂无评论,快去成为第一个评论的人吧

更多资讯推荐

新AI让教师能够快速开发智能辅导系统

通过使用一种采用人工智能的新方法,教师可以通过演示解决某个主题中的问题的几种方法来教计算机……

佚名 ·  13h前
终结重复工作!教你30分钟创建自己的深度学习机器

建立一个深度学习环境是一件很重要的事情。本文讲述使用深度学习 CommunityAMI、TMUX和 Tunneling在EC2为Jupyter Notebooks创建一个新的深度学习服务器。

读芯术 ·  19h前
如何用机器学习模型,为十几亿数据预测性别

基于用户画像进行广告投放,是优化投放效果、实现精准营销的基础;而人口属性中的性别、年龄等标签,又是用户画像中的基础信息。那该如何尽量准确的为数据打上这些标签?

TalkingData ·  1天前
教你轻松选择合适的机器学习算法!

机器学习方面没有免费午餐。因此,确定使用哪种算法取决于许多因素:面临的问题类型和预期的输出类型等。本文介绍了为数据集探究合适的机器学习方法时要考虑的几个因素。

布加迪 ·  1天前
大学生发明扎钢筋机器人,一小时扎600个,建筑工人又要失业了?

因为人工智能的发展,一些纯靠手工的工人已经逐渐面临失业了,像现在的工厂里面,很多流水线上都已经由人力换成了人工智能。

裙裙时尚达人 ·  1天前
画图太丑拿不出手?有人做了套机器学习专用画图模板,还有暗黑模式

论文、博客写好了,里面的图可怎么画?对于很多研究人员和开发者来说,内容的「可视化」是一个大问题。如果从头开始画,配色、空间布局都很伤脑筋,而且画丑了也拿不出手,要是有模板可以套就好了。

张倩、魔王 ·  1天前
「狗机交互」来了!狗子会听谁的话?机器人 or 机器狗?

人能与机器人交互,已经不是什么新鲜事了,那么通人性的狗子是不是也能与机器人交互呢?

付静 ·  1天前
机器学习:物联网成功的诀窍?

通过机器学习,物联网可以完美地运行。全球各地的组织正在竞相利用物联网的能力,但是,其中许多组织都被我们讨论过的一个或多个障碍所困扰。不过,不管您遇到什么问题,都可以通过结合了机器学习技术的方法来解决。

iothome ·  2天前
Copyright©2005-2020 51CTO.COM 版权所有 未经许可 请勿转载