WinHTK开发与使用三:连续语音识别
本文接上文,介绍连续语音识别系统设计过程,演示视频见下载资源中。
二、连续语音识别系统设计
上面讨论了一个简单的十个孤立数字识别系统的设计过程,可以看出比较简单,效果也非常好。下面将设计一连续语音识别系统,相比较于孤立词识别而言,它有很多不同的地方,且过程也比较繁琐复杂,识别效果并不是非常好(当然这是有很多原因的)。为了便于实现,识别任务主要是:识别一些简单的文档操作命令,比如复制,粘贴,删除等等。具体见语法约束中的描述。整个设计过程也分为四步。
1、数据准备
(1) 任务语法描述。这个系统识别任务为一些常见的文本编辑命令,具体包括43条语句,50个词汇。根据语法约束文件的格式描述语法,其对应的gram文件内容如下:
#选择命令
$ydir=(shang4 yi2)|(xia4 yi2);
$xdir=(qian2 yi2 ge4)|(hou4 yi2 ge4);
$selchar=xuan3 ze2 $xdir zi4;
$lp=hang2|ye4;
$sellp=xuan3 ze2 $ydir $lp;
$selcmd=$selchar|$sellp;
#删除,复制,粘贴,插入命令
$var=zi4|hang2|ye4;
$delcmd=shan1 chu2 xuan3 ze2 $var;
$copcmd=fu4 zhi4 xuan3 ze2 $var;
$pascmd=zhan1 tie1 xuan3 ze2 $var;
$inscmd=cha1 ru4 xuan3 ze2 $var;
#取消和重做命令
$cmd=(xuan3 ze2)|(shan1 chu2)|(fu4 zhi4)|(zhan1 tie1)|(cha1 ru4);
$cancmd=qu3 xiao1 $cmd;
$redo=chong2 zuo4 $cmd;
#查看命令
$view=((fang4 da4)|(suo1 xiao3)) cha2 kan4;
#翻页命令
$digit=yi1|er4|san1|si4|wu3|liu4|qi1|ba1|jiu3|shi2;
$gtpage=zhuan3 dao4 di4 $digit ye4;
#标记命令
$mark=(shi2 jian1)|(ye4 ma3)|(suo3 yin3);
$addcmd=tian1 jia1 $mark;
(sil($selcmd|$cancmd|$delcmd|$copcmd|$pascmd|$inscmd|$view|$gtpage|$addcmd) sil)
然后利用HParse工具转化成对应的SLF文件network.slf。其FSN形式由于比较复杂,故不列出。
(2) 词典准备。由于采用音素作为建模单元,因此需要给出发音词典。词典文件dict如下,共50个词汇(包含静音),为节省空间,分栏列出。实际要准备两个,一个有短暂停顿sp结尾和无sp结尾的词典,词典中的词必须按字母序排列好:
ba1 b a1 sp
cha1 ch a1 sp
cha2 ch a2 sp
… … … …
chong2 ch ong2 sp
… … … …
因为要转化成汉语输出,还需要转换文件translate,其功能是将发音输出转换成汉语输出。
(3) 语音录制。录制训语音样本,一共172条句子,对应43条语句,即每条语句说四遍,其中43条用于测试。采样速率为11.025khz,16位单通道采样。对应语句标注如下:
*\train*--01.wav:xuan3 ze2 shang4 yi2 hang2
*\train*--02.wav:xuan3 ze2 shang4 yi2 ye4
*\train*--03.wav:xuan3 ze2 xia4 yi2 hang2
… … … … …
*\train*--41.wav:tian1 jia1 shi2 jian1
*\train*--42.wav:tian1 jia1 ye4 ma3
*\train*--43.wav:tian1 jia1 suo3 yin3
(4) 数据标注。本系统采用flat start方式训练,也即连接词方式训练,不需要标注的边界信息,只需要给出相应的标注即可。因此语音文件的标注可以将上述文件通过WINHTK中的工具直接转换成MLF文件获得。由于MLF文件与上基本类似,故不列出。
(5) 编码数据。编码方案为:20ms汉明窗,10ms的帧移。采用12阶MFCC特征参数,能量参数,一阶,二阶动态参数,共39个系数。对应参数文件code.cfg内容如下:
SOURCEFORMAT=WAV
TARGETFORMAT=HTK
SOURCEKIND=WAVEFORM
TARGETKIND=MFCC_E_D_A
ZMEANSOURCE=T
USEHAMMING=T
PREEMCORF=0.97
SOURCERATE=907
TARGETRATE=100000
WINDOWSIZE=200000
NUMCHANS=26
NUMCEPS=12
CEPLIFTER=22
由于静音也被当做语音进行建模,故不需要进行端点检测,因此这个参数文件相比较孤立词的要简单一些。
2、模型训练
基于HTK的连续语音识别模型训练有两种方式:boot-strap和flat start两种。boot-strap是指首先进行孤立词方式设置模型参数,然后再进行模型参数重估,其过程如图1所示,这种方式需要手工标注语音文件,即需要边界信息;flat start方式则是首先采用全局均值和协方差设置模型参数,然后再进行模型参数重估,其过程如图2所示,对应的标签文件不需要边界信息。前者过程比较复杂,因此在这里采用第二种方
图1 boot-strap方式训练过程
图2 flat start方式训练过程
式训练模型。另外在利用HERest进行HMM嵌入式重估过程中,经常需要不断修改HMM,再进行训练,这个过程往往需要重复多次,如图3所示。具体过程如下所述:
图3 重估过程示意图
(1) 创建monophones
1) 首先将词层标签转换成音子层标签,利用HLed工具,调用形式:
HLed -i phone.mlf -l * -d dict edit.led word.mlf
输出音子层标签phone.mlf。其中dict为发音词典,这里用的词典是无sp结尾。word.mlf为词层标签,edit.led为其编辑文件,内容如下:
SO
EX
IS sil sil
2) 然后准备一个HMM模型定义文件hmm0,形式如下:
~o <VecSize> 39 <MFCC_E_D_A>
<StreamInfo>3 13 13 13
~h "1hmm0"
<BeginHMM>
<NumStates> 5
<State> 2
<Stream> 1
<Mean> 13
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
<Variance> 13
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
… … …
<Stream> 3
… … …
… … … …
<State> 4
… … …
<TransP> 5
0.6 0.4 0.0 0.0
0.2 0.4 0.4 0.0
0.0 0.3 0.4 0.3
0.0 0.0 0.6 0.4
0.0 0.0 0.0 0.0
<EndHMM>
并利用HCompV工具对模型进行初始化,调用形式:
HCompV -m -S train.scp -M newhmm -o hmm1 hmm0
输出设置参数后的HMM定义文件hmm1。其中train.scp为所有的训练文件列表,newhmm为输出HMM定义文件目录,hmm0为输入HMM原型定义文件。
3) 然后根据音子模型列表,利用WINHTK工具复制创建一系列HMM集,称为monophone。
4) 接下来,用HERest对这些monophone进行训练。调用形式:
HErest -M newhmm -S train.acp -H hmm1 monophone.lst
其中monophone.lst为HMM集列表,hmm1为输出hmm定义文件,newhmm为输出目录,train.scp为训练文件列表。连续进行两次。最后获得hmm3。
5) 考虑停顿sp,修改sil模型。在这一步,首先,利用sil模型获取sp模型,sp
取三个状态,第二个状态对应sil的第三个状态。相应的HMM定义编辑文件edit.hed文件如下:
AT 2 4 0.2 {sil.transP}
AT 4 2 0.2 {sil.transP}
AT 1 3 0.3 {sp.transP}
TI silsp {sil.state[3],sp.state[2]}
在后面使用带sp的词典获取音子层标签再用于后面的训练。
6) 模型训练,使用带sp的标签进行模型训练,连续两次,同步骤4。最后获得HMM定义文件hmm6。
(2) 创建triphones
1) 将训练monophone时的上下文无关标签转换成triphone模型相对应的上下文相关标签,edit.led内容如下:
SO
WB sp
WB sil
TC
2) 利用上面获得monophone模型通过克隆产生triphone音子模型集,同时进行转移概率绑定。相应的HMM定义编辑文件edit.hed文件内容为:
CL triphonelist
TI tie_a1 {(*-a1+*,a1+*,*-x).transP}
TI tie_a2 {(*-a2+*,a2+*,*-x).transP}
TI tie_a3 {(*-a3+*,a3+*,*-x).transP}
… … … … … … … … …
3) 对triphone进行两次训练,最后获得HMM定义文件hmm9。
(3) 创建 tied-state triphones
1) 对triphone模型进行数据驱动方式的状态绑定,相应的HMM定义编辑文件edit.hed内容如下:
RO 3 stats
TC 100 tc_a12 {(*-a1+*,a1+*,*-a1).state[2]}
TC 100 tc_a13 {(*-a1+*,a1+*,*-a1).state[3]}
TC 100 tc_a14 {(*-a1+*,a1+*,*-a1).state[4]}
TC 100 tc_a22 {(*-a2+*,a2+*,*-a2).state[2]}
… … … …
2) 对绑定后的tied-state triphone HMM利用训练数据进行两次模型训练,最终获得HMM定义文件hmm12。
3、识别测试
下面利用HVite工具进行识别,其调用形式如下:
HVite –H hmm12 –S test.scp –l * -i rec.mlf -w network.slf dict triphonelist
rec.mlf为识别输出标注MLF文件。其中network.slf文件为语法约束转换成FSN的SLF文件,hmm12为训练得到的模型集,triphonelist为相应的HMM列表。Dict为发音词典文件。test.scp中列出训练文件。
4、识别效果分析
最后,利用HResults工具进行识别效果分析,其调用形式如下:
HResults -A -T 0002 -n -L * -I trans triphonelist rec.mlf
其中trans为参考标准文件,triphonelist为triphone列表,rec.mlf为识别输出的标准文件。分析结果为:
====================== HTK Results Analysis =======================
Date: Thu May 21 20:24:58 2009
Ref : trans
Rec : rec.mlf
------------------------ Overall Results --------------------------
SENT: %Correct=72.09 [H=31, S=12, N=43]
WORD: %Corr=88.12, Acc=84.65 [H=178, D=2, S=22, I=7, N=202]
===================================================================
从上可以看出识别效果并不是很好,句子的正确识别率仅为72.09%,词的正确识别率为88.12%。其主要原因是训练样本不足,另外就是HMM结构没有优化所致。有充分的训练样本的,训练好的模型在录音较好的环境下,百条语句的识别率可以上95%。