TTS 是 Text-to-Speech 的缩写,译为语言合成。目前的语音合成技术都是端对端训练的。课程大纲会先讲在深度学习流行之前,业界是怎么做的,再讲我们要怎样控制 TTS 来合成出我们想要的声音
语音合成最早能找到的资料在1939年。VODER 是一个在美国世博会上展示的语音合成系统。当时的语音合成像电子琴。通过操控琴键去合出不同的声音
在1960年代,Johb 在贝尔实验室,用一台 IBM 的电脑,合成出了语音。链接点进去可以试听。它听起来像是机器人的声音。唱歌的时候像是鬼畜。现在的语音合成声音都太真实了,没有还原机器人声音的感觉。有时候,我们会特地让合成的人声不那么真实,以防用户听起来难辨真假,造成恐怖谷效应
Concatenative 方法是过去最常用的语音合成技术。它的思路很直观,直接构建一个庞大的声音数据库。比如想合成“你好吗”,就从数据库中挑出“你”,“好“,”吗”三个字的声音,然后拼接在一起。如果单纯地串起来,有时候会听起来很不自然。所以很多研究都集中在解决怎么挑选出能拼接起来听得自然的语音片段。目前很多网络上可以把政治人物的声音一个个截取下来,然后重新拼接,就可以让他说出他从来没有讲过的话。这个方法的主要局限在合成声音不够丰富。因为它无法合成语音数据量中没有的,某个特定人的声音
后来有人用机器学习的方法,比如 HMM 和 神经网络 来做语音合成系统。如果用 HMM 筛选出每个 STATE 概率最高的语音,通常都是同一段语音。它们也不是端对端的,而是参数化的方法,非常复杂
在端对端的语音合成模型之前,有一个模型叫 Deep Voice 很接近端对端了。它的中间有很多 Modules ,把它们串起来,就可以把文字转换成声音信号。Grapheme-to-phoneme 会把给定文字,去猜测它的发音。发音的结果会输入给另外两个模块,一个是用来判断每一个发音的长度应该是多少,另一个是用来判断每一个发音的音高应该是多少。而且有一些音素,人是不发声的。这个模块也会考虑决定把那些不发声的音素给标记上。有了音素,每个音素的发音时常和它们要不要发声,发声的音高多高,就可以都输入给合成模块获得声音。所有的这些模块都是基于深度学习的,串起来就是端对端的了。Deep Voice 第三代它被改进成了端对端
Tacotron 是一种端对端的语音合成系统。Taco 的意思是一种墨西哥卷饼,加上 tron 是为了增加它的科技感。之前它的名字本来叫作 Talktron,由于作者喜欢吃墨西哥卷饼,Talktron 又与 Tacontron 谐音,所以取了这个名字
Spectrogram 与 Wave 波形只差了一个相位的信息。二者的转换不需要特别强的编码器,用线性映射的或基于模板的方法都可以互相转换。Tacontron 的输入是字符,输出是声音频谱。之前有人做过输入是 phoneme 输出是声学特征向量的,端对端的 TTS 模型。STRAIGHT 的意思是,这些声学特征向量需要丢入一个特殊的 Vocoder 才能输出声音信号。也有人做过 Char2wav,输入是字,输出是 SampleRNN 的声学特征向量。这其中,只有 Tacotron 的方式是最一步到位的
Tacotron 用的是一个典型的 Seq2Seq + Attention 的模型架构。它输出还会有个后处理才产生声音频谱
先看它的编码器,目标是把字符转换成音素,告诉接下来的注意力模块,这些字符应该要怎么发音。编码器的输入之间是字母加上标点符号。加上标点符号能够帮助模型学到语气和说话之间的停顿。这些字符会以嵌入的形式输入给一个由几个全连接层组成的 Pre-net ,再通过一个 CBHG 的模块。模块架构比较复杂,架构如图左所示。这部分在 Tacotron 的第二个版本得到改进,变成了 3 层卷积和一个 BiLSTM
接下来注意力层部分,会选择对哪些音素嵌入做更多侧重。它的可视化会和之前的语音识别 LAS 中的注意力可视化一致,会形成一条对角线。在注意力矩阵上,纵轴代表的是编码器的输出,横轴代表的是来自编码器的每一个嵌入会输出几个时长步。注意力矩阵可视化展现出的是模型对每个音素的持续时长的建模方式,即编码器吐出的每一个音素,解码器要把它变成多长的声音信号
解码器的输入是经过注意后的音素嵌入,输出是声音信号。在 Tacotron 中,解码器有个特别的地方在,它不是一次只产生一个 Mel-Spectrogram 向量,而是产生好几个。产生的数目叫作 r frams。Tacotron 的第一版中,r 可以是3或5。为什么要让它一次产生多个向量呢?因为声音信号非常长,而解码器每个时间步生成的声音又非常的短。为了让产生的速度更快,我们允许模型一次多产生几个频谱向量。在第二版的 Tacotron 中,r 被设为了1。当输出是多个向量时,我们可以把它们串起来当作下一个 RNN 的输入,也可以把最后那个向量当作下一个 RNN 的输入。我们需要 dropout 来防止过拟合。和语音识别类似,我们也要使用 teacher forcing 的技术来训练。虽然我们在训练的时候输出的是正确答案,但 Pre-net 中的某些 Dropout 可以模拟在测试的时候,RNN出错的情景
此外,我们还需要一个额外的模块来决定什么时候结束。一般是让它生成一个特定的向量,一旦遇到这个特定的向量,模型就自动结束。这个额外的模块其实是一个分类器。它的输入是 RNN 的最后一个隐层和Cell,输出是一个 [0,1] 的数值,代表是否要结束的概率
输出的频谱向量,还会经过一个后处理模块。这个模块也是一个 CBHG (v1) 或 3xConv (v2)。它会把解码器输出的全部向量当作输入,然后再输出另外一排向量。为什么要多这一步操作呢?因为 RNN 输出的这些向量是按顺序产生的,它只能通过前面产生的向量来产生后面的向量。有可能中途有遇到问题,想要再去改,却没有机会了。这个后处理的目标就是为了修正这些中途可能遇到的问题。训练的时候,有两个训练损失。我们希望 RNN 的输出与标签的 Mel-spectrogram 越接近越好。同时我们也希望 RNN 的输出,通过 CBHG 之后,也要和 Mel-spectrogram 越接近越好。两个损失是同时减小的。最后的 Mel-spectrogram 会被丢到一个 Vocoder 中,变成波形的声音信号。第一代 Tacotron 中,它用的是一个基于规则的 Vocoder,但到了第二代,它变成了一个 Wavenet
Tacotron 的结果表现如何呢?我们通常会使用一个 mean opinion score 来评估生成的语音质量。它的计算是通过找一群人,让他们听声音,给分数一个 1-5 的分数。第一代的 Tacotron 评分在 3.82,但第二代已经是 4.53 了。这个已经非常接近 Ground truth
是什么贡献了让第二代 Tacotron 变得这么好呢?主要在于它把 Vocoder 换成了 WaveNet。而且 WaveNet 是需要数据学出来的。用什么样的数据去做训练,是会影响到我们的结果。如果我们今天用 Ground Truth 的数据去训练 WaveNet,但是给它合成出来的频谱。结果却只有 4.3 分。但如果我们用合成出来的声音去训练 WaveNet,测试的时候也是合成的频谱。结果会比之前的好0.2分
在训练 Tacotron 的时候,还有一个非常有趣的问题。它在测试的时候也需要用 Dropout。这和以往的 dropout 用法截然不同。这里 (43:37) 可以听二者的比较。测试不用 Dropout,出来的声音是坏掉的。为什么会这样呢?目前还没有非常好的解释。在用 GPT-2生成句子的时候,其实也有类似的问题。如果你每次都让 GPT-2 生成概率最大的那个词汇,它就会陷入一个奇怪的循环。它会不断地跳帧,不断地产生重复的词。所以我们需要让 GPT-2 产生一些随机文章的时候,需要让它具备一定的随机性,即用分布采样得到输出的词汇。这样其它概率的词也有机会生成出来。由此我们可以推断,Tacotron 需要在测试用 Dropout 的理由也是这样的。Dropout 能让 Tacotron 在生成新语音频谱的时候,考虑一些随机性。不然它就会像 GPT-2 那样陷入重复循环
博主,请问你听的什么课呀?可不可以推一下系统学习ASR的 比心!