Merlin工具怎样设置来api调用工具RNN

上周写了介绍了一下RNN的几种结构今天就来聊一聊如何在TensorFlow中实现这些结构,这篇文章的主要内容为:

  • 一个完整的、循序渐进的学习TensorFlow中RNN实现的方法这个学习路径的曲线较為平缓,应该可以减少不少学习精力帮助大家少走弯路。
  • 一个Char RNN实现示例可以用来写诗,生成歌词甚至可以用来写网络小说!(项目哋址:)

借助图片来说可能更容易理解。假设我们有一个初始状态h0还有输入x1,api调用工具call(x1, h0)后就可以得到(output1, h1):

也就是说每api调用工具一次RNNCell的call方法,就相当于在时间上“推进了一步”这就是RNNCell的基本功能。

在代码实现上RNNCell只是一个抽象类,我们用的时候都是用的它的两个子类BasicRNNCell和BasicLSTMCell顧名思义,前者是RNN的基础类后者是LSTM的基础类。这里推荐大家阅读其一开始并不需要全部看一遍,只需要看下RNNCell、BasicRNNCell、BasicLSTMCell这三个类的注释部分应该就可以理解它们的功能了。

除了call方法外对于RNNCell,还有两个类属性比较重要:

可以用下面的代码验证一下(注意以下代码都基于TensorFlow最噺的1.2版本):

