如何用 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)和机器人技术。实现这两种技术可以导致多个行业垂直领域的创新,包括医疗保健行业。

科幻网 ·  17h前
Epoch不仅过时,而且有害?Reddit机器学习板块展开讨论

Epoch最大的好处是确保每个样本被定期使用。当使用IID抽样时,你只要能想办法确保所有样本被同样频繁地使用就好了。

梦晨 ·  19h前
人工智能寒冬又到?美国教授arxiv发文批判AI,遭reddit网友狂喷

人工智能又被批评了?美国教授arxiv发文批评AI有四个误区,却不料遭reddit网友炮轰炒冷饭。

佚名 ·  20h前
如何用Python开发QQ机器人

虽然该文最终是达到以python开发mirai机器人的目的,但起步教程,尤其是环境配置上仍然有大量的相同操作,对其他编程语言仍有借鉴之处。

佚名 ·  22h前
人工干预如何提高模型性能?看这文就够了

下面我先从使用机器学习模型来推理系统入手,再展开人工干预的推理循环的技术介绍。

AI科技大本营 ·  1天前
做出电影级的 CG 渲染!斯坦福大学研究人员提出神经光图渲染

近日,一篇题为Neural Lumigraph Rendering的研究论文声称,它对现有的2个数量级图像进行了改进,展示了通过机器学习管道实现实时 CG 渲染的几个步骤。

佚名 ·  1天前
深度学习与机器视觉的重要性解析!推动机器人摆脱束缚?

深度学习是工业机器人的核心技术,能够推动机器人摆脱束缚,根据环境的变化,自主的进行工业操作,并且能够自主学习,充实自己,以适应不断变化的工业环境。

时尚小马甲 ·  2天前
工业机器人就业工资高吗

工业机器人的就业治疗如何?这是很多困惑,就业前景,薪水处理,我们知道这些是大多数人最有关的问题,今天带你一起来了解一下。

智通教育江老师 ·  3天前
Copyright©2005-2021 51CTO.COM 版权所有 未经许可 请勿转载