应用HTK搭建语音拨号系统3:创建绑定状态的三音素HMM模型

选自:http://maotong.blog.hexun.com/6261873_d.html

苏统华

哈尔滨工业大学人工智能研究室

2006年10月30日

声明:版权所有,转载请注明作者和来源

该系统能够识别连续说出的数字串和若干组姓名。建模是针对子词(sub-word, eg. 音素),具有一定的可扩充性。当加入一个新名字时,只需修改发音词典和任务语法即可。模型为连续混合高斯输出,运用语音决策树聚类形成的绑定状态式三音素。

3. 创建绑定状态的三音素HMM模型

目的是加入上下文依赖(context-dependent)三音素模型并得到稳健的训练。包括两步,先由单音素得到三音素并重估参数,第二步就是绑定三音素的状态以使输出分布更加稳健。

[step 9]得到三音素HMM

上下文依赖三音素模型可以用单音素作为初始,再进行重估。由于重估时要三音素级标注文本,就先生成标注文本。

HLEd -n .\lists\triphones1 -l * -i .\labels\wintri.mlf mktri.led .\labels\aligned.mlf

编辑脚本mktri.led包括如下命令:

文件名:mktri.led

WB sp

WB sil

TC

其中文件wintri.mlf是由单音素标注文本文件aligned.mlf转换成的等价三音素标注文本。一个三音素的列表保存到了triphones1。

下面利用HMM编辑器初始化三音素模型。所用命令为:

HHEd -H .\hmms\hmm9\macros -H .\hmms\hmm9\hmmdefs -M .\hmms\hmm10 mktri.hed .\lists\monophones1

其中的mktri.hed文件由perl脚本生成:

perl .\scripts\maketrihed .\lists\monophones1 .\lists\triphones1

修改mktri.hed文件,把第一行的.\lists\triphones1改成./lists/triphones1。

运行HHEd得到如下警告,没有大碍的:

WARNING [-2631]  ApplyTie: Macro T_sp has nothing to tie of type t in HHEd

WARNING [-2631]  ApplyTie: Macro T_sil has nothing to tie of type t in HHEd

重估两次:

HERest -C .\config\config1 -I .\labels\wintri.mlf -t 250.0 150.0 1000.0 -S train.scp -H .\hmms\hmm10\macros -H .\hmms\hmm10\hmmdefs -M .\hmms\hmm11 .\lists\triphones1

HERest -C .\config\config1 -I .\labels\wintri.mlf -t 250.0 150.0 1000.0 -s stats -S train.scp -H .\hmms\hmm11\macros -H .\hmms\hmm11\hmmdefs -M .\hmms\hmm12 .\lists\triphones1

两次均会有如下警告,不用理会:

Pruning-On[250.0 150.0 1000.0]

WARNING [-2331]  UpdateModels: ax-n[7] copied: only 1 egs in HERest

WARNING [-2331]  UpdateModels: l-y+ax[26] copied: only 1 egs in HERest

WARNING [-2331]  UpdateModels: y-ax+n[39] copied: only 1 egs in HERest

WARNING [-2331]  UpdateModels: uw-l+y[43] copied: only 1 egs in HERest

试着执行一下识别任务,看看怎么样:

HVite -H .\hmms\hmm12\macros -H .\hmms\hmm12\hmmdefs -S test.scp -l * -i recout_step9.mlf -w wdnet -p 0.0 -s 5.0 .\dict\dict2 .\lists\triphones1

暂时未通过,报错:

ERROR [+8231]  GetHCIModel: Cannot find hmm [y-]uw[+???]

FATAL ERROR - Terminating program HVite

令config2在config1基础上加入FORCECXTEXP=T,ALLOWXWRDEXP=F,仍没有改善。通过分析dict2,发现y-uw+?出现在单词SUE的第二种发音上。注释掉这一行,仍然报错,但跟上次的错误有了可喜的差别:

ERROR [+8231]  GetHCIModel: Cannot find hmm [ao-]r[+???]