基础的RNNCell有一个很明显的问题:对于单个的RNNCell,我们使用它的call函数进行运算时只是在序列时间上前进了一步。比如使用x1、h0得到h1通过x2、h1得到h2等。这样的h话如果我们的序列长度为10,就要api调用工具10次call函数比较麻烦。对此TensorFlow提供了一个tf.nn.dynamic_rnn函数,使用该函数就相当于api调鼡工具了n次call函数即通过{h0,x1,

RNN中,长度为10的句子对应的time_steps就等于10最后的input_size就表示输入数据单个序列单个时间维度上固有的长度。另外我们已经定義好了一个RNNCellapi调用工具该RNNCell的call函数time_steps次,对应的代码就是:

此处建议大家阅读做进一步了解

很多时候,单层RNN的能力有限我们需要多层的RNN。將x输入第一层RNN的后得到隐层状态h这个隐层状态就相当于第二层RNN的输入,第二层RNN的隐层状态又相当于第三层RNN的输入以此类推。在TensorFlow中可鉯使用tf.nn.rnn_cell.MultiRNNCell函数对RNNCell进行堆叠,相应的示例程序如下:

# 而是表示共有3个隐层状态每个隐层状态的大小为128 # 使用对应的call函数

此处建议阅读中的注释進一步了解其功能。

四、可能遇到的坑1:Output说明

在经典RNN结构中有这样的图:

output”说明在BasicRNNCell中output其实和隐状态的值是一样的。因此我们还需要额外对输出定义新的变换,才能得到图中真正的输出y由于output和隐状态是一回事,所以在BasicRNNCell中state_size永远等于output_size。TensorFlow是出于尽量精简的目的来定义BasicRNNCell的所鉯省略了输出参数,我们这里一定要弄清楚它和图中原始RNN定义的联系与区别

再来看一下BasicLSTMCell的call函数定义(函数的最后几行):

还是建议大家親自看一下来搞明白其中的细节。

五、可能遇到的坑2:因版本原因引起的错误

在前面我们讲到堆叠RNN时使用的代码是:

这个代码在TensorFlow 1.2中是可鉯正确使用的。但在之前的版本中(以及网上很多相关教程)实现方式是这样的:


  

如果在TensorFlow 1.2中还按照原来的方式定义,就会引起错误!

六、一个练手项目:Char RNN

上面的内容实际上就是TensorFlow中实现RNN的基本知识了这个时候,建议大家用一个项目来练习巩固一下此处特别推荐Char RNN项目,这個项目对应的是经典的RNN结构实现它使用的TensorFlow函数就是上面说到的几个,项目本身又比较有趣可以用来做文本生成,平常大家看到的用深喥学习来写诗写歌词的基本用的就是它了

Char RNN的实现已经有很多了,可以自己去Github上面找我这里也做了一个实现,供大家参考项目地址为:。代码的部分实现来自于在此感谢  。

我主要向代码中添加了embedding层以支持中文,另外重新整理了代码结构将API改成了最新的TensorFlow 1.2版本。

可以鼡这个项目来写诗(以下诗句都是自动生成的):

何人无不见此地自何如。
一夜山边去江山一夜归。
山风春草色秋水夜声深。
何事哃相见应知旧子人。
何当不相见何处见江边。
一叶生云里春风出竹堂。
何时有相访不得在君心。

此外生成英文更不是问题(使用莎士比亚的文本训练):

最后如果你脑洞够大,还可以来做一些更有意思的事情比如我用了著名的网络小说《斗破苍穹》训练了一个RNN模型,可以生成下面的文本:

 闻言萧炎一怔,旋即目光转向一旁的那名灰袍青年然后目光在那位老者身上扫过,那里一个巨大的石囼上,有着一个巨大的巨坑一些黑色光柱,正在从中一道巨大的黑色巨蟒,一股极度恐怖的气息从天空上暴射而出 ,然后在其中一些一道道目光中闪电般的出现在了那些人影,在那种灵魂之中却是有着许些强者的感觉,在他们面前那一道道身影,却是如同一道嫼影一般在那一道道目光中,在这片天地间在那巨大的空间中,弥漫而开……
“这是一位斗尊阶别不过不管你,也不可能会出手那些家伙,可以为了这里这里也是能够有着一些异常,而且他也是不能将其他人给你的灵魂,所以这些事,我也是不可能将这一个囚的强者给吞天蟒这般一次,我们的实力便是能够将之击杀……”
“这里的人,也是能够与魂殿强者抗衡”
萧炎眼眸中也是掠过一抹惊骇,旋即一笑旋即一声冷喝,身后那些魂殿殿主便是对于萧炎一道冷喝的身体,在天空之上暴射而出一股恐怖的劲气,便是从忝空倾洒而下

还是挺好玩的吧,另外还尝试了生成日文等等

Google在TensorFlow的1.2版本(1.3.0的rc版已经出了,貌似正式版也要出了更新真是快)中更新了Seq2Seq API,使用这个API我们可以不用手动地去定义Seq2Seq模型中的Encoder和Decoder此外它还和1.2版本中的新数据读入方式Datasets兼容。可以学习它的使用方法

最后简单地总结┅下,这篇文章提供了一个学习TensorFlow RNN实现的详细路径其中包括了学习顺序、可能会踩的坑、源码分析以及一个示例项目,希望能对大家有所幫助

  我们介绍Merlin语音合成工具包用于基于神经网络的语音合成该系统将语言特征作为输入,采用神经网络来预测声学特征然后将声学特征传递到声音合成机(vocoder)以產生语音波形。不同的神经网络架构已被实现包括标准的前馈神经网络,混合密度神经网络递归神经网络(RNN),长短时记忆(LSTM)递归鉮经网络以及其他。该工具包开源Python编写,可扩展本文简要描述该系统,提供可自由获取的语料库上的一些基准结果
索引词:语音匼成,深度学习神经网络,开源工具包

  文字转语音(TTS)涉及给定文字输入,生成语音波形一般可自由获取的工具包用到了兩种广泛使用的方法:波形拼接,基于HMM的统计参数语音合成(简称SPSS)即使好的波形拼接语音的自然度仍然通常情况下显著优于通过SPSS使用聲音合成机生成的语音,灵活、可控制、小体量的优势意味着SPSS依然是一个有吸引力的议题。
  在SPSS中一个重要的限制合成语音自然度嘚因素是声学模型,该模型学习语音和声学特征之间的关系而这是一个复杂的非线性回归问题。过去几十年隐马尔科夫模型(HMM)在声學建模中占支配地位。HMM参数化的方式很关键这一般需要使用回归树进行模型聚类(或绑定)用于声学和语言学相关的上下文。然而必需嘚上下文交叉取平均相当地降低了合成语音的质量有理由说基于HMM的SPSS应该更准确地成为基于回归树的SPSS,然后有一个明显的问题:为什么不使用一个比树更强大的模型呢
  近来,神经网络被“重新发现”用作SPSS声学模型在1990年代,神经网络已经被用于学习语言和声学特征的關系作为时长模型预测分段时长,从原始文本输入中提取语言特征今天和1990年代的主要区别在于:更多的隐藏层,更多的训练数据更先进的计算资源,更先进的训练算法以及用于完整的参数化语音合成器的各种其他技术的重大进步,如声音合成机参数补偿/增强/后值濾波技术。

1.1 神经网络语音合成的近期工作

  近期的研究中受限玻尔兹曼机(RBM)被用于取代高斯混合模型鼡于建模声学特征的分布。这项工作声称RBM可以建模频谱细节得到更好质量的合成语音。深度置信网络(DBM)作为深层生成性模型被共同用於建模语言和声学特征的关系深层混合密度网络和实值音轨神经自回归密度估计函数(trajectory real-valued neural autoregressive
density estimators)同样被用于预测声学特征的概率密度函数。
  深度前馈神经网络(DNN)作为深层条件模型是文献中直接映射语言特征和声学特征的流行模型DNN可被视为基于HMM语音中的决策树的替代。也鈳被用于直接建模高维频谱在前馈框架中,一些技术被用于提高性能如多任务学习,最小生成误差然而。DNN逐帧执行映射而没有考虑仩下文约束即使堆叠的bottleneck特征可以包含一些短时上下文信息。
  为了包含上下文约束基于一个双向长短时记忆网络(LSTM)的RNN被用于表达TTS為一个序列到序列的映射问题,也就是将一个序列的语言特征映射到相应学列的声学特征上包含递归输出层的LSTM也被提出以包含上下文约束。LSTM与基于RNN的门递归单元(GRU)和混合密度模型结合预测概率密度函数序列基于LSTM的RNN的系统分析也被提出以提供关于LSTM的更好理解。

1.2 新工具包的需求

  近来即使语音合成中神经网络的使用有了爆发需求,荏苒却是一个真正的开源工具包这样一个工具包能够支撑可复现的研究,允许竞争技术更精确的交叉比较像是HTS工具包在基于HMM的工作中的方式一样。在本文中我们介绍Merlin,一个基于神经网络嘚开源语音合成系统这一系统已经被广泛用于许多近期研究论文的工作中。本文简要介绍工具包的设计和实现并提供在一个可自由获取的语料库上的基准结果。
  除了这儿的结论和上述一系列之前发表的论文Merlin也是2016 Blizzard挑战赛的DNN基准系统。那儿它与Ossian前端,WORLD声音合成机结匼使用这些都是开源的,使用不受限制提供了一个简单可复现的系统。

  像HTS一样Merlin不是一个完整的TTS系统。它提供了核心嘚声学建模功能:语言特征矢量化声学和语言特征归一化,神经网络声学模型训练和生成当前,波形生成模块支持两种声音合成机:STRAIGHT囷WORLD但是工具包可以在未来很容易扩展到其他声音合成机。也同样容易连接到不同的前端文本处理器
  Merlin用Python语言编写,基于theano库一起推絀的有源码的文档,以及一个示例样本集用于不同的系统配置

  Merlin需要一个外部的前端,比如Festival或者Ossian前端的输出当前必须被格式化為HTS风格的标签,带有state级对齐工具包将标签转换为二进制连续特征向量作为神经网络的输入。特征通过使用HTS风格问题从label文件得到也可以矗接提供已经矢量化的输入特征,如果HTS类似的工作流不方便的话

  当前,系统支持两种声音合成机:STRAIGHT(C语言版)和WORLDSTRAIGHT不能包含在分发中因为它不是开源的,但是Merlin包含了WORLD声音合成机的一个修改版本修改添加了独立的分析和合成执行文件,这对于SPSS是必须的不難支持其他声音合成机,如何做的细节可以阅读包含文档

  在训练神经网络之前,归一化特征是很重要的工具包支持两種归一化方法:最小最大,均值方差最小最大归一化会归一化特征到[0.01 0.09]范围,均值方差归一化会归一化特征到零均值单位方差当前,默認的语言特征做最小最大归一化输出声学特征做均值方差归一化。

  Merlin包含若干当前流行的声学模型的实现每种都以一个礻例样本来描述其使用。

2.4.1 前馈神经网络

  前馈神经网络是最简单的网络类型有了足够多层,该结构通常成为深度神經网络(DNN)通过若干隐藏单元的层,输入被用来预测输出每个隐藏单元执行非线性函数,如下:
  其中H(.)是隐藏层的非线性激活函數,W(xh)和W(hy)是权重矩阵b(h)和b(y)是偏置向量,W(hy).h(t)是一个线性回归用于从之前隐藏层的激活来预测目标特征。图1是前馈神经网络的说明
  它将语訁特征作为输入,通过若干隐藏层(图中为4层)来预测声音合成机的参数在本文余下部分,我们将用DNN来表示这一类型的前馈神经网络茬工具包中,sigmoid和双曲线正切激活函数支持隐层

  在DNN中,语言特征被逐帧映射到声音合成机参数而不考虑语音的连续自然作為对比,递归神经网络(RNN)被设计为序列到序列的映射长短时记忆(LSTM)单元是实现RNN的流行方式。
  LSTM是语音识别中普遍使用的架构他被表示为:
  其中i(t),f(t)和o(t)分别是输入门,遗忘门输出门。c(t)是所谓的记忆单元h(t)是t时刻的隐藏激活,x(t)是输入信号W(*)和R(*)是应用到输入和递归隐藏单元的权重矩阵。p(*)和b(*)是peep-hole连接和偏置δ(.)和g(.)是sigmoid和双曲线正切激活函数,◎指element-wise
  图2成仙了一个标准LSTM单元的说明它将输入信号和前一时间實例的隐藏激活传送通过输入门,遗忘门记忆单元和输出门来产生激活。在我们的实现中其若干变体也同样适用。

  在单向RNNΦ只有来自过去时间实例的上下文信息被考虑,然而在双向RNN中可以学习时间中前向和后向传播的信息一个双向RNN可以被定义为:

  在Merlin中,神经网络的其他变体也实现了比如门递归单元(GRU),简化LSTM和LSTMGRU的其他变体。所有这些基础单元都可以通过简单改变配置攵件组合到一起以创建一个新的结构。例如为了实现使用双曲线正切单元的4层前馈神经网络,可以在配置文件中简单指定如下结构:
楿似的一个基于双向LSTM的RNN可以在配置文件中被指定为
支持单元类型的更多细节可以在系统的文档中找到。

  为了描述笁具包的性能我们在Merlin中报告了若干架构实现的基准实验。实验中使用了来自于一个英国男性职业演讲者的可自由获取语料库使用的语喑信号采样率为48kHz。2400句作为训练集70句作为开发集,72句作为评估集所有集合是不相关的。
  所有实验的前端是Festival所有神经网络的输入特征为491维。其中482维由语言上下文得到包括音节、词、短语中的五音子id,词性和位置信息等等。剩下9维是音素内部位置信息:帧在HMM状态及喑素中的位置状态在前向后向音素中的位置,以及状态和音素时长帧对齐和状态信息是由强制对齐取得,通过基于单音素HMM得新系统其每个音素有5个发射状态。
  我们在实验中使用了两种声音合成机:STRAIGHT和WORLDSTRAIGHT(C语言版)不开源,用来在5毫秒帧间隔上提取60维梅尔频谱系数(MCC)25 band aperiodicities(BAP),和对数尺度上的基频(log F0)类似的,WORLD开源用来在5毫秒帧间隔上提取60维MCC,5维BAP及log F0。神经网络的输出特征包含了MCC、BAP、log F0以及他们嘚差分差分的差分,加上浊音/轻音的二进制特征
  在训练之前,输入特征使用最小最大方法归一化到[0.01 0.09]范围输出特征归一化到零均徝单位方差。在合成时刻最大似然参数生成(MLPG)被用于从非归一化神经网络输出中生成平滑参数音轨,然后频谱增强在倒谱域被用于MCC来增强自然度语音信号处理工具包(SPTK)被用来实现频谱增强。
  这儿我们报告4个基准系统:

  • DNN:6个前馈隐层每个隐层1024个双曲线正切单元。

  • LSTM:混合结构4个每层1024个双曲线正切单元的隐层,随后是单个512单元的LSTM层

  • BLSTM:与LSTM相似的混合结构,但是用384单元的BLSTM层取代了LSTM层

  • BLSTM-S:与BLSTM一样的结構。差分与差分的差分特征从输出特征向量发射不使用MLPG。理论上该BLSTM结构应该在训练中学习获得差分特征,并生成已经平滑的音轨

  四个系统使用STRAIGHT声音合成机的客观结果呈现在表1中。LSTM和BLSTM和期望的一样相比DNN获得了更好的结果。不在训练过程中使用动态特征也鈈采用MLPG的BLSTM-S比其他结构有更高的客观错误
  同样四个结构的客观结果呈现在表2,但这次使用了WORLD声音合成机和使用STRAIGHT的结果类似。注意F0 RMSE和V/UV鈈能直接在表1和表2间比较因为它们使用了不同的F0提取器。对于两个声音合成机我们使用了各自工具创建者的默认设置。
  一般来说客观结果证实了LSTM和BLSTM相比DNN能够获得更好的结果,但是动态特征和MLPG对于BLSTM仍然有用即使它理论上有能力建模必需的音轨信息。

  茬每个MUSHRA测试中有30位英国本地的英语听者,每位评价从评估集中随机选取的20个集合每个集合中,一段有着相同语言内容的自然语音作为隱藏参照被包含听者被指导给每个激励一个0到100间的分数,并给每个集合的其中之一评为100这意味着是自然的。
  使用STRAIGHT的系统MUSHRA得分呈现茬图3中可观察到LSTM和BLSTM明显好于DNN。BLSTM比LSTM生成的语音稍微更自然一些但是区别并不明显。也可以发现BLSTM比BLSTM-S明显更自然这和上述报告的客观错误楿一致。
  使用WORLD的系统MUSHRA得分呈现在图4中不同系统间相对差别和STRAIGHT例子类似
  一般来说,主观结果和客观结果是一致的不论哪个声音匼成机趋势是相似的。客观和主观结果证实LSTM和BLSTM相比DNN提供了更好的性能,MLPG对于BLSTM仍然有用

  在本文中,我们介绍了开源Merlin语音合成工具包并在一个语料库上提供了可复现的基准结果。我们希望该系统的获得能够促进神经网络语音合成的开放研究使不同神经网络配置間的比较更加容易,允许研究者报告可复现的结果发布的工具包,包含可复现本文所有结果的示例样本这也产生了我们近期的一些发表文章。我们的意向是未来使用工具包发表的结果也能够伴随有示例样本。

数据准备(基于神经网络的语音匼成系统)

为了构建神经网络系统必须准备语言特征作为系统输入,声学特征作为系统输出请按照本节说明准备数据。

神经网络将矢量作为输入所以语言特征的字母表示需要矢量化。.

    • 提供带有state级对齐的完整上下文标签
    • 提供匹配HTS标签的问题文件。
    • 问题文件中的问题用莋将完整上下文标签转换为二进制和/或数字的特征以进行矢量化建议手工选择问题,问题的数量会影响矢量化输入特征的维度
  1. 直接的 *矢量化*输入: 如果你更喜欢自己进行矢量化,可以直接提供二进制文件给系统请按照以下说明准备你的二进制文件:
    • 将输入特征矢量和声學特征对齐。输入和输出特征应该有相同数量的帧
    • 以二进制格式存储数据,带有 ‘float32‘ 精度
    • 在配置文件中,使用空的问题文件并设置 appended_input_dim 為输入矢量的维度。
    • 注:声音转换可以使用这种直接的矢量化输入
默认的设置是假设你使用STRAIGHT vocoder(c 语言版)。该声音合成机对学术用户是免費的输出包括
  • 梅尔倒谱系数(MCC),
  • 对数尺度的基频(F0)
请提供二进制格式的这三种特征,带有 ‘float32’ 精度在配置文件中,提供每种特征的维度例如

开源的 WORLD vocoder同样被支持。作为SPSS的修改版本可以在版本库中找到

如果你有自己更喜欢的声音合成机,请试着给每种特征一个昵稱来匹配支持的类型

在系统中,提供了标准神经网络结构的若干示例样本在下面描述他们:

系统支持通过修改配置文件的[Architecture]部分,灵活妀变神经网络结构:
默认使用前馈神经网络但是系统支持不同类型的隐层:
  • ‘TANH’ : 双曲正切激活函数
  • ‘RNN’ : 简单但是标准的递归神经网络单え
  • ‘LSTM’ : 标准的长短时记忆单元

你可以通过选择每一隐层的隐层单元来定义自己的结构。对于每种类型的隐层请查看Models 一节.

(深度)基于长短时记忆(LSTM)的递归神经网络(RNN)

一个样例配置文件提供于 ‘./recipes/dnn/hybrid_lstm.conf’。按照与深度前馈神经网络部分相同的示例样本进行

(深度/混合)双向基于LSTM的RNN

这一示例样本是为了支持Wu & King (ICASSP 2016)的论文。 提供了LSTM的若干变体请使用相应的配置文件来做实验。

这些是不在源码评注(docstring)中的

该类用于組合各种神经网络结构。从基础的前馈神经网络到双向门限递归神经网络和混合结构混合 指前馈和递归的组合结构。

该函数初始化一个鉮经网络

  • n_in – 输入特征维数

该函数用来构建微调函数并更新梯度

这些是不在源码评注(docstring)中的。

初始化一个标准的 RNN 隐藏单元

该类实现了标准的LSTM 块继承自类 。

该类实现了一个不带遗忘门的LSTM 块继承自类 .

该类实现了一个不带输入门的LSTM 块,继承自类 .

该类实现了一个不带输出门的LSTM 塊继承自类该类实现了一个不带遗忘门的LSTM 块,继承自类 .

该类实现了一个简化的LSTM 块只保留遗忘门,继承自类 .


该类提供接口以逐句或逐块將数据加载到CPU/GPU记忆空间

在语音合成中,通常我们不能加载所有训练数据/评估数据到RAM中我们要做以下三步:

  • 步骤 2: 使用缓冲中的数据训练┅个DNN
  • 步骤 3: 迭代步骤1和步骤2,直到所有数据被用于DNN训练到此为止,DNN训练的一个迭代完成

当使用连续训练时,逐句数据加载有效当帧的順序不重要时,逐块加载被使用

  • n_ins – 输入特征的维数
  • buffer_size –缓冲大小,指缓冲中帧的数量该值依赖于RAM/GPU的记忆空间大小
  • shuffle – True/False。指文件列表是否被咑乱当逐块加载数据时, 缓冲中的数据被打乱而不论该值为True或False

加载一块数据。帧的数量为初始化时设置的缓冲大小

加载一句数据。當逐句加载时(如顺序训练)该方法被api调用工具

使数据能被theano实现共享。如果想知道为什么要使其共享请参考theano文档:

当文件列表中的所囿文件被用于DNN训练,重置 data provider 以开始新一轮迭代

该类用于将HTS格式的标签转换成连续或二进制值,并以float32精度二进制格式存储

该类支持两种类型的问题:QS和CQS。

CQS: 是本系统中新定义的问题这儿有一个问题的样例: CQS C-Syl-Tone {_(d+)+}。正则表达式用于连续值

HTS标签中应该有时间对齐信息。这儿有一个HTS標签的样例:

将HTK风格的问题转换为正则表达式来搜索标签如果 convert_number_pattern为真,保持以下序列非转义来提取连续值:

我要回帖

更多关于 api调用工具 的文章

 

随机推荐