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

如何使用TensorFlow构建、训练和改进递归神经网络

时间:2023-03-14 21:28:37 科技观察

硅谷数据科学的研究人员展示了递归神经网络(RNN)在探索时间序列和开发语音识别模型方面的能力。当前许多AI应用都依赖于递归深度神经网络,在谷歌(语音搜索)、百度(DeepSpeech)和亚马逊的产品中都可以看到RNN。然而,当我们着手构建自己的RNN模型时,我们发现几乎没有直接的先例可以遵循将神经网络用于语音识别等任务。可以找到的一些例子非常强大,但是非常复杂,比如Mozilla的DeepSpeech(基于百度的研究,使用TensorFlow);或无法应用于真实数据的极其简单的抽象。本文提供了一个简短的教程,包括代码片段,介绍如何使用RNN训练语音识别系统。本教程的灵感来自各种开源项目。本项目GitHub地址:https://github.com/silicon-valley-data-science/RNN-Tutorial首先,在你开始阅读本文之前,如果你还不了解RNN,可以阅读ChristopherOlah的RNNLong短期记忆网络概述:http://colah.github.io/posts/2015-08-Understanding-LSTMs/1.语音识别:声音和转录直到2010年,最好的语音识别模型仍然基于语音学方法,通常包含单独的组件,例如拼写、声学和语言模型。过去和现在的语音识别技术都依赖于使用傅立叶变换将声波分解为频率和振幅,从而产生如下图的声谱图:在训练语音模型时,隐马尔可夫模型(HiddenMarkovModels,HMM)需要语音+文本数据,还需要一个单词和音素的字典。HMM用于生成序列数据的概率模型,通常使用编辑距离(Levenshteindistance,编辑距离的一种。指的是两个字符串之间从一个变为另一个所需编辑操作的最少次数.可以执行的编辑操作包括一个字符替换另一个字符、插入一个字符和删除一个字符)。这些模型可以通过对音素相关数据进行训练来简化或变得更加准确,但这是一项繁琐的手动任务。因此,在大型数据集中,音素级语音转录比单词级转录更难实现。有关语音识别工具和模型的更多信息,请参考此博客:https://svds.com/open-source-toolkits-speech-recognition/二、连接时间分类(CTC)损失函数幸运的是,当使用神经网络时网络执行语音识别,我们可以通过可以执行单词级转录的连接主义时间分类(CTC)目标函数来丢弃音素的概念。简而言之,CTC能够计算多个序列的概率,即语音样本中所有可能的字符级转录的集合。神经网络使用一个目标函数最大化一个字符序列的概率(即选择最可能的转录),然后将预测结果与实际结果进行比较,并计算预测结果的误差以不断更新网络权重在训练中。值得注意的是,CTC损失函数中的字符级错误与传统语音识别模型中常用的Levenstein拼写错误相去甚远。对于字符生成RNN,字符和单词错误距离在语音语言(例如世界语、克罗地亚语)中是相同的,其中不同的发音对应不同的字符。相比之下,字符到单词的错误距离在其他语音文字(例如英语)中明显不同。如果你想了解更多关于CTC和百度对它的最新研究,这里有一些链接:http://suo.im/tkh2ehttp://suo.im/3WuVwVhttps://arxiv.org/abs/1703.00096在为了优化算法和构建传统/深度语音识别模型,SVDS团队开发了语音识别平台:3.数据的重要性毫无疑问,训练一个将语音转录为文本的系统需要数字语音文件和转录这些录音文字。由于该模型最终将用于解释新的语音,因此更多的训练意味着更好的性能。SVDS研究人员使用大量带有转录的英语演讲来训练模型;其中一些数据包括LibriSpeech(1000小时)、TED-LIUM(118小时)和VoxForge(130小时)。下图显示了这些数据集的信息,包括持续时间、采样率和注释。LibriSpeech:http://www.openslr.org/12/TED-LIUM:http://www.openslr.org/7/VoxForge:http://www.voxforge.org/为了让模型更容易获取数据,我们将所有数据以相同的格式存储。每条数据由一个.wav文件和一个.txt文件组成。例如:Librispeech的“211-122425-0059”对应Github中的211-122425-0059.wav和211-122425-0059.txt。这些数据的文件使用Dataset对象类加载到TensorFlow图形中,这使得TensorFlow可以更高效地加载、预处理和加载单批数据,从而节省CPU和GPU内存负载。Dataset对象中数据字段的示例如下所示:classDataSet:def__init__(self,txt_files,thread_count,batch_size,numcep,numcontext):#...deffrom_directory(self,dirpath,start_idx=0,limit=0,sort=None):returntxt_filenames(dirpath,start_idxstart_idx=start_idx,limitlimit=limit,sortsort=sort)defnext_batch(self,batch_size=None):idx_list=range(_start_idx,end_idx)txt_files=[_txt_files[i]foriinidx_list]wav_files=[x.repla('.txt','.wav')forxintxt_files]#Loadaudioandtextintomemory(audio,text)=get_audio_and_transcript(txt_files,wav_files,_numcep,_numcontext)四、特征表示为了让机器识别音频数据,数据必须首先从时域转换到频域。有多种方法可以创建音频数据的机器学习特征,包括任意频率(例如100Hz)的合并,或人耳可以感知的频率的合并。这种典型的语音数据转换需要针对13位或26位的不同倒谱特征计算梅尔倒谱系数(MFCC)。转换后,数据存储为时间(列)和频率系数(行)的矩阵。因为自然语言的发音不是独立的,它们与字母没有一对一的对应关系,所以我们可以捕捉到协同发音的效果(一个音节另一个音节的发音影响)。以下代码显示了如何获取MFCC功能以及如何创建音频数据窗口。Loadwavfilesfs,audio=wav.read(audio_filename)#Getmfcccoefficientsorig_inputs=mfcc(audio,samplerate=fs,numcepnumcep=numcep)#Foreachtimesliceofthetrainingset,weneedtocopythecontextthismakestrain_inputs=np.array([],np.float.shaperes_shape32)train_inputs(0],numcep复制代码+2*numcep*numcontext))fortime_sliceinrange(train_inputs.shape[0]):#Pickuptonumcontexttimeslicesinthepast,#Andcompletewithemptymfccfeaturesneed_empty_past=max(0,((time_slices[0]+numcontext)-time_slice))empty_source_past=list(empty_mf(need_empty_past))data_source_past=orig_inputs[max(0,time_slice-numcontext):time_slice]assert(len(empty_source_past)+len(data_source_past)==numcontext)...对于这个RNN例子,我们使用前后9个时间点——19个时间点总共。在25毫秒内共有494个数据点有26个倒谱系数。根据数据采样率,我们建议使用16,000Hz的26个倒谱特征和8,000Hz的13个倒谱特征。这里是8000Hz数据的加载窗口:如果你想了解更多关于转换数字音频用于RNN语音识别的内容,可以看看AdamGeitgey的介绍:http://suo.im/Wkp8B5.SpeechSequentialEssenceModeling长短期记忆(LSTM)是一种循环神经网络(RNN),适用于对依赖于长期顺序的数据进行建模。对于时间序列数据建模非常重要,因为这种方法可以在当前时间点保持对过去信息的记忆,从而改善输出结果,所以这个特性对于语音识别非常有用。如果您想了解如何在TensorFlow中实例化LSTM单元,这里是DeepSpeech启发的双向循环神经网络(BiRNN)的LSTM层的示例代码:withtf.name_scope('lstm'):#Forwarddirectioncell:lstm_fw_cell=tf.contrib。rnn.BasicLSTMCell(n_cell_dim,forget_bias=1.0,state_is_tuple=True)#Backwarddirectioncell:lstm_bw_cell=tf.contrib.rnn.BasicLSTMCell(n_cell_dim,forget_bias=1.0,state_is_tuple=True)#Nowwefeed`layer_3`intotheLSTMBRNNcellandobtainsoutputs.state_outputs.state.rnn.BasicLSTMCell(n_cell_dim,forget_bias=1.0,state_is_tuple=True)输出nn.bidirectional_dynamic_rnn(cell_fw=lstm_fw_cell,cell_bw=lstm_bw_cell,#InputisthepreviousFullyConnectedLayerbeforetheLSTMinputs=layer_3,dtype=tf.float32,time_major=True,sequence_length=seq_length)tf.summary.activations关于网络的更多细节,可以参考RNN和LSTM的概述单元操作详解:http://karpathy.github.io/2015/05/21/rnn-effectiveness/http://colah.github.io/posts/2015-08-Understanding-LSTMs/另外还有一些探索除RNN以外的其他语音识别方法的作品,例如比RNN计算效率更高的卷积层:https://arxiv.org/abs/1701.02720六、训练和监控网络因为示例中网络是使用TensorFlow训练的,我们可以用十orBoard的可视化计算图监控训练、验证和性能测试DandelionMane在2017TensorFlowDevSummit上给出了一些有用的帮助:https://www.youtube.com/watch?v=eBbEDRsCmv4我们使用tf.name_scope添加节点和层名称,并将摘要写入文件,结果是自动生成的,可理解的计算图,如下面的双向神经网络(BiRNN)所示。数据在不同操作之间从左下角到右上角传递。为清楚起见,可以使用名称空间标记和着色不同的节点。在这个例子中,蓝绿色的fc框对应于完全连接的层,绿色的b和h框分别对应于偏差和权重。我们利用TensorFlow提供的tf.train.AdamOptimizer来控制学习率。AdamOptimizer通过使用动量(参数的移动平均值)来促进超参数的动态调整,从而改进了传统的梯度下降。我们可以通过创建标签错误率的汇总标量来跟踪丢失率和错误率:使用tf.name_scope("accuracy"):#Computetheedit(Levenshtein)distanceofthetoppathdistance=tf.edit_distance(tf.cast(self.decoded[0],tf.int32),self.targets)#Computethelabelerrorrate(accuracy)self.ler=tf.reduce_mean(distance,name='label_error_rate')self.ler_placeholder=tf.placeholder(dtype=tf.float32,shape=[])self.train_ler_op=tf.summary.scalar("train_label_error_rate",self.ler_placeholder)self.dev_ler_op=tf.summary.scalar("validation_label_error_rate",self.ler_placeholder)self.test_ler_op=tf.summary.scalar("test_label_error_rate",self.ler_placeholder))7。如何改进RNN现在我们已经搭建了一个简单的LSTMRNN网络,接下来的问题是:如何继续改进它?幸运的是,在开源社区中,许多大公司都开源了他们最新的语音识别模型。2016年9月,微软的论文《The Microsoft 2016 Conversational Speech Recognition System》展示了一种在NIST200Switchboard数据上实现单系统残差网络错误率为6.9%的新方法。他们在卷积+递归神经网络之上使用了几种不同的声学和语言模型。微软团队和其他研究人员在过去4年中做出的主要改进包括:在基于字符的RNN上使用语言模型使用卷积神经网络(CNN)从音频中提取特征结合多个RNN模型Notable是的,传统方法获得的研究结果过去几十年的语音识别模型仍然在当前的深度学习语音识别模型中发挥作用。修改自:语音识别的历史视角,XuedongHuang,JamesBaker,ACM的RajReddyCommunications,Vol。57No.1,Pages94-103,20148.TrainyourfirstRNNmodelinthistutorial在Github中,作者提供了一些介绍来帮助读者在TensorFlow中使用RNN和CTC损失函数训练端到端语音识别系统.大多数案例数据来自LibriVox。数据存储在以下文件夹中:Train:train-clean-100-wav(5examples)Test:test-clean-wav(2examples)Dev:dev-clean-wav(2examples)在训练这些示例数据时,你会很快注意到训练数据的词错误率(WER)过拟合,而测试和开发集中的词错误率(WER)约为85%。单词错误率不是100%的原因是每个字母有29种可能性(a-z、逗号、空格和空格),神经网络可以快速学习:某些字符(e、a、空格、r、s、t)比其他的更常见辅音-元音-辅音是英语构词的一个特征,您可以在这些文件夹中添加额外的.wav和.txt文件,或者创建一个新文件夹并在configs/neural_network.ini中更新文件夹位置。注意:数百小时的音频可能需要大量时间来训练,即使您拥有强大的GPU。原文:https://svds.com/tensorflow-rnn-tutorial/【本文为专栏机器心、微信公众号“机器心(id:almosthuman2014)”原创翻译】点此查看作者更多多么好的文章