应用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 riphones1 -l * -i .labelswintri.mlf mktri.led .labelsaligned.mlf

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

 

文件名:mktri.led

WB sp

WB sil

TC

 

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

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

HHEd -H .hmmshmm9macros -H .hmmshmm9hmmdefs -M .hmmshmm10 mktri.hed .listsmonophones1

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

perl .scriptsmaketrihed .listsmonophones1 .lists riphones1

修改mktri.hed文件,把第一行的.lists riphones1改成./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 .configconfig1 -I .labelswintri.mlf -t 250.0 150.0 1000.0 -S train.scp -H .hmmshmm10macros -H .hmmshmm10hmmdefs -M .hmmshmm11 .lists riphones1

HERest -C .configconfig1 -I .labelswintri.mlf -t 250.0 150.0 1000.0 -s stats -S train.scp -H .hmmshmm11macros -H .hmmshmm11hmmdefs -M .hmmshmm12 .lists riphones1

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

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 .hmmshmm12macros -H .hmmshmm12hmmdefs -S test.scp -l * -i recout_step9.mlf -w wdnet -p 0.0 -s 5.0 .dictdict2 .lists riphones1

暂时未通过,报错:

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

 FATAL ERROR - Terminating program HVite

config2config1基础上加入FORCECXTEXP=TALLOWXWRDEXP=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 .hmmshmm12macros -H .hmmshmm12hmmdefs -S test.scp -l * -i . esults ecout_step9.mlf -w wdnet -p 0.0 -s 5.0 .dictdict4 .lists riphones1

dict4字典如下所示:

 

文件名:.dictdict4

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 estwords.mlf .listsmonophones1 . esults ecout_step9.mlf

所得结果如下:

 

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

  Date: Mon Oct 30 22:45:31 2006

  Ref : .labels estwords.mlf

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

perl .scriptsmakedict.pl .dictdict2 .dictdict4 .lists riphones1

 

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

 

[step 10]绑定三音素

 

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

HHEd -H .hmmshmm12macros -H .hmmshmm12hmmdefs -M .hmmshmm13 tree.hed .lists riphones1 > log

 

上面的tree.hedperl脚本mkclscript.prl (.scripts目录下)生成:

perl mkclscript.prl TB 350.0 .listsmonophones1>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 .listsfulllist -g global2.ded -l flog .dicteep-tri .dicteep

其中,文件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,对于其他没模型的三音素也这样处理。我们这里不用这个路子,因为工作量太大了一点点。我们走第二条路,这条路在htkmaillist中有人提到过,详见2006424的一封信,作者是Moustafa Nabil。这条路不用beep字典,而使用我们制作的任务字典。我们对dict2进行修改,另存为dict5,其中去掉了下述两项:

SENT-END    []     sil

SENT-START []     sil

执行HDMan生成fulllist

HDMan -b sp -n .listsfulllist -g global3.ded -l flog .dictdict5-tri .dictdict5

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

 

文件名:global3.ded

RS cmu

MP sil sil sp

TC

 

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

HERest -C .configconfig1 -I .labelswintri.mlf -t 250.0 150.0 1000.0 -S train.scp -H .hmmshmm13macros -H .hmmshmm13hmmdefs -M .hmmshmm14 .lists iedlist

出现如下错误:

  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 .configconfig1 -I .labelswintri.mlf -t 250.0 150.0 1000.0 -S train.scp -H .hmmshmm14macros -H .hmmshmm14hmmdefs -M .hmmshmm15 .lists iedlist

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

原文地址:https://www.cnblogs.com/welen/p/3781894.html