用HTK搭建语音识别器实录(TIDigits数据库)
TIDIGITS数据库包含11个孤立数字,分别为one,two,three,four ,five,six,seven,eight,nine,oh,zero.1.数据准备1.1.1 建立任务语法它的任务语法如下:$digit= ( one | two | three | four | five |six | seven | eight | nine | zero | oh );(
TIDIGITS数据库包含11个孤立数字,分别为one,two,three,four ,five,six,seven,eight,nine,oh,zero.
1.数据准备
1.1.1 建立任务语法
它的任务语法如下:
$digit= ( one | two | three | four | five |six | seven | eight | nine | zero | oh );
([sil] <$digit sp> [sil])
将上面内容保存为digit.gram文件
注:|竖线表示可选择。尖括号<>表示一次和多次重复,[]中括号表示:可选择
HTK识别器需要一个用Standard Lattice Format (SLF)建立的词的网络。该网络描述词与词之间的转移。该词的网络可以用Hparse命令进行创建。
Hparsedigit.gram digit.net
其中digit.gram为任务语法,digit.net为生成的词网络。
digit.gram为手工编辑。
1.1.2 建立词典
建立词典之前需要一个词列表,对于简单的任务,可以用用手工的方法建立所需的词列表。这里用手工的方法制作。如下:保存为digitlist文件
one
two
three
four
five
six
seven
eight
nine
zero
oh
sil
sp
注:创建字典之前,需要创建一个词的列表文件,在本实验中,可以很方便的用手工制作这样一个文件。如果任务非常复杂的识别,需要从训练数据的句子中生成词的列表。可以从句子集sentence prompts中建立词列表 word list。
这里以词作为HMM模型,所以发音模型为整词。对于连续语音识别要用音素。
beep文件用手工编写,如下:
eight eight
five five
four four
nine nine
oh oh
one one
seven seven
sil sil
six six
sp sp
three three
two two
zero zero
我在实现的过程中出现错误:
主要原因是beep中的词不是按字母顺序排列,一定要按字母顺序排列,要不然出错。
有了词列表和发音表,就可以生成词典了。用HDMan建立词典。
HDMan -m -w wlist -n monophones1 -l dlog dict beep names
上面命令通过查找词典beep,names,生成wlist每个词的发音,创建了一个名为dict的字典。
Wlist为在任务语法中词的列表。names是手工建的一个文件,包括上面任务语法当中某些名字的发音。可以不用,当beep中的发音不全,即不包含任务语法中所有词的发音,可以手工某些发音。下图为区别,没有names的时候有三个词丢失,找不到发音。
-l选项是是告诉HDman命令生成一个日志文件dlog,它包括生成词典过程中的一些统计数据。HDMan命令还可以生成该过程中用到的发音列表,名为:monophones1,当训练数据和测试数据录好后,就要为monophones1列表的每个音素建立HMM模型。
生成的字典dict.txt内容格式如下:
WORD [outsym] p1 p2 p3 ....
代表的含义:which means that the word WORD is pronounced as the sequence of phones p1 p2 p3 ....
方括号中的词表示识别后输出的结果。如果为空,则输出WORD
当 WORD []时,输出为空。
本实验的词列表为:wlist为词列表。词对应的发音为:beep,生成用到的发音词典。monophones1,这里monophones1与wlist的内容相同,原因是用音节作为模型。后面要为monophones1中对应的发音列表建立模型。
具体命令如下:HDMan -m -w wlist/digitlist –n monophones –l dlog dict/digit.dict
beep
生成文件:digit.dict 其中包含wlist中对应词的发音
monophones 其中包含所有词用到的发音列表,等会要对该文件中的所有列表建立HMM模型。
提供的文件:wlist,词列表。由词网络digit.net生成。 beep发音词典库。
生成的字典digit.dict内容格式如下:
WORD [outsym] p1 p2 p3 ....
代表的含义:which means that the word WORD is pronounced as the sequence of phones p1 p2 p3 ....
方括号中的词表示识别后输出的结果。如果为空,则输出WORD
当 WORD []时,输出为空。
本实验中digit.dict的内容如下:
eight eight
five five
four four
nine nine
oh oh
one one
seven seven
sil sil
six six
sp sp
three three
two two
zero zero
1.1.3 建立特征提取列表文件Wav2Scp
如下格式:
data\train\wav\MAN\AE\1A_endpt.wav data\train\feature\MAN\AE\1A_endpt.mfc
data\train\wav\MAN\AE\1B_endpt.wav data\train\feature\MAN\AE\1B_endpt.mfc
data\train\wav\MAN\AE\2A_endpt.wav data\train\feature\MAN\AE\2A_endpt.mfc
data\train\wav\MAN\AE\2B_endpt.wav data\train\feature\MAN\AE\2B_endpt.mfc
data\train\wav\MAN\AE\3A_endpt.wav data\train\feature\MAN\AE\3A_endpt.mfc
data\train\wav\MAN\AE\3B_endpt.wav data\train\feature\MAN\AE\3B_endpt.mfc
1.1.4 .建立训练数据的标注文件trainwords.mlf
如下
#!MLF!#
"data\train\feature\MAN\AE\1A_endpt.lab"
one
.
"data\train\feature\MAN\AE\1B_endpt.lab"
one
.
然后将trainwords.mlf转换成音素级别的mlf
命令如下:
HLEd -l '*' -d dict/dict.txt -i lists/phones0.mlf edfiles/mkphones0.led lists/trainwords.mlf
其中-l是为了设置路径,dict为词典,-n命令输出所用到的音素.保存在扩展名位mnl的文件名中。phones0.mlf为生成的音素级的MLF文件。mkphones0.led为一些命令,内容如下:
EX //用dict词典中的发音替换word.mlf文件中每个词
IS sil sil // IS命令是在每个句子前面和后面加上一个静音sil模型
DE sp// DE命令删除发音词典标签中所有的sp,因为在音素级的标记文件不需要这些标记
本实验为孤立词识别,不需要上面过程。
1.1.5.提取语音特征参数
用HCopy命令。
提取参数配置文件:
# Coding parameters
TARGETKIND = MFCC_0
TARGETRATE = 100000.0
SAVECOMPRESSED = T //以压缩的方式存储,并且增加循环冗余检查
SAVEWITHCRC = T
WINDOWSIZE = 250000.0//窗口长度:25ms
USEHAMMING = T //使用汉明窗
PREEMCOEF = 0.97
NUMCHANS = 26 //三角滤波器个数
CEPLIFTER = 22
NUMCEPS = 12
ENORMALISE = F //能量是否归一化
提取特征参数的命令如下:
HCopy -T 1 -C config -S codetr.scp
2.训练过程
a.建立HMM模型原型,如下
~o <VecSize> 13 <MFCC_E> <StreamInfo> 1 13
<BeginHMM>
<NUMSTATES> 5
<STATE> 2<NUMMIXES> 1
<STREAM> 1
<MIXTURE> 1 1.000000e+000
<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 0.0
<VARIANCE> 13
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
<STATE> 3<NUMMIXES> 1
<STREAM> 1
<MIXTURE> 1 1.000000e+000
<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 0.0
<VARIANCE> 13
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
<STATE> 4<NUMMIXES> 1
<STREAM> 1
<MIXTURE> 1 1.000000e+000
<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 0.0
<VARIANCE> 13
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
<TRANSP> 5
0.000000e+000 1.000000e+000 0.000000e+000 0.000000e+000 0.000000e+000
0.000000e+000 6.000000e-001 4.000000e-001 0.000000e+000 0.000000e+000
0.000000e+000 0.000000e+000 6.000000e-001 4.000000e-001 0.000000e+000
0.000000e+000 0.000000e+000 0.000000e+000 6.000000e-001 4.000000e-001
0.000000e+000 0.000000e+000 0.000000e+000 0.000000e+000 0.000000e+000
<ENDHMM>
然后用HCompV工具扫描所有的训练数据,计算全局均值和方差,让每个HMM模型中的高斯函数有相同的均值和方差。
假设训练数据列表存在trainFea.scp
如下命令可以为每个HMM模型赋相同的均值和方差:
HCompV -C config -f 0.01 –o hcompv.hmm train.scp -M hmms/hmm0
hmms/template.hmm
其中config为提取特征时用到的配置文件。 Train.scp为所有训练数据集列表.mfc,-m计算均值和方差, -M hmms/hmm0初始化后模型存放的文件夹,hmms/template.hmm为HMM模型原型。
-f输出0.01乘以全局方差矩阵。它是方差的一个最低限,保存在文件vFloors中,在后面的训练要用。
从生成的hcompv.hmm可以看出:它们的转移概率没变。每个高斯函数的均值和方差都变了,它们是通过MLE (maximum likelihood estimate)算法从训练样本中得到的。
b.拷贝Hcompv.hmm文件的内容,为每个音素模型建立hmm模型。所有的模型保存在一个文件中。Macro.init,这样做的目的是防止太多的HMM模型定义文件,把它们放在一个文件中更方便。
Macro.inti包括11音素的HMM模型参数(sil、ling、i、er、san、si、wu、liou、qi、ba、jiou) acoustic models
该过程可以通过手工完成,包括sil模型参数
c.用mxup.led修改macro.init模型生成macro.0文件,增加高斯分量。
先拷贝hmms\hmm1\macro.init 到hmms\hmm1\macro.0
然后用 HHED命令修改macro.0
HHED为HMM模型编辑工具,工作模式如同HLED
mxup.led
MU 3 {*.state[2-4].mix}
该命令表示为第二到第四个状态增加高斯分量,从开始的1个增加到3个。
macro.0 各个状态的三个分量的方差相同,但是均值不同.
d.重新估计macro.0中各模型的参数.生成macro.1 ~ macro.5
用HERest命令进行嵌入式重估
HERest -C config -I phones0.mlf -t 250.0 150.0 1000.0 \
-S train.scp -H hmm0/macros -H hmm0/hmmdefs -M hmm1 monophones0
说明:加载hmm0/hmmdefs中在monophones0列出的所有HMM模型,然后用train.scp列出的数据训练模型,训练好的模型保存在hmm1目录下。
Macros为全局宏命令,其中包括~o <MFCC_0_D_A> <VecSize> 39
和vFloors和每运行一次HERest命令进行重估一次。要进行多次训练的时候要不断改变—H和—M后的值
3.识别过程以及分析
HVite -H maro.HMM -l * -i result_train.mlf -w networks\\digit.net -S Trainfea.scp dict\\digit.dict monophones
dos('findstr /v "sp" result_train.mlf > result_train_no_sp.mlf');
dos('findstr /v "sil" result_train_no_sp.mlf > result_train_no_sp_sil.mlf');
dos('HResults -p -e ??? sil-I phones0.mlf dict/digit.dict result_train_no_sp_sil.mlf > insideTest.txt');
type insideTest.txt
contents=fileread('insideTest.txt');
keyStr='WORD: %Corr=';
startIndex=strfind(contents, keyStr)+length(keyStr);
inRR=eval(contents(startIndex:startIndex+4));
fprintf('训练数据的识别率为:%g%%\n', inRR);
完成所有的步骤之后,我的文件夹如下:
更多推荐
所有评论(0)