当前位置: 首页 > 科技观察

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

时间:2023-03-18 15:31:50 科技观察

今天想看看AI是怎么作曲的。本文将使用TensorFlow编写一个音乐生成器。当你对机器人说:我想要一首表达希望和奇迹的歌曲时会发生什么?计算机首先将你的语音转换成文本,然后提取关键词并转换成词向量。然后我们会使用一些带标签的音乐数据,这些标签就是人类的情感。然后,通过在这些数据上训练一个模型,模型训练完成后,就可以生成符合要求关键词的音乐。程序最终输出的是一些和弦,他会选择一些最接近大师要求的情感关键词的和弦输出。当然,你不仅可以听,还可以作为创作的参考,让你轻松创作音乐,即使你没有练过10000小时。机器学习其实就是开阔我们的脑筋,扩展我们的能力。DeepMind发表了一篇名为WaveNet的论文,介绍了音乐生成和文本转语音的艺术。通常,语音生成模型是级联的。这意味着如果我们想从一些文本样本中生成语音,我们需要一个非常大的语音片段数据库,通过截取其中的一部分并将它们重新组合在一起形成一个完整的句子。生成音乐也是如此,但是它有一个很大的难点:当你把一些静态的成分组合在一起的时候,它需要自然而有感情,这是非常困难的。在理想情况下,我们可以将生成音乐所需的所有信息存储在模型的参数中。这就是那张纸上的内容。我们不需要将输出通过信号处理算法得到语音信号,而是直接对语音信号的波形进行处理。他们使用的模型是CNN。在该模型的每个隐藏层中,每个扩展因子都可以相互关联并呈指数增长。每一步生成的样本将被放回网络中,用于生成下一步。让我们看一下这个模型的图表。输入数据是一个单独的节点,是一个粗糙的声波,需要先进行预处理,方便后面的操作。然后我们对其进行编码以生成一个Tensor,它具有一些样本和通道。然后将其送入CNN网络的第一层。该层生成通道数以便于处理。然后合并所有输出结果并增加其维度。然后将维度增加到原始通道数。将此结果输入损失函数以衡量我们的模型训练得如何。***,这个结果会再次投入网络,生成下一个时间点需要的声波数据。重复此过程以生成更多语音。该网络非常庞大,在他们的GPU集群上需要90分钟,并且只产生一秒钟的音频。接下来我们将使用一个更简单的模型在TensorFlow中实现一个音频生成器。1.引入包:数据科学包Numpy,数据分析包Pandas,tqdm可以生成进度条显示训练进度。importnumpyasnpimportpandasasspdimportmsgpackimportglobimporttensorflowastffromtensorflow.python.opsimportcontrol_flow_opsfromtqdmimporttqdmimportmidi_manipulation我们将使用神经网络模型RBM-RestrictedBoltzmannMachine作为生成模型。它是一个双层网络:第一层是可见层,第二层是隐藏层。同一层的节点之间没有连接,不同层的节点之间是有连接的。每个节点都必须决定是否需要将它收到的数据发送到下一层,而且这个决定是随机的。2.定义超参数:首先定义rangelowest_note=midi_manipulation.lowerBound#theindexofthelowestnoteonthepianorollhighest_note=midi_manipulation.uPPerBound#theindexofthehighestnoteonthepianorollnote_range=highest_note-lowest_note#thenoterange然后需要定义模型需要生成的note的timestep和hiddenlayer的大小。num_timesteps=15#Thisisthenumberoftimestepsthatwewillcreateatatimen_visible=2*note_range*num_timesteps#Thisisthesizeofthevisiblelayer.n_hiDDen=50#ThisisthesizeofthehiddenlayerTrainingtimes,batchsize,和学习率。num_epochs=200#Thenumberoftrainingepochsthatwearegoingtorun.Foreachepochwegothroughtheentiredataset.BAtch_size=100#ThenumberoftrainingexamplesthatwearegoingtosendthroughtheRBMatatime.lr=tf.constant(0.005,tf.float32)#thelearningrateofourmodel3用于存储两层数据矩阵的权重。另外,他们之间的关系需要两种偏置,一种是隐藏层的bh,一种是可见层的bvx=tf.placeholder(tf.float32,[None,n_visible],name="x")#TheplaceholdervariablethatholdsourdataW=tf.Variable(tf.random_normal([n_visible,n_hidden],0.01),name="W")#TheweightMATrixthatstorestheedgeweightsbh=tf.Variable(tf.zeros([1,n_hidden],tf.float32,name="bh"))#Thebiasvectorforthehiddenlayerbv=tf.Variable(tf.zeros([1,n_visible],tf.float32,name="bv"))#Thebiasvectorforthevisiblelayer接下来使用辅助方法gibbs_sample创建样本输入数据x,以及隐藏层的样本:gibbs_sample是一种可以从多个概率分布中抽取样本的算法。它可以生成一个统计模型,其中每个状态都依赖于先前的状态,并从分布中随机生成样本。#Thesampleofxx_sample=gibbs_sample(1)#Thesampleofthehiddennodes,startingfromthevisiblestateofxh=sample(tf.sigmoid(tf.matMUl(x,W)+bh))#Thesampleofthehiddennodes,startingfromthevisiblestateofx_sampleh_sample=sample(tf.sigmoid(W)bh))4.更新变量:size_bt=tf.CAst(tf.shape(x)[0],tf.float32)W_adder=tf.mul(lr/size_bt,tf.sub(tf.matmul(tf.transpose(x),h),tf.matmul(tf.transpose(x_sample),h_sample)))bv_adder=tf.mul(lr/size_bt,tf.reduce_sum(tf.sub(x,x_sample),0,True))bh_adder=tf.mul(lr/size_bt,tf.reduce_sum(tf.sub(h,h_sample),0,True))#Whenwedosess.run(updt),TensorFlowwillrunall3updatestepsupdt=[W.assign_add(W_adder),bv.assign_add(bv_adder),bh.assign_add(bh_adder)]5.运行Graph算法图:1.首先用tf.Session()assess初始化变量:#First,wetrainthemodel#initializethevariablesoftthemodelinit=tf.initialize_all_variables()sess.run(init)首先需要reshape每首歌曲,使得相应的向量表示可以更好地用于t给模型下雨。forepochintqdm(range(num_epochs)):forsonginsonGS:#Thesongsarestoredinatimexnotesformat.Thesizeofeachsongistimesteps_in_songx2*note_range#Herewereshapethesongssotheeachtrainingexampleisavectorwithnum_timestepsx2*note_rangeelementssong=np.array(song)song=song[:num.steps]/song_time[0]np.reshape(song,[song.shape[0]/num_timesteps,song.shape[1]*num_timesteps])2、接下来训练RBM模型,一次训练一个样本foriinrange(1,len(song),batch_size):tr_x=song[i:i+batch_size]sess.run(updt,feed_dict={x:tr_x})模型完全训练好后,就可以用来生成音乐了。3.需要先训练Gibbs链中的可见节点初始化为0,生成一些样本。然后将矢量重塑为更好的播放格式。示例=gibbs_sample(1).eval(session=sess,feed_dict={x:np.zeros((10,n_visible))})foriinrange(sample.shape[0]):ifnotany(sample[i,:]):continue#Herewereshapethevectortobetimexnotes,然后savethevectorasamidifileS=np.reshape(sample[i,:],(num_timesteps,2*note_range))4.***,打印出生成的和弦midi_manipulation.noteStateMatrixToMidi(S,"generated_chord_{}".format(i))1212综上所述,CNN用于参数化生成声波,而RBM可用于根据训练数据轻松生成音频样本。吉布斯算法可以帮助我们根据概率分布获取训练样本。***发送Siraj的原始视频和源代码链接。