FATAL ERROR - Terminating program HVite

看来路子是对的。ao-r+?出现在单词FOUR的第二种发音上,再次注释掉,把进行了如上两行注释的字典存为dict4。重新运行HVite,不再出错:

HVite -H .\hmms\hmm12\macros -H .\hmms\hmm12\hmmdefs -S test.scp -l * -i .\results\recout_step9.mlf -w wdnet -p 0.0 -s 5.0 .\dict\dict4 .\lists\triphones1

dict4字典如下所示:

文件名:.\dict\dict4

CALL            k ao l sp

DAVE            d ey v sp

DIAL            d ay ax l sp

EIGHT           ey t sp

FIVE            f ay v sp

FOUR            f ao sp

#FOUR            f ao r sp

JULIAN          jh uw l ia n sp

JULIAN          jh uw l y ax n sp

LAW             l ao sp

LEE             l iy sp

NINE            n ay n sp

OH              ow sp

ONE             w ah n sp

PHIL            f ih l sp

PHONE           f ow n sp

SENT-END    []  sil

SENT-START  []  sil

SEVEN           s eh v n sp

SIX             s ih k s sp

STEVE           s t iy v sp

SUE             s uw sp

#SUE             s y uw sp

THREE           th r iy sp

TWO             t uw sp

TYLER           t ay l ax sp

WOOD            w uh d sp

YOUNG           y ah ng sp

ZERO            z ia r ow sp

进行识别验证:

HResults -I .\labels\testwords.mlf .\lists\monophones1 .\results\recout_step9.mlf

所得结果如下:

====================== HTK Results Analysis =======================

Date: Mon Oct 30 22:45:31 2006

Ref : .\labels\testwords.mlf

Rec : .\results\recout_step9.mlf

------------------------ Overall Results --------------------------

SENT: %Correct=93.33 [H=14, S=1, N=15]

WORD: %Corr=100.00, Acc=97.06 [H=68, D=0, S=0, I=2, N=68]

==============================================================

可以看出,基于三音素的HMM比基于单音素的HMM有较大的性能提升。

我们进一步进行讨论dict4的由来。由于在step 8中对标记文本和语音数据进行了校准,对于象FOUR,SUE这样有多个发音的单词,在Vitebi算法的作用下,会选择最大化似然率的单词,而不是象step 4那样选择第一种读音。结果使dict2中的发音在扩展成三音素时在音素级真值文本中没有实例,当然也就找不到该三音素的HMM模型。这时会报错。根据这个原理,可以编一个Perl脚本自动对字典中没用到的单词注释掉。我把这个脚本命名为makedict.pl,包含在scripts文件夹里。它可以代替上面的手工注释工作,使用下面的命令可以得到dict4:

perl .\scripts\makedict.pl .\dict\dict2 .\dict\dict4 .\lists\triphones1

注8:hmm11下的模型文件并没有包含在压缩包里。

[step 10]绑定三音素

在上一步估计模型时,因数据不足导致很多分布的方差只好用截至方差vFloors。这一步就是通过绑定状态来共享数据,使输出分布更加的稳健。HHEd提供两种聚类状态的机制,这里采用的是决策树:

HHEd -H .\hmms\hmm12\macros -H .\hmms\hmm12\hmmdefs -M .\hmms\hmm13 tree.hed .\lists\triphones1 > log

上面的tree.hed用perl脚本mkclscript.prl (.\scripts\目录下)生成:

perl mkclscript.prl TB 350.0 .\lists\monophones1>tree.hed

这时候的tree.hed的内容:

文件名:中间tree.hed

TB 350 "k_s2" {("k","*-k+*","k+*","*-k").state[2]}

TB 350 "ao_s2" {("ao","*-ao+*","ao+*","*-ao").state[2]}

……

TB 350 "z_s4" {("z","*-z+*","z+*","*-z").state[4]}

还要往tree.hed中插入问题集和trace等信息。最终形式如下:

