HMM训练

1 合成基元以及其状态数量的选择

如何选取合成基元

对于汉语语音系统而言,常用的基本基元有音节、声韵母和音素。由于汉语有410个无调音节,如考虑语调则有1300多个音节(具体数量上不同词典的标准都不相同,这里取约数),在进行上下文无关的建模时,选用音节作为基元可以取得比较好的性能。[todo 可以试一下使用音节来作为合成单元,看看合成效果]但如果考虑上下文相关的变化,则会由于基元数目太多而导致模型无法实现。而声韵母(声母21个,韵母todo个)与音素的数目都相对较少,因此可以用来作上下文相关模型的基元。[3]

汉语大概有35个音素,但是音素并没有反映出汉语语音的特点,而且,相对于声韵母,音素显得十分不稳定,这就给标注带来了困难,进而影响声学建模,因此,音素也不适合作为上下文相关的合成基元。[3] 这里的音素单个发音的字母,例如可以将拼音ming分成 m i n g四个音素

这里选取声韵母作为基元,同时为了模拟发音中的停顿,可以将短时停顿和长时停顿看做是合成基元,此外,将句子开始前和结束时的静音sil也当做合成基元

合成基元的列表

本项目选用的合成基元为

  • 声母 | 21个声母+wy(共23个)
  • 韵母 | 39个韵母
  • 静音 | sil pau sp

sil(silence) 表示句首和句尾的静音,pau(pause) 表示由逗号,顿号造成的停顿,句中其他的短停顿为sp(short pause)

声母(23个)
b p m f d t n l g k h j q x zh ch sh r z c s y w
韵母(39个)
  • 单韵母 a、o、e、 ê、i、u、ü、-i(前)、-i(后)、er
  • 复韵母 ai、ei、ao、ou、ia、ie、ua、uo、 üe、iao 、iou、uai、uei
  • 鼻韵母 an、ian、uan、 üan 、en、in、uen、 ün 、ang、iang、uang、eng、ing、ueng、ong、iong
韵母(39个)(转换标注后)
  • 单韵母 a、o、e、ea、i、u、v、ic、ih、er
  • 复韵母 ai、ei、ao、ou、ia、ie、ua、uo、 ve、iao 、iou、uai、uei
  • 鼻韵母 an、ian、uan、 van 、en、in、uen、 vn 、ang、iang、uang、eng、ing、ueng、ong、iong

改进方法——引入零声母

参考自文献[3],但本项目没有采用

[contro] 6个零声母()的引入是为了减少上下文相关的tri-IF数目,这样就可以使得每个音节都是由声母和韵母组成,原先一些只有韵母音节可以被视作是声母和韵母的结构,这样一来,基元就只有 声母-韵母-声母 以及 韵母-声母-韵母 两种结构,而不会出现两个韵母相邻的情况,进而明显减少了上下文相关的基元。[3]

如果这么做的话就是21+6=27个声母,可以将零声母标记成 aa, ee, ii, oo, uu, vv,一是将yw替换,二是将一个韵母组成的音节手动添加上零声母,举例
  • ye,yan,yang(整体认读音节)标注成——ii ie, ii ian, ii iang (ie, ian, iang是真实发音的韵母)
  • ao an ou 熬 安 欧, 标记成 aa ao, aa an, oo ou

基元状态数量的选择

一般我们选择将一个基元分成5个状态。假设每个状态都由一个高斯分布描述,那么总共的高斯分布数量等于上下文相关基元的数目*5,这样数量过多,在训练数据库不是足够大的情况下,很多基元会存在训练不充分的问题。解决的方法是采用参数共享的技术。例如进行状态共享(state Tying)建模,或者混合密度共享(Tied Mixture)建模

上下文基元是否带声调

语音识别中,大多数系统使用的基元时不带有声调的。但在语音合成系统中,我们有两种选择:一是训练中仍采用无声调基元,然后在合成的最后阶段,根据汉语声调的模式调整基音周期,达到合成语调的目的。另一方法是,在训练中即使用带有声调的基元,然后在上下文相关训练时将它们进行状态共享,以降低模型规模,并提供近似合成未知基元的能力。[3]

