分类: LINUX
2013-01-15 15:46:05
声学模型主要用于计算语音特征和每个发音模板之间的似然度。目的是为每个声学单元建立一套模型参数(通过不断地学习和改进得到最优的,也就是概率最大的一组HMM模型参数)。
需要训练的情况:
1)需要创建一个新的语音或者方言的模型;
2)为你的小词汇的应用创建一个特定的模型;
3)你有足够的大量的语音数据:单的人的话(控制指令)需要1小时的录音,200个人的话需要50小时的录音。
4)你需要有语言的音素结构的知识;
5)你有足够的时间去训练和优化(大概需要一个月)。
如果不具备以上的情况或者条件,那么用模型增强(适应)比训练一个新的模型更有效。
另外,你的语音数据库应该能够比较好地代表你所要识别的语音,而且最好是多个人的录音数据,而且包含多种录音情况,还有所有可能的语言学句子。语音数据库包含两个部分:训练集和测试集,一般来说,测试集占全部数据库的1/10,但最好不要超过4个小时的录音时长。
获得一个语音数据库的一个比较好的方式是:
1)对现有的你需要识别的语音的录音材料进行切割,例如新闻或者电台播音等;
2)把你身边的人,例如家人,朋友或者同事的语音录下来;
3)在voxforge上面收集;
SphinxTrain是CMU大学开发的开源声学模型训练器。此工具可以训练适应于PocketSphinx的半连续HMM声学模型,也可以训练应用于Sphinx3的连续HMM声学模型。
(1)需要准备的文件:
在进行训练之前,先通过SphinxTrain中的wave2feat文件对音频文件进行特征提取,得到的MFCC特征参数文件,并把它们作为声学模型训练的输入。在进行训练之前,需要建立如下准备文件:
分别创建两个目录etc和wav,然后在两个目录下面制作一些数据文件,方便后面训练时使用。待会需要的目录及文件如下所示:
etc:
your_db.dic - Phonetic dictionary
your_db.phone – Phone set file
your_db.lm.DMP - Language model
your_db.filler - List of fillers
your_db_train.fileids - List of files for training
your_db_train.transcription - Transcription for training
your_db_test.fileids - List of files for testing
your_db_test.transcription - Transcription for testing
wav:
speaker_1
file_1.wav - Recording of speech utterance
speaker_2
file_2.wav
下面对以上的文件作用做些说明:
your_db.dic - Phonetic dictionary
主字典文件:该文件中包含要训练的所有词语以及与它们相对应的音素集(记录的是字到语音单元的映射)。如果某个词有两个以上的发音要分别列出。在训练之前,要指明如何将每一个数字的拼音拆解成声学模型。这里我们将数字的每一个音节看成一个声学模型,存放在字典文件中。文件的加载内容为:例如:
三SAN
四SI
五WU
一YAO
一(2) YI
如果是英文的话,例如:
HELLO HH AH L OW
WORLD W AO R L D
另外,对于特殊字符,我们需要对其进行修改,此处不说了。
your_db.phone – Phone set file
音素文件:表示声学模型训练单元,由于数字识别系统只包含10个词的小词汇量识别系统,所以我们的训练单元以这是个词的音节为训练基本单元即可。音素排列以26个字母顺序排列。在数字识别中主要选择音节作为识别单元,故音素文件中包括十二个单元:BA、ER、JIU、LING、LIU、QI、SAN、SI、SIL、WU、YAO、YI。其中SIL表示句子的停顿或静音,或者是录音环境的背景噪声。YAO和YI代表了数字1的两个发音。
例如,如果声学单元是音素的话,就是每个音素一行,最后加上SIL这个静音单元:
AH
AX
DH
your_db.lm.DMP - Language model
语言模型文件:你在训练得到的语言模型。
your_db.filler - List of fillers
补充字典文件:该文件主要列举了非语音单词,它可以包括静音,背景噪声,或者mm,um或者呼吸,笑等等。多音字的情况必须全部列出,除此文件外我们还要建立一个补充字典来说明语音中的停顿,当然这种静音(或停顿)可以理解为背景噪声。每个补充字典文件至少包含以下三项:
SIL
SIL
文件中的代表句首的停顿,代表句末的停顿,
your_db_train.fileids - List of files for training
控制文件:指明了包含所有训练语音文件的路径。表示如下
wav/train/name1/1.WAV
wav/train/name2/1.WAV
your_db_train.transcription - Transcription for training
脚本文件: 存放每个控制文件(用于训练的)路径的内容(告诉训练器你需要训练哪些语音单元)。文件内容是与控制文件的路径一一对应的语句内容。包括句中的停顿也要用文本列举出来。例如:1.WAV录下的就是hello world这个句子的音,那文件的内容就是:
hello world (1)
foo bar (2)
主要注意的是,每个行都需要以 开始和以 结束,而且()括号内的语音文件只包含文件名,不包含文件路径。
your_db_test.fileids - List of files for testing
控制文件:指明了包含所有测试语音文件的路径。
your_db_test.transcription - Transcription for testing
脚本文件: 存放每个控制文件(用于测试的)路径的内容。
在准备这些文件的时候必须注意以下几点:
1)主字典和补充字典必须与音素文件相对应,即字典文件中不允许有音素文件中不存在的音素;
2)确保字典文件中没有重复的单词,不包括多音字的列举;
3)确保脚本文件和控制文件行数相同,并且一一对应;
4)确保脚本文件中的词都存在与字典文件中;
5)确保脚本文件中所有音素都存在于音素文件中,并且音素在训练的脚本文件中出现一次。
以上五点,如有一点不满足条件,训练将自动终止。
(2)准备etc下的数据文件
# mkdir train
# cd train
# mkdir etc wav
# cd etc
1、声音文件我是直接放在wav文件夹下的,命名如下(因为这样方便我用脚本去控制录音):
# vi my_db_train.fileids
voice_0001
voice_0002
voice_0003
voice_0004
voice_0005
voice_0006
voice_0007
voice_0008
voice_0009
voice_0010
voice_0011
voice_0012
voice_0013
voice_0014
voice_0015
voice_0016
voice_0017
2、测试数据和语音数据一样,因为我并没有测试这个步骤,所以把简单的copy了一下:
# cp my_db_train.fileids my_db_test.fileids
3、我的库主要是包含了17个控制的指令,如下:
#vi my_db_train.transcription
确定 (voice_0001)
取消 (voice_0002)
关闭 (voice_0003)
退出 (voice_0004)
返回 (voice_0005)
放大 (voice_0006)
缩小 (voice_0007)
音乐 (voice_0008)
图片 (voice_0009)
视频 (voice_0010)
天气 (voice_0011)
设置 (voice_0012)
菜单 (voice_0013)
向左 (voice_0014)
向右 (voice_0015)
向上 (voice_0016)
向下 (voice_0017)
4、#cp my_db_train.transcription my_db_test.transcription
5、# vi my_db.dic
确定 Q UE D ING
取消 Q U X IAO
关闭 G UAN B I
退出 T UI CH U
返回 F AN H UI
放大 F ANG D A
缩小 S UO X IAO
音乐 Y IN Y UE
图片 T U P IAN
视频 SH I P IN
天气 T IAN Q I
设置 SH E ZH IB
菜单 C AI D AN
向左 X IANG Z UO
向右 X IANG Y OU
向上 X IANG SH ANG
向下 X IANG X IA
6、#vi my_db.filler
SIL
SIL
7、生成my_db.phone
#cp ../../sourcecode/sphinxtrain-1.0.7/scripts_pl/make_phoneset.pl .
#./make_phoneset.pl my_db.dic my_db.filler > my_db.phone
# vi my_db.phone //看下有没有多余的
A
AI
AN
ANG
B
C
CH
D
E
F
G
H
I
IA
IAN
IANG
IAO
IB
IN
ING
OU
P
Q
S
SH
SIL
T
U
UAN
UI
UO
UX
UXE
X
Y
Z
ZH
以上若有多余字母,可手工删除。
8、把之前的my_db.lm.DMP也拷贝到etc下。
至此,etc下的数据文件已准备完毕。
注意:以上所有的文件在输入结尾不可留下“/n”。
(3)准备wav下的音频文件
为每一个控制词录制一个语音文件,录音文件的命名需要和my_db_train.transcription与my_db_train.fileids的一致。
注意:此处音频文件采样率16KHz,16bit单声道录音,而且是wav格式。
我在Linux下写了一个处理脚本来实现上面这17个词的录音:rec_wav.sh,内容如下:
#cd ../wav
#vi rec_wav.sh
for i in `seq 1 17`; do
fn=`printf voice_%04d $i`;
read sent; echo $sent;
rec -r 16000 -e signed-integer -b 16 -c 1 $fn.wav 2>/dev/null;
done < ../etc/my_db.dic
在这里我们需要用到rec这个录音命令,这个命令是由Linux下一个很有名的音频转换程序sox携带的,所以我们需要先安装sox:
#apt-get install sox
然后改变rec_wav.sh的运行属性:
#chmod 777 rec_wav.sh
#./rec_wav.sh
这个脚本会显示一个词,然后进入录音,我们把这个词读出来,然后按ctrl+c显示下一个词,然后录音,如此循环到全部的词的语音数据拿到。这样在当前文件夹下面就会显示如下文件:
voice_0001.wav
voice_0002.wav
.....
voice_0017.wav
然后,我们需要测试下每个音频文件是否正常:
for i in *.wav; do play $i; done
他会依次的播放我们录下的这些音频文件;如果不对的话,就得重录,我的就没有什么问题。