文件名:最终tree.hed

RO 100.0 stats

TR 0

QS  "R_NonBoundary" { *+* }

……

QS  "L_z"            { z-* }

TR 2

TB 350 "k_s2" {("k","*-k+*","k+*","*-k").state[2]}

TB 350 "ao_s2" {("ao","*-ao+*","ao+*","*-ao").state[2]}

……

TB 350 "z_s4" {("z","*-z+*","z+*","*-z").state[4]}

TR 1

ST trees

CO ./lists/tiedlist

AU ./lists/fulllist

在tree.hed中,tiedlist是绑定后的不同三音素列表。fulllist是输入参数,代表绑定前的所有三音素列表,所以要事先制作。HTK book的制作方法:

HDMan -b sp -n .\lists\fulllist -g global2.ded -l flog .\dict\beep-tri .\dict\beep

其中,文件global2.ded是在global.ded基础上加入了TC命令:

文件名:global2.ded

AS sp

RS cmu

MP sil sil sp

TC

HDMan这里所做的工作包括1)按照global.ded的配置把beep字典中的发音扩展成(词内)三音素形式,保存到beep-tri字典;2)提取beep-tri中出现的所有不同三音素保存到fulllist列表中。但是你会发现,按照上述方式制作的fulllist在执行HHEd时会引发错误,下面是我得到的一个例子:

ERROR [+2662]  FindProtoModel: no proto for k-b+l in hSet

FATAL ERROR - Terminating program HHEd

这是什么原因呢?其实上面错误提示中的k-b+l并没在我们的演示任务中出现。正因为没出现,所以HMM模型文件里没它的位置。要解决这个错误,有两种解决途径。第一个路子,既然提示模型文件里没有三音素的模型,那就给它制作一个。可以把单音素*-b+*的模型复制一份给k-b+l,对于其他没模型的三音素也这样处理。我们这里不用这个路子,因为工作量太大了一点点。我们走第二条路,这条路在htk的maillist中有人提到过,详见2006年4月24日的一封信,作者是Moustafa Nabil。这条路不用beep字典,而使用我们制作的任务字典。我们对dict2进行修改,另存为dict5,其中去掉了下述两项:

SENT-END    []     sil

SENT-START []     sil

执行HDMan生成fulllist:

HDMan -b sp -n .\lists\fulllist -g global3.ded -l flog .\dict\dict5-tri .\dict\dict5

上面的global3.ded是在global2.ded基础上去掉了AS sp一行,因为dict5中的每一单词发音后已经存在sp了。文件global3.ded的内容如下:

文件名:global3.ded

RS cmu

MP sil sil sp

TC

重新执行HHEd,不会再出错了。我们重估两次:

HERest -C .\config\config1 -I .\labels\wintri.mlf -t 250.0 150.0 1000.0 -S train.scp -H .\hmms\hmm13\macros -H .\hmms\hmm13\hmmdefs -M .\hmms\hmm14 .\lists\tiedlist

出现如下错误:

ERROR [+5010]  InitSource: Cannot open source file sil

ERROR [+7010]  LoadHMMSet: Can't find file

ERROR [+2321]  Initialise: LoadHMMSet failed

FATAL ERROR - Terminating program HERest

在fulllist中加入sil。重新运行HHEd一次,这时的HERest只有一个警告:

Pruning-On[250.0 150.0 1000.0]

WARNING [-2331]  UpdateModels: ax-n[7] copied: only 1 egs in HERest

再重估一次:

HERest -C .\config\config1 -I .\labels\wintri.mlf -t 250.0 150.0 1000.0 -S train.scp -H .\hmms\hmm14\macros -H .\hmms\hmm14\hmmdefs -M .\hmms\hmm15 .\lists\tiedlist

这次的警告与上次相同,没有关系的。

上一篇:应用HTK搭建语音拨号系统4: 识别器评估


下一篇:【2016-10-17】【坚持学习】【Day8】【工厂方法模式】