[todo][contro]直觉上后者合成出来的语音可能更自然,本文选择后者(需要再进行测试评估)

2上下文相关的标注

设计上下文相关标注的规则

上下文相关标注的规则要综合考虑有哪些上下文对当前音素发音的影响,总的来说,需要考虑发音基元及其前后基元的信息,以及发音基元所在的音节、词、韵律词、韵律短语、语句相关的信息。[1]

本项目的上下文相关标注参考了文献[13],其规则见 面向汉语统计参数语音合成的标注生成方法

本项目自行设计了上下文设计规则以及问题集,尽可能保证了设计规则的可扩展性

3 基于决策树的聚类

[tmp]下面主要参考了[2]中的问题集设计

由于采用了大量的三音素结构,HMM模型数量骤增,过多的模型数量使得难以有足够的数据进行训练。决策树通过将模型进行归类很好地解决了这个问题。此外,实际语音合成时可能遇到训练数据中没有出现的基元,基于决策树(Decision Tree)的方法,可以使用那些可见基元的分布来合成在训练数据中不可见的基元。

决策树介绍TODO(可以抄写[2]中的介绍)

[6]

聚类分析就是为了将我们的数据集聚集成为各种不同的类,聚类的原则是根据 数据的相似性,使得类之间的相似性尽量小,同时保证类内的相似性尽量大[35],常 用的聚类方法有K均值法、自组织映射神经网络法等等。决策树的方法起源较早, 早期的方法有CLS (自概念学习系统),后来逐渐发展成了 ID3方法,到现在则 发展成了以C4.5方法为代表的一类能处理连续属性的决策树方法[36]。 本文最终选取了 C4.5方法来建立决策树,构造决策树的方法是采用自顶向下 的递归构造,构造原则如下:若一个训练数据集里面的所有例子都是同一类别的, 我们就将其作为决策树的叶子节点,该类别的标记就是叶子节点的内容;如果训练 数据不属于同一个类,则根据预设的策略来选择其中一个属性,并根据属性的各个 取值将例子集合划分为多个子集合,这样每个子集上的所有例子在该属性上具有同 样的属性值;然后再以此递归处理各个子集[37]。

决策树的学习资料可以参见[todo]

4 问题集的设计

目前笔者设计了未经优化的问题集,后面可以根据决策树的情况进行优化。 * 问题集设计规则和示例 * 完整问题集文件

问题集(Question Set)即是决策树中条件判断的设计。问题集通常很大,由几百个判断条件组成。 一个典型的英文问题集文件(merlin)

问题集的设计依赖于不同语言的语言学知识,而且与上下文标注文件相匹配,改变上下文标注方法也需要相应地改变问题集,对于中文语音合成而言,问题集的设计的规则有:

  • 前前个,前个,当前,下个,下下个声韵母分别是某个合成基元吗,合成基元共有65个(23声母+39韵母+3静音),例如判断是否是元音a QS “LL-a” QS “L-a” QS “C-a” QS “R-a” QS “RR-a”
  • 声母特征划分,例如声母可以划分成塞音,擦音,鼻音,唇音等,声母特征划分24个
  • 韵母特征划分,例如韵母可以划分成单韵母,复合韵母,分别包含aeiouv的韵母,韵母特征划分8个
  • 其他信息划分,词性划分,26个词性; 声调类型,5个; 是否是声母或者韵母或者静音,3个
  • 韵律特征划分,如是否是重音,重音和韵律词/短语的位置数量
  • 位置和数量特征划分

对于三音素模型而言,对于每个划分的特征,都会产生3个判断条件,该音素是否满足条件,它的左音素(声韵母)和右音素(声韵母)是否满足条件,有时会扩展到左左音素和右右音素的情况,这样就有5个问题。其中,每个问题都是以 QS 命令开头,问题集的答案可以有多个,中间以逗号隔开,答案是一个包含通配符的字符串。当问题表达式为真时,该字符串成功匹配标注文件中的某一行标注。格式如:

QS 问题表达式 {答案 1,答案 2,答案 3,……}

QS “LL==Fricative” {f^*,s^*,sh^*,x^*,h^*,lh^*,hy^*,hh^*}

对于3音素上下文相关的基元模型的3个问题,例如: * 判断当前,前接,后接音素/单元是否为擦音 * QS ‘C_Fricative’ * QS ‘L_Fricative’ * QS ‘R_Fricative’

更多示例:

Question 含义
QS “C_a” 当前单元是否为韵母a
QS “L_Fricative” 前接单元是否为擦音
QS “R_Fricative” 后接单元是否为擦音
QS “C_Fricative” 当前单元是否为擦音
QS “C_Stop” 当前单元是否为塞音
QS “C_Nasal” 当前单元是否为鼻音
QS “C_Labial” 当前单元是否为唇音
QS “C_Apieal” 当前单元是否为顶音
QS “C_TypeA” 含有a的韵母
QS “C_TypeE” 含有e的韵母
QS “C_TypeI” 含有i的韵母
QS “C_POS==a” 当前单元是否为形容词
QS “C_Toner==1” 当前单元音调是否为一声

主要参考文献[3][7][24][28]

值得注意的是,merlin中使用的问题集和HTS中有所不同,Merlin中新增加了CQS问题,Merlin处理Questions Set 的模块在merlin/src/frontend/label_normalisation 中的Class HTSLabelNormalisation

Question Set 的格式是
QS + 一个空格 + “question_name” + 任意空格+ {Answer1, answer2, answer3…} # 无论是QS还是CQS的answer中,前后的**不用加,加了也会被去掉 CQS + 一个空格 + “question_name” + 任意空格+ {Answer} #对于CQS,这里只能有一个answer 比如 CQS C-Syl-Tone {_(d+)+} merlin也支持浮点数类型,只需改为CQS C-Syl-Tone {_([d.]+)+}

5 决策树的构建

6 HMM拓扑结构以及声学参数结构

基元状态的拓扑结构

本文选择了从左至右无跳转的HMM拓扑结构,其他结构详见[3]3.1.2节

(begin) 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 (end)

表示可以跳转到自身的状态,1和7分别是起始和结束状态。

声学参数的结构

TODO,可参考[3]

6 建模参数

[6]

在安装Linux的计算机上配置好相关的依赖环境后,我们在训练数据之前,还需要对HMM模型的建模参数进行配置,具体的参数配置如表

表4-2 HMM建模的参数配置表

  • 参数类型 配置情况
  • 声学参数 采用24维梅尔倒谱参数(MFCC)、一维能量以及一维基频参数,加上其对应的一阶差方和二阶差方,一共78维参数;
  • 建摸单元 以声韵母力主要建摸单元,其中包括38个韵母和21个声母和5种声调,同时加入和静音段、长暂停和短暂停;
  • 状态数目 声韵母单元进行统一,都采用5状态的HMM进行建摸;
  • 拓扑结构 采用无跳转的从左至右咅态历经的拓扑结构;
  • 高靳摸型数目 采用的是单高斯摸型;
  • 分巾贞加窗 果用了双明窗(Hamming),巾贞长:呆用25ms;巾贞稳5ms;

对几个重要的参数作如下说明:

  1. 用于语音合成的特征参数其实有很多的选择,其中包括梅尔倒谱参数 (MFCC)、LCP、MCEG等等,最常用的就是本次系统选择的MFCC,该参数能很好的表示语音的声学特征,被广泛应用于语音合成和语音识别的系统搭建,采用 MFCC三阶差方系数也是业内较常用的做法。
  2. 在语音合成的系统中,对HMM建模的状态数目通常会比语音识别采用的数 目要多,HTS对英语的语音合成采用的时3状态的HMM,但是针对于中文,选择 5状态的HMM被证明合成的效果更好。
  3. 由于模型训练是针对单个人的语音训练数据,我们直接选择了单高斯模型。
  4. 为了描述语音信号在短时间的平稳特性,我们采用了汉明窗(Hamming)来 对信号进行加窗分帧,对每帧的语音信号进行特征计算。