1训练的基本步骤:... 3
2模拟未绑定状态的场景依赖音素的注意事项:... 4
3 你所需准备的数据... 4
4,训练之前需检查的项... 5
6 当你有一个非常小的闭合的词汇表(字典)(50—60字):... 6
7 “base”集合和高阶特征向量... 6
8 特征流(featuresstreams)... 6
9训练连续模型... 7
10 创建模型定义文件:文件后缀为.mdef7
11,创建HMM拓扑文件文件后缀为.topo. 8
12 场景依赖模型参数的flat(直接)initialization初始化... 9
13 训练场景独立模型... 11
14 创建CD-untied模型的定义文件... 13
15 flat 初始化CD-untied模型参数... 19
16 训练CD-untied模型... 19
17为共享参数(参数共享)建立决策树... 21
18产生语音问题(generatingthe linguistic questions)... 21
19 对决策树剪枝... 23
20创建CD绑定模型定义文件(CDTIED MODEL DEFINITION FILE)... 24
21初始化和训练CDtied(绑定)的高斯混合模型... 26
22训练半连续模型... 28
23矢量量化... 28
24创建CI模型定义文件... 30
25创建HMM拓扑文件... 30
26 flat-initialize CI模型的参数... 30
27 训练CI模型... 30
28创建CDuntied模型定义文件... 31
29 flat 初始化CD untied模型参数... 31
30 训练CDuntied模型... 31
31 为共享参数创建决策树... 31
32 创建语言问题... 31
33 对决策树进行剪枝... 31
34 创建CDtied模型定义文件... 31
35 初始化并训练CDtied(绑定)模型... 31
36 删除代替插入DELETED INTERPOLATION.. 32
37 Sphinx2的数据和模型格式。... 33
38sphinx3的数据和模型格式... 36
39对特征向量组成部分的解释:... 39
40 训练多语言模型... 40
41 训练字典THE TRAINING LEXICON.. 40
42 把sphinx3格式的模型转换成sphinx2格式的模型... 41
43 更新以存在的模型设置或自适应以存在的模型集... 42
44 在sphinx-III的解码器中使用半连续和连续模型... 43
45 强制校准FORCE-ALIGNMENT. 44
目录
模型类型选择
︳
﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉
︳ ︳
连续 半连续
︳ ︳
︳ 矢量量化
︳ ︳
﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉
︳…制作场景独立的mdef
︳…平滑初始化场景独立模型
训练场景独立的模型
︳…制作场景依赖的非绑定的mdef
︳…初始化
训练非绑定的场景依赖模型
︳
建立决策树
︳…剪枝
︳…绑定状态
︳…制作场景依赖绑定的mdef
训练绑定的场景依赖模型
︳
﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉
迭代高斯分割 …︳ ︳
连续模型 半连续模型
︳ ︳
﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉ 删除插入代替
︳ ︳ ︳………自适应
︳ 自适应 ︳ ︳
︳ ︳ ﹉﹉﹉﹉﹉﹉﹉﹉﹉
用sphinx3解码器解码 < …… 制作绑定的场景依赖mdef …︳ ………︳
用解码字典和剪枝数…︳ ︳
用sphinx3解码器解码 ︳
转换sphinx2
︳
用sphinx2的解码器解码
注意高斯函数是为多维高斯函数。
模拟未绑定状态的场景依赖音素(如,三音素)需要大量的硬件资源。你需发时间检查你是否有足够的资源。需要资源的多少依赖于你要训练的模型的类型,特征向量的维度度和组成,以及在HMMs中状态的数目。
例如:半连续模型,含义10,000个三音素,每个三音素含义5个状态,有4流的特征向量集,每个状态一个含义4*256个混合权重。即:
相应的,对于4特征流中的每一个,在码本中都有256个均值和256个方差,所有这些,所有的混合权重,转移矩阵都将被载入RAM,在训练中,一个附加的相等长度的缓存需要被分配为存储所产生的中间结果。这些随后都会被写入硬盘中当对当前训练的迭代都完成后。注意,转移矩阵是和音素一样多的(对于40—50的英语,这依赖于你的字典),所有这些被分配的将大于400Mb RAM。
对于拥有较小内存的机器来说着是一个瓶颈。不管你选择训练的语料库有多大,事实上你所能够训练的仅仅只有10,000个三音素在场景依赖非绑定上,如果你小于400mb的RAM(一个100小时的广播语料库,一般有40,000个三音素)。你能够训练更多,如果你的机器有足够的可供处理的内存(这能过被做,例如,有更大的交换空间),如果你在多台机器上训练,每一台都要求这么多内存。另外,在最后的每一次迭代,你必须把所有的缓存发射到一台单独的机器上以便执行norm操作(均一化)。网络问题也应该被考虑。
场景依赖非绑定模型被用于构造树。在这一阶段你所训练的音素的数量对于树的特性会有直接的影响。如果你没有足够的内存,你所创建的数只能使用比训练集中更小的音素。
连续模型:有10,000三音素:
如此当我们又跟半连续模型相同的内存时,我们能训练的三音素是它的12.因为我们能够使用更多的音素来训练,得到的决策树也将会更好,最终识别的结果也将会更好。
在你开始训练之前,你需要拥有以下文件:
A,一系列的特征文件。这是从音频的训练数据计算而来的。每一条录音都能通过一个可以执行的前端处理程序转换成一系列的特征矢量。前端处理程序提供了对语音信号的分析处理,可以得到不同的语音特征。
B,控制文件,包含一系列的全路径的特征集合的文件名。如:dir/subdir1/utt1
注意,文件的扩展名没有给出。它们都将单独的供给训练。最好给特征文件一个独一的名字,尽管包含全路径使控制文件中的每一项都独一无二的。这将为你做许多的事情都提供便利。注意,在控制文件中一行只有一个特征文件,一行即一项,一项就是一个全路径。
C,脚本(副本)文件,脚本即是特征文件的(副本)脚本。脚本是于控制文件中的特征文件相同的顺序列出的。
D,主字典文件,它拥有脚本中的全部声学事件和字。在字典中冗余字即额外字是允许的,如果一个字有多个发音,那么另外的发音也应该列出,并在字的后面用括号把数字括起来,表示其是第几个不同的发音。字典必须有全部的可供选择的发音标记,用括号括上数字从(2)开始对于第二个发音,标记(1)是省略。例子如下:
E,填充字典,它通常把非语音事件当做字列出,并映射到用户自定义的音素。字典至少必须拥有以下词条:
这些词条代表了:<s>: begin-utterance silence <sil>:within-utterancesilence
</s>:end-utterance slience 注意:字<s> ,<sil>,</s>都被认为是特殊的字,都要求在填充字典中呈现。它们之中至少有一个必须映射到一个叫“SIL“的音素。SIL音素是以一种特殊的方式被对待,SIL音素要求被呈现。Sphinx系统希望我们把于背景条件一致的声学事件命名为SIL。对于清洁,干净的语音,这些声学事件其实是表示静音。但是对于噪声语音,这些声学事件是指战胜了数据库中语音的最一般的背景噪声。其它的噪声也能够模拟成用户所定义的音素。
在训练中,SIL代替左右加“+”的每个音素,当做相邻音素的上下文。左右加了“+”的音素仅仅被模拟成场景独立的音素,它们并没被使用为三音素的上下文。如果你并不想要其发生,你应该把填充映射成不加“+”的音素。音素前后加“+”表示音素场景独立。
F,一个音素列表,这是一个你将训练的所有声学单元(一般为音素)的列表。Sphinx系统并不允许你有不在字典中的声学单元。在你两个字典中的所有单元都必须列在音素列表中。也就是说音素列表中的音素必须和你在字典中所含音素完全一致,不多不少。在文件中一个音素为单独的一行,从左开始,音素后没有额外的空间。例如:
A,脚本文件中所有的字是是否都在主字典或填充字典中?应该在。
B, 确保脚本的长度与.ctl文件相匹配。
C, 检查在.ctl文件即控制文件中定义的边界都存在ie,你要有在控制文件中列出的所有帧。
D,根据主字典和填充字典来检查音素列表。
如果你仅仅有大约50—60字的词汇表,并且所有的测试数据词汇表都被训练数据覆盖。那么训练字模型比音素模型会更好,即应该训练的是字模型,而非音素模型,为了训练字模型,应该把音素集定义为字本身的集合,即字的音素用字本身来代替。字典也是一个字映射到本身字(同一个字)的字典。使用了更少的填充。如果你需要训练音素模型,你需确保每一个绑定的状态应该有足够的数量(每个至少5或10实例)。
你使用sphinx的前端执行程序计算而得到的特征向量集叫做“base”基本特征向量集。基本特征向量集能够被扩展成所谓的“higherorder“特征集。一些共同的扩展如下:
A,差分向量集,是其某些前序后序向量的差分。差分向量集被用来获得当前时刻的斜率或趋势的估计。差分向量集是当前向量的扩展。它们称之为“delta“特征。更合适的名字应该是叫”trend“特征(趋势特征)。
B,差分向量的差分向量集,是当前向量的前序“delta“向量和后续”delta“向量的差分。称之为”double delta“向量。
C,当前向量的第n个前序和后续向量的差分,是当前向量的扩展,称之为“long-term delta“特征,是不同于仅仅捕捉扩展了一个时间窗的”delta“特征的。
D,当前向量的第1个元素和一些上述扩展向量的第1个元素组成向量,叫做“power“(强)特征,它的维度小于或等于你所考虑的特征类型的总和。
在半连续模型中,通常是把“base“向量和扩展向量分离的。如此的每个集合叫做一个特征流。你必须确定你想使用多少个特征流在半连续模型中,以及怎样安排它们。当前被sphix系统可选择支持的特征集有:
c/1. .L-1/,d/1. .L-1/,c/0/d/0/dd/0,dd/1. .L-1/ : 这被读作为:cepstra/second to last component(倒普/第二组成部分到最后组成部分),deltacepstra/second to last component,cepstra/first component deltacepstra/first componentdoubledeltacepstra/first component,
doubledeltacepstra/secondto last component.
这是一个在半连续模型中使用最频繁的4 流特征。这样的安排并没有特别的优势,任何的排列都会产生相同的模型,只是其参数以不同的顺序被写。被4流特征集使用的不明显的标记为:4流特征向量的维度,是12cepstra+24deltas+3powerterms+12doubledeltas
Detals被计算为两倒普帧之间的差分,从当前帧的一边开始移动(12of these),接着是4倒普帧之间的差分,从当前帧的一边开始移动的。The power stream(强流)使用了两帧移deltas的第一成分,计算使用了C0。
第一步你必须准备一个模型定义文件为场景独立音素。模型定义文件的作用是为将于训练的每个HMM的每个状态定义一个独特的数字标示或为其通过一个独特的数字标识符。模型定义文件也提供了模型参数文件中参数被写的顺序。在训练中,状态仅仅被那些数字引用。模型定义文件在一定程度上确定了你模型的结构。它经常存储在“model_architecture“目录下。当然,你能够把它存储在你想存储的地方,除非你正在运行由sphinx-III包提供的脚本命令外。
为产生场景独立的模型定义文件。我们应该使用mk_model_def可执行命令或程序,并设置一下标志:
把标准的输出输入到ci_mdef.log的日志文件中。如果你在音素列表中仅仅列出了三个音素,确定了你想为每个音素建立一个三状态的HMM。模型定义文件看上去如下所示:
HMM拓扑文件由一个矩阵组成,矩阵的每一项为布尔值。每项表示了在HMM中是否存在从状态(所在行数)到状态(所在列数)的转移。例如,三状态的HMM,HMM中的状态之间不存在着跳跃,其拓扑文件如下所示:
4是一个HMM中的总状态数,注意,sphinx系统会自动的添加一个非发射状态给3状态的HMM。第一项1.0表示一个状态1到状态1(本身)的转移是容许的。相应的对于任何音素的被估计的转移矩阵将会有一个转移概率在布尔项的地方。在项为零的地方,其转移概率将不会被估计(将为零)。
你能够自己手写拓扑文件,或通过sphinx包提供脚本make-topology.pl来制作拓扑文件,脚本需要如下参数:
注意,拓扑文件是被所有的HMM所共有的,是一个单一的包含拓扑定义矩阵的文件。文件同时也定义了模型的结构,它通常被放在“model-architecture”目录下。这是可选的,但是被推荐这样做。如果你运行来自sphinx训练包的脚本,你会发在“model-architecture”存在着这样的一个文件。
场景依赖模型有4个参数文件组成:
A,mixture_weights(混合权重),权重被给予到与一个状态相应的高斯混合中的每一个高斯。即一个状态的高斯混合中的每个高斯。
B,transition_matrices(转移矩阵),状态的转移概率矩阵
C,means(均值),所有高斯的均值
D,variances(方差),所有高斯的方差
在开始训练场景独立模型前,以上4个文件的每一个都必须被初始化。混合权重和转移矩阵使用mk-flat可执行命令初始化,它需以下参数:
为了初始化均值和方差,这些参数的全局值首先被估计,然后被拷贝到参数文件合适的位置。全局均值使用了你特征文件中的所有向量来计算。这通常是一个很大的数目,所以这项工作被分成了许多分(部分)。在这阶段你告诉sphinx系统这项操作被分成多少个分(部分或层次)(这依赖于你有的计算工具),sphinx系统积聚或收集单独每一部分的向量,然后把它写入你机器的中间缓存中。Init_gau可执行命令就是用来完成这个目标的。它需要如下参数:
一旦,缓存被写,缓存的内容被均匀化,或者被用来计算特征向量的全局均值。这通过使用norm可执行命令来完成,需使用如下标记:
下一步是聚集向量来计算全局方差值,使用init-gau可执行命令来完成,需要全局均值的值和对所有的数据集收集值(全局均值向量)集合,可执行命令需如下参数:
再一次,一旦缓存被写,缓存的内容被均匀化,或者被用来计算特征向量的全局方差。这需要再次使用norm可执行命令,需如下标志被设:
一旦全局均值和方差被计算得到,它们必须被拷贝到每一个HMM得每一个状态的均值和方差上。全局均值被写入到一个均值中的合适状态位置。全局方差被写入到一个方差文件的合适的状态位置。如果你使用了sphinx包所通过的脚本,你将会在model-parameters目录下找到以“flatinitial”作为其部分文件名的那些文件。
Flat(直接还平滑还单调)的均值和方差文件能够通过使用cp-parm可执行命令模型产生。为了使用这可执行命令,你需创建一拷贝操作映射(copyoperations map)文件,这个文件含有两列,左列状态id-ing表示到哪个全局值被拷贝的,右列状态id-ing表示其来自哪个被拷贝的。如果有“nphones”场景独立音素,每个状态有“nEstate-per-hmm”发射状态,则拷贝操作映射文件有ntotal-Estates=nphons*nEstate-per-hmm行。在左列的状态id值从0到(thru)nEstate-per-hmm—1,这有这样一样一个例子,3状态hmm(nEstate-per-hmm=3),两音素(nphones=2),ntotal-Estates=6,状态ids在0-5变化。
cp-parm需要以下参数:
cp-parm将会被运行两次,一次用来拷贝均值,一次用拷贝方差。如此场景独立(CI)训练的初始化就被完成了。
一旦平滑初始化被完成,你就可以为base或场景独立或CI音素训练音素模型。这叫做CI-训练即场景独立训练,在场景独立训练中,平滑初始化模型被重新估值通过叫做Baum-Welch算法的前向-后向重估算法。这是一个迭代重估的处理过程,所有你需对你的训练数据进行多次的Baum-Welch重估“pases”(通过)。每一次pases或迭代都会为CI音素产生更好的模型集。不管怎样,因为在每次pases中的最大化得目标函数是似然的,太多的迭代次数会最终会导致模型过于紧密的适合于训练数据。你也许有许多理由不想这种情况发生。典型的,5-8次的Baum-Welch迭代对于获得好的CI模型的估计就足够的。你能够很快的决定迭代的次数,这需你要第一次迭代后训练数据的总似然度,以及决定一个似然收敛率。这是当前迭代的总似然度于上次迭代的似然度的简单的比率。由于每次迭代后模型都会变得越来越适合训练的数据,所以训练数据的似然度一般是单调增加的。收敛率是一个很小的正值。随着迭代的进行收敛率变得越来越小,因为每个时间点的当前模型比前一模型有着更小的不同。收敛率是数据和目标的确定。但是对于CI训练,你也许会停止Baum-Welch迭代的值在0.1到0.001之间。当模型被方差均值化(均匀化)后,收敛率会更小。
运行Baum-Welch迭代的可执行命令行是“bw”,对于训练连续CI模型需以下参数:
FLAG |
DESCRIPTION |
-moddeffn |
model definition file for CI phones |
-ts2cbfn |
this flag should be set to ".cont." if you are training continuous models, and to ".semi." if you are training semi-continuous models, without the double quotes |
-mixwfn |
name of the file in which the mixture-weights from the previous iteration are stored. Full path must be provided |
-mwfloor |
Floor value for the mixture weights. Any number below the floor value is set to the floor value. |
-tmatfn |
name of the file in which the transition matrices from the previous iteration are stored. Full path must be provided |
-meanfn |
name of the file in which the means from the previous iteration are stored. Full path must be provided |
-varfn |
name of the file in which the variances fromt he previous iteration are stored. Full path must be provided |
-dictfn |
Dictionary |
-fdictfn |
Filler dictionary |
-ctlfn |
control file |
-part |
You can split the training into N equal parts by setting a flag. If there are M utterances in your control file, then this will enable you to run the training separately on each (M/N)th part. This flag may be set to specify which of these parts you want to currently train on. As an example, if your total number of parts is 3, this flag can take one of the values 1,2 or 3 |
-npart |
number of parts in which you have split the training |
-cepdir |
directory where your feature files are stored |
-cepext |
the extension that comes after the name listed in the control file. For example, you may have a file called a/b/c.d and may have listed a/b/c in your control file. Then this flag must be given the argument "d", without the double quotes or the dot before it |
-lsnfn |
name of the transcript file |
-accumdir |
Intermediate results from each part of your training will be written in this directory. If you have T means to estimate, then the size of the mean buffer from the current part of your training will be T*4 bytes (say). There will likewise be a variance buffer, a buffer for mixture weights, and a buffer for transition matrices |
-varfloor |
minimum variance value allowed |
-topn |
no. of gaussians to consider for computing the likelihood of each state. For example, if you have 8 gaussians/state models and topn is 4, then the 4 most likely gaussian are used. |
-abeam |
forward beamwidth |
-bbeam |
backward beamwidth |
-agc |
automatic gain control |
-cmn |
cepstral mean normalization |
-varnorm |
variance normalization |
-meanreest |
mean re-estimation |
-varreest |
variance re-estimation |
-2passvar |
Setting this flag to "yes" lets bw use the previous means in the estimation of the variance. The current variance is then estimated as E[(x - prev_mean)2]. If this flag is set to "no" the current estimate of the means are used to estimate variances. This requires the estimation of variance as E[x2] - (E[x])2, an unstable estimator that sometimes results in negative estimates of the variance due to arithmetic imprecision |
-tmatreest |
re-estimate transition matrices or not |
-feat |
feature configuration |
-ceplen |
length of basic feature vector |
如果你已经进行了几个部分的训练,既使你只运行了一部分的训练,上述描述的Baum-Welch可执行命令仅仅会产生中间缓存。最终的模型参数也就是均值,方差,混合权重,转移矩阵必须被估计用存储在那些缓存(buffers)中的值。这通过一个叫“norm”的可执行命令完成,
它需如下参数:
FLAG |
DESCRIPTION |
-accumdir |
Intermediate buffer directory |
-feat |
feature configuration |
-mixwfn |
name of the file in which you want to write the mixture weights. Full path must be provided |
-tmatfn |
name of the file in which you want to write the transition matrices. Full path must be provided |
-meanfn |
name of the file in which you want to write the means. Full path must be provided |
-varfn |
name of the file in which you want to write the variances. Full path must be provided |
-ceplen |
length of basic feature vector |
如果你在“bw”过程中没有对模型的参进行重估,那么给予给“norm”的相应的参数标志必须被省略掉。可执行命令将会尝试读取在buffer目录下的一个“non-existence”(不存在)buffer(缓存)。如此如果你在运行”bw”命令时的-meanreset设为“no”,则在运行“norm”命令时应该把-meanfn标志省略掉。这是很有用的在自适应期间。
Baum-welch迭代和norm最终会产生CI模型,一旦训练数据的似然度收敛,则迭代会停止。用norm计算出来的模型参数在最后迭代中初始化非绑定状态的场景依赖音素(triphones)模型。这是下一训练阶段的主要出来过程,我们选择了非绑定状态的三音素HMM训练过程(CD untied training)。
下一步是训练CD-untied(非绑定场景依赖)的训练。在其中对于在语音库中的所有三音素(场景依赖音素)其HMM都将被训练。对于CD-untied训练,我们需创建一个定义文件所有在训练集中的三音素。完成这需要几步:
1, 在词汇表中所有可能的三音素是从字典中产生的。为了从字典中获得完整的三音素列表,我们必须以如下格式写出音素列表:
phone1 0 0 0 0
phone2 0 0 0 0
phone3 0 0 0 0
phone4 0 0 0 0
...
用来CI训练的音素列表被用来产生上述音素列表,二者中被列的音素的顺序必须是一样的。
2,产生一个暂时的字典,它包含了除填充字(被++()++包围的字)之外的所有字。项SIL SIL 必须被添加入暂时字典中,字典中的音素必须以字母表的顺序排列。Sphinx-III包提供的“quick-count”程序能够被用来从暂时字典中产生所有可能的三音素列表。它需如下参数:
FLAG |
DESCRIPTION |
-q |
mandatory flag to tell quick_count to consider all word pairs while constructing triphone list |
-p |
formatted phonelist |
-b |
temporary dictionary |
-o |
output triphone list |
这是“quick-count”的典型输出:
AA(AA,AA)s 1
AA(AA,AE)b 1
AA(AA,AO)1 1
AA(AA,AW)e 1
在AA(AA,AO)中的“1”表示这是一个字内三音素。这是sphinx-II所支持的,现在“quick-count”的输出被写成了如下格式:
AA AA AA s
AA AA AE b
AA AA AO i
AA AA AW e
这能够通过在quick-count的输出中用一个空格来代替“(”,“,”和“)”,和只打印出首4列来实现。这样做的话,所有1的实例需用“i”来代替。在CI音素列表的结果文件的顶部添加如下格式:
AA - - -
AE - - -
AO - - -
AW - - -
..
..
AA AA AA s
AA AA AE b
AA AA AO i
AA AA AW e
例如:如果quick-count的输出存储在一个叫“quick-count.out”的文件中,则用perl命令将会产生我们所期待格式的音素列表。
perl -nae'$F[0] =~ s/\(|\)|\,/ /g; $F[0] =~ s/1/i/g; print $F[0]; if ($F[0] =~/\s+$/){print "i"}; print "\n"' quick_count.out
上述的 三音素(和音素)列表被转换成列出来自字典的所有可能三音素的模型定义文件。这需要使用“mk-model-def”程序,接下来的参数是每个HMM的状态数
FLAG |
DESCRIPTION |
-moddeffn |
model definition file with all possible triphones(alltriphones_mdef)to be written |
-phonelstfn |
list of all triphones |
-n_state_pm |
|
在下一步中,我们查找在训练语音库中出现的,列出在使用triphones-mdef中的每一个三音素的出现次数。这通过“param-cnt”程序完成,需如下参数:
FLAG |
DESCRIPTION |
-moddeffn |
model definition file with all possible triphones(alltriphones_mdef) |
-ts2cbfn |
takes the value ".cont." if you are building continuous models |
-ctlfn |
control file corresponding to your training transcripts |
-lsnfn |
transcript file for training |
-dictfn |
training dictionary |
-fdictfn |
filler dictionary |
-paramtype |
write "phone" here, without the double quotes |
-segdir |
/dev/null |
param-cnt把每个三音素出现的次数写到标准输出中。所有的其它信息会被送到标准错误输出中(stderr)。因此标准输出必须指向一个文件。如果你使用tcsh或csh来做它,需要以如下方式:
(param_cnt [arguments] > triphone_count_file) >&! LOG
这是这个程序的输出示例:
+GARBAGE+ - - - 98
+LAUGH+ - - - 29
SIL - - - 31694
AA - - - 0
AE - - - 0
...
AA AA AA s 1
AA AA AE s 0
AA AA AO s 4
每一行的最后数字表示了特定音素或填充音素在训练语料库中出现的次数。Not that if all possible triphonesof a CI phone are listed in the all_triphones.mdef the CI phone itself willhave 0 counts since all instances of it would have been mapped to a triphone.(如果CI音素的所有可能三音素都被列在了all_triphones.mdef文件中,则CI音素其本身将会是0次计数,因为它的实例将会被映射到一个三音素)。
计数三音素列表被用来筛选一个有最小发生次数(threshold)的三音素列表。筛选的三音素列表于被筛选的文件的格式是一样的。筛选的三音素列表于用来产生all_triphones.mdef文件的三音素列表有这相同的格式。CI音素的格式列表必须被包含在其中像以前一样。在一个简单的例子中,如门限为4,则我们的筛选列表如下:
AA - - -
AE - - -
AO - - -
AW - - -
..
..
AA AA AO s
..
门限被调整以便使在门限之上的三音素的总数小于系统所能训练(或你自己想要训练)的最大的三音素的个数。尽可能的训练更多的三音素是有好处的。最大可训练的三音素取决于你机器内存的可使用量。与之相关的描述在手册的开头部分。
注意,门限通过用来减少三音素的数量,为了使结果模型足够小的适应电脑的内存(为是模型占据的内存足够小)。如内存不存在着问题,则可以把门限设置的足够小。如果三音素出现的次数太少,不管怎样,(如果门限太小设置的),将不会有足够的数据用来训练HMM合适的状态分布。最将会导致CD-utied模型被贫乏的(poorly)估计,这反过来会影响在接下来的训练的主要步骤的使用这些模型来构建的决策树。
模型定义文件现在被创建,仅仅包含那些筛选的三音素,这是用来CD –untied训练的最后的模型定义文件。减少后的三音素列表被放于模型定义文件中,使用mk-model-def,mk-model-def用如下参数:每个HMM的状态数
FLAG |
DESCRIPTION |
-moddeffn |
model definition file for CD untied training |
-phonelstfn |
list of shortlisted triphones |
-n_state_pm |
|
最后,列出了所有CI音素和可见三音素的模型定义文件被构建。这文件,和CI模型定义文件相似,赋予了独特的id给每个HMM状态,当做一个引用文件来使用为CD-untied模型参数的处理和识别。如果你在音素列表文件中列出了5个音素,SILB AE T,并且确定了你想为每个音素创建3状态的HMM,并且你在脚本(transcrip)文件中列出了一语音;
<s>BAT A TAB </s>,你的字典和填充字典项如下所示:
Fillerdict:
<s> SIL
</s> SIL
Dictionary:
A AX
BAT B AE T
TAB T AE B
你的CD-untied模型文件(为如下所示)看上去为如下所示:
在完成CD-untied模型定义文件后,接下来的CD-untied训练步骤是对模型参数进行初始化。在这阶段,于CD-untied模型定义文件相关的模型参数文件将会被创建,包括4个参数文件:
均值,方差,转移矩阵,混合权重。这些文件中的每一个,其值开始时是从相应的CI模型参数文件拷贝过来的。一个特定的CI音素的每个状态将会对CD-untied模型参数文件中相同的CI音素的相同状态和相同CI音素的所有三音素的相同状态做出贡献。CD-untied的 模型定义文件被用作这映射的一个引用。这处理过程,通常称之为初始化(initialization)。
对CD-untied 训练的初始化是通过“init-mixw”的可执行命令程序来完成的。它需要如下参数:
CD-untied训练初始化完成后,下一步训练CD-untied模型。为了训练模型,和CI训练一样,Baum-Welch 前向-后向算法被迭代使用。每次迭代由产生的bw 缓存(buffers)组成。 Bw缓存由对训练语料库运行bw可执行命令产生的,(这个过程能分成几个部分像在CI训练中解释的一样)。接下来是运行norm可执行命令来计算在迭代结束时的最后参数。在这阶段,bw可执行命令所需参数如下:
FLAG |
DESCRIPTION |
-moddeffn |
CD-untied model definition file |
-ts2cbfn |
this flag should be set to ".cont." if you are training continuous models, and to ".semi." if you are training semi-continuous models, without the double quotes |
-mixwfn |
name of the file in which the mixture-weights from the previous iteration are stored. Full path must be provided |
-mwfloor |
Floor value for the mixture weights. Any number below the floor value is set to the floor value. |
-tmatfn |
name of the file in which the transition matrices from the previous iteration are stored. Full path must be provided |
-meanfn |
name of the file in which the means from the previous iteration are stored. Full path must be provided |
-varfn |
name of the file in which the variances fromt he previous iteration are stored. Full path must be provided |
-dictfn |
Dictionary |
-fdictfn |
Filler dictionary |
-ctlfn |
control file |
-part |
You can split the training into N equal parts by setting a flag. If there are M utterances in your control file, then this will enable you to run the training separately on each (M/N)th part. This flag may be set to specify which of these parts you want to currently train on. As an example, if your total number of parts is 3, this flag can take one of the values 1,2 or 3 |
-npart |
number of parts in which you have split the training |
-cepdir |
directory where your feature files are stored |
-cepext |
the extension that comes after the name listed in the control file. For example, you may have a file called a/b/c.d and may have listed a/b/c in your control file. Then this flag must be given the argument "d", without the double quotes or the dot before it |
-lsnfn |
name of the transcript file |
-accumdir |
Intermediate results from each part of your training will be written in this directory. If you have T means to estimate, then the size of the mean buffer from the current part of your training will be T*4 bytes (say). There will likewise be a variance buffer, a buffer for mixture weights, and a buffer for transition matrices |
-varfloor |
minimum variance value allowed |
-topn |
no. of gaussians to consider for likelihood computation |
-abeam |
forward beamwidth |
-bbeam |
backward beamwidth |
-agc |
automatic gain control |
-cmn |
cepstral mean normalization |
-varnorm |
variance normalization |
-meanreest |
mean re-estimation |
-varreest |
variance re-estimation |
-2passvar |
Setting this flag to "yes" lets bw use the previous means in the estimation of the variance. The current variance is then estimated as E[(x - prev_mean)2]. If this flag is set to "no" the current estimate of the means are used to estimate variances. This requires the estimation of variance as E[x2] - (E[x])2, an unstable estimator that sometimes results in negative estimates of the variance due to arithmetic imprecision |
-tmatreest |
re-estimate transition matrices or not |
-feat |
feature configuration |
-ceplen |
length of basic feature vector |
Baum-Welch步骤后是normalization步骤,“norm”可执行命令程序被使用。norm所需的参数和在CI训练中的一样,被列在如下:
Baum-Welch和norm 迭代必须运行到似然收敛为止(收敛率达到一个小的门限值)。一般6-10迭代可达到。
CD-untied 模型被计算出后,在训练连续模型中下一主要的步骤是建立决策树。决策树被用来确定所有三音素(可见或不可见)的哪些HMM状态是彼此相似的,以便从那些状态收集数据和用来训练一个全局状态,全局特征被称为“senone”。许多相似状态组被形成,最后被训练的“senone”的数目能被用户指定(由用户决定)。一个senone也叫做一个tied-state(绑定-状态)并且被对它做出贡献的三音素所共享。决策树建立和状态绑定的将在这手册的技术部分介绍。在这里所讲的为状态绑定和决策树的建立的理解的足够的。
决策树需要CD-untied 模型和共享相同属性的未定义的音素类集合(或是被你模拟的音素单元的类)。这些类或问题被用来分割一颗树上以给节点的数据。每一个问题将会导致一次分割,导致最好分割(由于分割使得在似然度上最大增长|在似然度上最大增长的分割)的问题被选择来分割那节点上的数据。所有的语音问题被写在一个单独的称之为“linguistic questions”的文件内。为每一个音素的每一状态建立一颗决策树。
例如:如果你想为任何音素为场景(D B P AE M IY AX OY)创建一决策树,你能够问这样的问题:场景属于vowels类吗?,如果你定义的vowels类包含音素AE AX IY OY EY AA EH (换句话,如果在你的语音问题中有个问题命名为“VOWELS”,并且又元素AE AX IY OY EY AA EH与之相对应),决策树会出现如下分枝:
这是一个“linguistic-questions”文件的例子:
左边的列给确定看类名,这个名字由用户定义。类由单独音素或共享某些共同属性的音素集群所组成。如果你的声学单元没有完整的语音动机,或你为某一语言正在训练模型,那种语言的声学结构你不能完全的确定,那么由sphinx-III包提供的“make-quests”可执行命令可以被用来产生语音问题。它使用了CI模型来产生问题,需要如下参数:
FLAG |
DESCRIPTION |
-moddeffn |
CI model definition file |
-meanfn |
CI means file |
-varfn |
CI variances file |
-mixwfn |
CI mixture weights file |
-npermute |
A bottom-up top-down clustering algorithm is used to group the phones into classes. Phones are clustered using bottom-up clustering until npermute classes are obtained. The npermute classes are exhaustively partitioned into two classes and evaluated to identify the optimal partitioning of the entire phone set into two groups. An identical procedure is performed recursively on each of these groups to generate an entire tree. npermute is typically between 8 and 12. Smaller values of npermute result in suboptimal clustering. Larger values become computationally prohibitive. |
-niter |
The bottom-up top-down clustering can be iterated to give more optimal clusters. niter sets the number of iterations to run. niter is typiclly set to 1 or 2. The clustering saturates after 2 iterations. |
-qstperstt |
The algoritm clusters state distributions belonging to each state of the CI phone HMMs to generate questions. Thus all 1st states are clustered to generate one subset of questions, all 2nd states are clustered for the second subset, and so on. qstperstt determines how many questions are to be generated by clustering any state. Typically this is set to a number between 20 and 25. |
-tempfn |
|
-questfn |
output lingustic questions file |
语音问题创建完成后,必须为在你音素列表中的每一个CI音素的每一个状态创建决策树。不管怎样,对于在音素列表中的由+()+包围的填充音素是不会创建决策树的。对于SIL音素同样也不创建决策树。为了创建决策树,“bldtree”可执行命令必须被运行,它需以下参数:
FLAG |
DESCRIPTION |
-treefn |
full path to the directory in which you want the decision trees to be written |
-moddeffn |
CD-untied model definition file |
-mixwfn |
Cd-untied mixture weights file |
-ts2cbfn |
.cont. |
-meanfn |
CD-untied means file |
-varfn |
CD-untied variances file |
-mwfloor |
Floor value of the mixture weights. Values below this are reset to this value. A typical value is 1e-8 |
-psetfn |
linguistic questions file |
-phone |
CI phone for which you want to build the decision tree |
-state |
The HMM state for which you want to build the decision tree. For a three state HMM, this value can be 0,1 or 2. For a 5 state HMM, this value can be 0,1,2,3 or 4, and so on |
-stwt |
This flag needs a string of numbers equal to the number of HMM-states, for example, if you were using 5-state HMMs, then the flag could be given as "-stwt 1.0 0.3 0.1 0.01 0.001". Each of these numbers specify the weights to be given to state distributions during tree building, beginning with the *current* state. The second number specifies the weight to be given to the states *immediately adjacent* to the current state (if there are any), the third number specifies the weight to be given to adjacent states *one removed* from the immediately adjacent one (if there are any), and so on. A typical set of values for 5 state HMMs is "1.0 0.3 0.1 0.01 0.001" |
-ssplitmin |
Complex questions are built for the decision tree by first building "pre-trees" using the linguistic questions in the question file. The minimum number of bifurcations in this tree is given by ssplitmin. This should not be lesser than 1. This value is typically set to 1. |
-ssplitmax |
The maximum number of bifurcations in the simple tree before it is used to build complex questions. This number is typically set to 7. Larger values would be more computationally intensive. This number should not be smaller than the value given for ssplitmin |
-ssplitthr |
Minimum increase in likelihood to be considered for a bifurcation in the simple tree. Typically set to a very small number greater than or equal to 0 |
-csplitmin |
The minimum number of bifurcations in the decision tree. This should not be less than 1 |
-csplitmax |
The maximum number of bifurcations in the decision tree. This should be as large as computationlly feasible. This is typically set to 2000 |
-csplitthr |
Minimum increase in likelihood to be considered for a bifurcation in the decision tree. Typically set to a very small number greater than or equal to 0. |
-cntthresh |
Minimum number of observations in a state for it to be considered in the decision tree building process. |
如果你有一个音素列表含有如下音素:
并且你正在训练3状态的HMM,那么你必须创建9个决策树,对应于音素AA,AX,B的每一个状态。每个状态一个决策树。
决策树创建后,它们必须被剪枝到和你想训练的绑定的状态(senones)一样的数目。记住,绑定状态的数目并不包括那些从未绑定的CI状态。在剪枝的处理过程中,在决策树中的那些会导致在似然度上最小增长的分叉点会被渐渐的移掉,并用其父节点代替。被剪去的分支的选择是通过对整个决策树进行完全的采集完成的。决策树的剪枝是通过“prunetree“可执行命令来完成的,它需如下参数:
FLAG |
DESCRIPTION |
-itreedir |
directory in which the full decision trees are stored |
-nseno |
number of senones that you want to train |
-otreedir |
directory to store the pruned decision trees |
-moddeffn |
CD-untied model definition file |
-psetfn |
lingistic questions file |
-minocc |
minimum number of observations in the given tied state. If there are fewer observations, the branches corresponding to the tied state get pruned out by default. This value should never be 0, otherwise you will end up having senones with no data to train (which are seen 0 times in the training set) |
树被剪枝完成后,一个新的模型定义文件将会被创建,这个模型定义文件包含在训练期间可见的所有三音素,有与来自于剪枝后的树的senones所确定的那些三音素相对应的状态。
为了做这,含有来自当前训练字典的所有可能的三音素的模型定义文件被使用[所有的三音素模型定义文件alltriphones model definition file]。这文件在创建CD-untied 模型定义文件的过程中被创建。记住,CD-untied 模型定义文件仅仅包含那些所选择的三音素,不同的门限被用来选择这些三音素。因此,那个文件不能被用来创建CD-tied 模型定义文件,除非你确定CD-untied 模型定义文件包含在训练时所有可见的三音素。绑定状态必须被使用的可执行命令为“tiestate“,它需如下参数:
这里有一个CD-tied 模型定义文件的例子,基于早前被给出的CD-untied 模型定义文件。
所有的三音素模型定义是如下的有39个绑定状态(senone)的CD-tied模型定义文件的基础:
下一步是训练CD-tied模型,以连续模型为例,HMM的状态能够模拟成一个单独的高斯分布或一个混合高斯分布。在一个混合分布中高斯的数量必须被选择为偶数,和一个2的幂(例如,2,4,8,16,32,…)。为了通过一个8高斯的混合来模型HMM的状态,我们首先必须为每一个状态模型训练一个高斯,每个高斯通过轻微的扰乱其均值来分离成2个高斯,这2个高斯用来初始化训练每个状态的2个高斯。在通过扰乱来产生4个高斯,4个高斯被用来训练,再通过对4个高斯扰乱产生8个高斯为每状态模型,再被用来训练。所以对于每个状态 2N 个高斯的CD-tied的模型训练需要N+1步,N+1的每一步包含以下三步:
1. 初始化,2.Baum-Welch迭代后的norm ,3.高斯分离(在N+1是不进行分离的)。
训练从每状态1高斯模型初始化开始,在初始化期间,来自于CI模型参数文件的模型参数被拷贝到CD tied模型参数文件的合适位置。4个模型参数文件被创建,为均值,方差,转移矩阵,混合权重。在初始化期间,特定CI音素的每个状态对在CD –tied模型参数文件中的相同的CI音素的相同状态,以及在CD –tied模型参数文件中的相同的CI音素的所有三音素的相同状态做出了贡献。(CD-tied模型定义文件被用来指向这个映射) The CD-tied model definition file is used asa reference for this mapping.
对每状态1高斯模型的初始化是使用了init-mixw可执行命令,它需如下参数:
执行 baum-welch,norm and Gaussaian splitting的可执行命令为bw,norm和inc-comp。
执行bw所需参数为如下:
FLAG |
DESCRIPTION |
-moddeffn |
CD tied model definition file |
-ts2cbfn |
this flag should be set to ".cont." if you are training continuous models, and to ".semi." if you are training semi-continuous models, without the double quotes |
-mixwfn |
name of the file in which the mixture-weights from the previous iteration are stored. Full path must be provided |
-mwfloor |
Floor value for the mixture weights. Any number below the floor value is set to the floor value. |
-tmatfn |
name of the file in which the transition matrices from the previous iteration are stored. Full path must be provided |
-tpfloor |
Floor value for the transition probabilities. Any number below the floor value is set to the floor value. |
-meanfn |
name of the file in which the means from the previous iteration are stored. Full path must be provided |
-varfn |
name of the file in which the variances fromt he previous iteration are stored. Full path must be provided |
-dictfn |
Dictionary |
-fdictfn |
Filler dictionary |
-ctlfn |
control file |
-part |
You can split the training into N equal parts by setting a flag. If there are M utterances in your control file, then this will enable you to run the training separately on each (M/N)th part. This flag may be set to specify which of these parts you want to currently train on. As an example, if your total number of parts is 3, this flag can take one of the values 1,2 or 3 |
-npart |
number of parts in which you have split the training |
-cepdir |
directory where your feature files are stored |
-cepext |
the extension that comes after the name listed in the control file. For example, you may have a file called a/b/c.d and may have listed a/b/c in your control file. Then this flag must be given the argument "d", without the double quotes or the dot before it |
-lsnfn |
name of the transcript file |
-accumdir |
Intermediate results from each part of your training will be written in this directory. If you have T means to estimate, then the size of the mean buffer from the current part of your training will be T*4 bytes (say). There will likewise be a variance buffer, a buffer for mixture weights, and a buffer for transition matrices |
-varfloor |
minimum variance value allowed |
-topn |
no. of gaussians to consider for likelihood computation |
-abeam |
forward beamwidth |
-bbeam |
backward beamwidth |
-agc |
automatic gain control |
-cmn |
cepstral mean normalization |
-varnorm |
variance normalization |
-meanreest |
mean re-estimation |
-varreest |
variance re-estimation |
-2passvar |
Setting this flag to "yes" lets bw use the previous means in the estimation of the variance. The current variance is then estimated as E[(x - prev_mean)2]. If this flag is set to "no" the current estimate of the means are used to estimate variances. This requires the estimation of variance as E[x2] - (E[x])2, an unstable estimator that sometimes results in negative estimates of the variance due to arithmetic imprecision |
-tmatreest |
re-estimate transition matrices or not |
-feat |
feature configuration |
-ceplen |
length of basic feature vector |
执行norm所需的参数如下:
FLAG |
DESCRIPTION |
-accumdir |
Intermediate buffer directory |
-feat |
feature configuration |
-mixwfn |
name of the file in which you want to write the mixture weights. Full path must be provided |
-tmatfn |
name of the file in which you want to write the transition matrices. Full path must be provided |
-meanfn |
name of the file in which you want to write the means. Full path must be provided |
-varfn |
name of the file in which you want to write the variances. Full path must be provided |
-ceplen |
length of basic feature vector |
执行inc-comp的参数如下:
FLAG |
DESCRIPTION |
-ninc |
how many gaussians (per state) to split currently. You need not always split to double the number of Gaussians. you can specify other numbers here, so long as they are less than the number of Gaussians you currently have.This is a positive integer like "2", given without the double quotes |
-ceplen |
length of the base feature vector |
-dcountfn |
input mixture weights file |
-inmixwfn |
input mixture weights file |
-outmixwfn |
output mixture weights file |
-inmeanfn |
input means file |
-outmeanfn |
ouput means file |
-invarfn |
input variances file |
-outvarfn |
output variances file |
-feat |
type of feature |
矢量量化需两步才能完成,在第一步,对于量化的矢量空间特征向量被积累(积聚)。并不是所有的特征向量都被使用。相当多的可用的或一个可用的矢量采样被得到通过“agg-seg“可执行命令,这个可执行命令把矢量简单的聚集在一个缓存(缓存文件)中。执行它需设置一下标志:
FLAG |
DESCRIPTION |
-segdmpdirs |
directory in which you want to put the aggregate buffer |
-segdmpfn |
name of the buffer (file) |
-segtype |
all |
-ctlfn |
control file |
-cepdir |
path to feature files |
-cepext |
feature vector filename extension |
-ceplen |
dimensionality of the base feature vector |
-agc |
automatic gain control factor(max/none) |
-cmn |
cepstral mean normalization(yes/no) |
-feat |
type of feature. As mentioned earlier, the 4-stream feature vector is usually given as an option here. When you specify the 4-stream feature, this program will compute and aggregate vectors corresponding to all streams separately. |
-stride |
how many samples to ignore during sampling of vectors (pick every stride'th sample) |
矢量量化的第二步,一个 Expectation-Maximization(EM) algorithm(期望最大算法)被用来把聚合的特征流分隔入一个由N个高斯组成的码本中。通常N是2的幂,使用这平常的是N=256.数字256在原则上是可变化的,但是这个选择并没有被sphinx-II解码器提供。所以如果你想使用sphinx-II解码器,但是训练模型使用的是sphinx-III训练器,你必须使用N=256.这已经被研究所观察到了使用256码字码本所创建的模型对于好的识别是足够的。码字数量的增加也许会引起数据不足的问题。在许多情况下,选择训练半连续模型(而非连续模型)是因为训练数据的不足够所引起的。考虑到一个实际的情况,码本数量的增加会加重由数据不足所引起的估计问题。请慎重的考虑这个问题当你决定增大N时。
在sphinx-III中,EM步骤的完成是通过k-means算法完成的,k-means算法是通过可执行命令“kmeans-init“完成的。所以使用kmeans-init命令就行了。它需通常需设置以下标志:
矢量量化完成后,你必须flat-initialize(平滑初始化)你的声学模型,为训练的实际第一步做好准备。下面的步骤解释了flat-initialize的处理:
Thisprocedure is the same as described for continuous models.
Thisprocedure is the same as described for continuous models.
在flat(平滑)初始化中,对于所有状态的所有混合权重都被设置成相等的,所有状态转移概率也被设置成是相等的。与在连续模型中的不一样,码本高斯的均值和方差并不被给予全局值,因为它们在矢量量化的步骤中从数据中被估计出来的。为了flat初始化混合权重,每一个特征流的每一混合权重分布的每一部分被设置成一个等于1/N的数字,N是码本的长度。混合权重和转移矩阵被初始化通过使用mk-flat可执行命令。它需如下参数:
FLAG |
DESCRIPTION |
-moddeffn |
CI model definition file |
-topo |
HMM topology file. |
-mixwfn |
file in which you want to write the initialized mixture weights |
-tmatfn |
file in which you want to write the initialized transition matrices |
-nstream |
number of independent feature streams, for continuous models this number should be set to "1", without the double quotes |
-ndensity |
codebook size. This number is usually set to "256", without the double quotes |
这个过程和在连续模型中所描述的是一样的,除了:
1, 对于bw可执行命令,-tst2cbfn, -topn and –feat标志必须被设置成下列值:
FLAG |
VALUE |
-tst2cbfn |
.semi. |
-topn |
This value should be lower than or equal to the codebook size. It decides how many components of each mixture weight distribution are used to estimate likelihoods during the baum-welch passes. Itaffects the speed of training. A higher value results in slower iterations |
-feat |
The specific feature type you are using to train the semi-continuous models |
2, 对于norm可执行命令,feat标志被设置成以下值
FLAG |
VALUE |
-feat |
The specific feature type you are using to train the semi-continuous models |
需记住,与码本均值和方差相关的重估的均值和方差是很重要的。在半连续模型中,在训练中,码本也可以被重估。因此对于码本来说,矢量量化仅仅只是一个初始化得步骤。这个事实影响我们自适应模型的方式在半连续的情况下。
这个过程的处理与在连续模型中描述的是一样。
Thisprocedure is the same as described for continuous models.
这个处理过程与连续模型描述的是一样的。
Thisprocedure is the same as described for continuous models.
这个处理过程与在连续模型中的描述一样。
Thisprocedure is the same as described for continuous models.
31 为共享参数创建决策树BUILDING DECISION TREES FOR PARAMETER SHARING
这个处理过程与在连续模型中的描述一样。
Thisprocedure is the same as described for continuous models.
32 创建语言问题 GENERATING THELINGUISTIC QUESTIONS
这个处理过程与在连续模型中的描述一样。
Thisprocedure is the same as described for continuous models.
33 对决策树进行剪枝 . PRUNING THEDECISION TREES
这个处理过程与在连续模型中的描述一样。
Thisprocedure is the same as described for continuous models
34 创建CD tied模型定义文件CREATING THE CD TIED MODEL DEFINITION FILE
这个处理过程与在连续模型中的描述一样。
Thisprocedure is the same as described for continuous models
在初始化中,来自于CI模型参数文件的模型参数被拷贝到CD tied模型参数文件的合适的位置。4个模型参数文件被创建,它们是,均值,方差,混合权重和转移矩阵。在初始化中,一个特定的CI音素的每一个状态对来自CD tied模型参数文件的相同的CI音素的相同的状态和来自CD tied模型参数文件的相同的CI音素的所有三音素相同的状态做有贡献。CD-tied模型定义文件是对这个映射的一个引用。
CD-tied训练的初始化是通过执行“init-mixw”可执行命令来完成的。它需如下参数:
-src_moddeffn |
source (CI) model definition file |
-src_ts2cbfn |
.semi. |
-src_mixwfn |
source (CI) mixture-weight file |
-src_meanfn |
source (CI) means file |
-src_varfn |
source (CI) variances file |
-src_tmatfn |
source (CI) transition-matrices file |
-dest_moddeffn |
destination (CD tied) model def inition file |
-dest_ts2cbfn |
.semi. |
-dest_mixwfn |
destination (CD tied) mixture wei ghts file |
-dest_meanfn |
destination (CD tied) means file |
-dest_varfn |
destination (CD tied) variances fi le |
-dest_tmatfn |
destination (CD tied) transition matrices file |
-feat |
feature configuration |
-ceplen |
dimensionality of base feature vector |
删除代替插入是创建半连续模型的最后一步。删除代替插入的输出是一个sphinx-3格式的半连续模型。如果你想在sphix-II的解码器中使用它们的话。你需把sphinx-3格式的半连续模型转换成sphinx-2格式的才行。
删除代替插入是一个在CD和CI混合权重之间的用来减少过度适合的影响的代替插入的迭代处理。数据被分成2个集合,来自于一个集合的数据被用来估计来自于另一个集合的CI和CD训练模型之间的最佳代替插入因子。然后两个数据集进行交换,这过处理过程被重复,使用上一个估计的代替插入因子来对当前的步骤进行初始化。交换被持续进行直到代替插入因子收敛。
为了做这,我们需要2个平衡的数据集合。不管怎样,我们使用Bauim-Welch缓存来代替实际的数据,因为它们相关的数学计算是很方便的。因此我们需要一个“偶数“的数量的buffers(缓存),它能够被分组成2个集合。如果你只有一个缓存(buffer)则DI就不能被执行。不管怎样,在训练的最后迭代中,我们必须在(至少)2个部分(parts)上进行训练。你能够连续的这样做以至于BW后训练的最后一次迭代收敛,在一个non-lsf 计划(调整|安排)。
注意在每一次Baum-Welch迭代结束时,norm可执行命令被用来计算来自buffers的模型,但是这并不要求偶数数量的buffers。BW返回的是最后估计的分子项和分母项。Norm执行实际的除法。Buffers的数量并不重要,但是你需要在BW的偶数迭代结束后运行norm命令,即使你只对一个部分进行训练。当我们有多个parts(部分)时,norm会把来自多个的buffers的分子相加,和分母项,然后做除。
我们可以通过使用sphinx-III包提供的“delint“可执行命令来完成删除代替插入(deleted interpolation)。它需要如下参数:
FLAG |
DESCRIPTION |
-accumdirs |
directory which holds the baum-welch buffers |
-moddeffn |
CD-tied model-definition file |
-mixwfn |
CD-tied mixture weights files |
-cilambda |
initial interpolation factor between the CI models and the Cd models. It is the weight given given to the CI models initially. The values range from 0 to 1. This is typically set to 0.9 |
-ceplen |
dimentionality of base feature vector |
-maxiter |
the number of iterations of deleted-interpolation that you want to run. DI can be slow to converge, so this number is typically between 1000-4000 |
使用半连续模型的决策树被创建后,训练连续模型是有可能的。Ci半连续模型需要被训练为了初始化半连续untied模型。ci连续模型需要被训练为初始化连续tied状态模型。当决策树创建阶段后特征集能够被改变。
A.特征集:这是一个二进制文件,在其中每个矢量的所有元素被顺序的存储。头部是一个4字节的整数用来告诉我们在这个文件中有多少个浮点数。头部后接下来是实际的cepstral(倒普)值(通常是每帧13倒普值,相邻帧之间有10ms的跨度。帧长通常是固定的,一般为25ms)。
文件格式如下:
B.sphinx2半连续(semi-continuous)HMM(SCHMM)的格式:
Sphinx II的SCHMM的格式是相当复杂的,它包含以下几个主要的组成部分(其中每个组成部分都有相应的子组成部分):
a ,一个码本集
b,一个“sendump”文件,内存储的是状态(senone)分布
c,一个”phone”(音素)文件和一个“map”(映射)文件,map文件把senone映射到三音素的状态。
d,一个“.chmm”文件集合,它存储的是转移矩阵。
1, 码本:这存在8个码本文件。Sphinx-2使用了一个4流特征集:
a. Cepstral (倒普)特征:[c1-c12],(12 个组成部分)
b. delta 特征:[delta_c1-delta_c12,longterm_delta_c1-longterm_delta_c12],(24个组成部分)。
c. power (强)特征:[c0,delta_c0,doubledelta_c0],(3个组成部分)
d. doubledelta 特征:[doubledelta_c-doubledelta_c12],(12个组成部分(12 components))
8码本文件存储了这4特征中每一个得所有高斯的均值和方差。8码本是,
n cep.256.vec[这是cepstral特征的均值文件]
n cep.256.var[这是cepstral特征的方差文件]
n d2cep.256.vec[这是delta cepstral特征的均值文件]
n d2cep.256.var[这是delta cepstral特征的方差文件]
n p3cep.256.vec[这是power特征的均值文件]
n p3cep.256.var[这是power特征的方差文件]
n xcep.256.vec[this is the file of means for the double delta feature]
n xcep.256.var[this is the file of variances for the double delta feature]
所有的文件都是2进制的,并且都有如下格式:[4 byte int] [4 byte float] [4 bytefloat].............. 4字节整数头存储了接下来文件中的浮点数的个数。对于cep.256.var, cep.256.vec, xcep.256.varand xcep.256.vec,这个值应该是3328。 对于 d2cep.*它应该是6400,对于 p3cep.* 它应该是768。 浮点数字是均值矢量(或方差矢量)的组成部分,被安排在end和end之间。So cep.256.[vec,var] have 256 mean (orvariance) vectors, each 13 dimensions long, d2cep.256.[vec,var] have 256mean/var vectors, each 25 dimensions long, p3cep.256.[vec,var] have 256vectors, each of dimension 3, xcep.256.[vec,var] have 256 vectors of length 13each。
cep,d2cep and xcep分布的第一个组成部分不是以似然度计算得,这部分原因是纯历史造成。
2. “sendump”文件:存储的是与每个音素相关的状态的混合权重。这个文件有一个小的ascii 头,这也许会对你有一定的帮助。除了头外,这是一个二进制文件。混合权重都被转换成8位的整数通过如下操作:initmixw=(-log(floatmixw)>>shift) log base(基)是1.0003。这个“shift”是位的数字。最小的混合权重必须右移一般适合8位。“sendump”文件存储,
for each feature (4 features in all)
for each codeword (256 in all)
for each ci-phone (including noise phones)
for each tied state associated with ci phone,
probability of codeword in tied state
end
for each CI state associated with ci phone, ( 5 states )
probability of codeword in CI state
end
end
end
end
“sendump”有如下的存储格式(所有数据,除头字符串外都是二进制):
3.“PHONE”音素文件:音素文件存储的是一系列的被解码器使用的音素和三音素。这是一个ascii 文件,它包含2部分,第一部分列出了再模型中的CI音素,第一部分由格式行组成。
AA 0 0 8 8
“AA”是CI音素,第一个“0”表示这是一个CI音素,第一个“8”是CI音素的索引号,最后一个“8”是在文件中的行号,第二个“0”的存在是由于历史原因。
音素文件的第二部分列出的是三音素,它由格式行组成,
A(B,C)P -1 0 num num2
“A”代表的是中心(中间)音素,“B”是左场景音素,“C”是右场景音素。“P”代表了三音素的位置,它是4个值中的一个,4个值分别是“s“,”b“,”i“和”e“,分别代表了单独字三音素,字的开始三音素,字的内部三音素,字的结束三音素。”-1“表示它是一个三音素而非CI音素。”num“是CI音素”A“的索引号,”num2“是三音素(或CI 音素)(在列表中位置)在文件中的行号(从0开始)。
3. map(映射)文件:“map“文件存储的是一张映射表。这张表显示了每个三音素的每个状态的哪个senone被映射。”map“文件也是一个以行的形式的ascii文件
AA(AA,AA)s<0> 4
AA(AA,AA)s<1> 27
AA(AA,AA)s<2> 69
AA(AA,AA)s<3> 78
AA(AA,AA)s<4> 100
第一行显示了在场景“AA“和”AA”中的三音素“AA“的第0个状态被与CI音素AA相关的第4个senone模拟。注意,CI音素的编号是确定的。所以“AX“的第4个senone也将被编号为4(但是这不应该引起混淆)。
4. chmm 文件:每一个ci音素一个*.chmm文件。每一个chmm文件存储的是与特定ci音素相关的转移矩阵(注意,与一个ci音素相关的共享它的转移矩阵)(所有的数字都是4字节的整数)。文件是以二进制形式存储的。
u -10(一个头显示这是一个tmat文件)
u 256(码字数)(no of codewords)
u 5(发射状态数)
u 6(总状态数,包括非发射状态)
u 1(初始状态编号,在fbs8中,一个状态序列仅是从state[0]开始的(In fbs8 a statesequence can only begin with state[0].)。所以尽有一个可能的初始状态。)
u 0(初始状态列表,这只有一个,也就是状态0)
u 1(终止状态编号。这只有一个非发射终止状态)
u 5(终止状态id。对于5状态HMM来说是5)
u 14(被拓扑所允许的非0转移的总数 total no.of non-zero transitions allowed by topology)
这总共有65个整数,所有每一个chmm文件应该是65*4=260字节长。
对于模型集,在模型文件中的所有senone-id是和与相应的模型定义文件的引用一起的(All senone-ids in the modelfiles are with reference to the corresponding model-definition file for themodel-set.)
均值文件
对于3状态,每状态8高斯的HMM的ascii的均值文件看上去如下(looks like this):
这是什么意识了,请以左到右,从上到下的方式读:
Parameters for 602 tied-states (or senones), 1 feature stream, 8Gaussians per state.(参数为602个绑定状态(或senone),1个特征流,每状态8个高斯流)。
Means for senoneno.0, feature-stream no.0. Gaussian density no.0,followed by its 39-dimensional mean vector. (Note that each senone is a mixtureof 8 gaussians, and each feature vector consists of 13 cepstra, 13delta cepstra and 13 double delta cepstra)
编号为0的senone,特征流,高斯密度,随后跟着的是它的39维的均值矢量。(注意每一个senone有8个高斯的混合高斯,每一个特征流由13维cepstra,13 delta cepstra and 13 double deltacepstra)。
方差文件
方差文件和均值文件的格式是完全一样的。
混合权重文件
对于3状态,每状态8高斯的HMM,其ascii权重文件如下所示:
请从左到右,从上到下看:
Mixtrue weightsfor 602 tied-states (or senones), 1 feature stream, 8 Gaussians per state (Eachmixture weight is a vector with 8 components)。(混合权重为602个senones,1特征流,每状态8个高斯(每个混合权重是一个有8个部分的矢量))。
Mixture weightsfor senone no. 0, feature-stream no. 0, number of times this senone occured inthe training corpus (instead of writing normalized values, this number isdirectly recorded since it is useful in other places during training[interpolation, adaptation, tree building etc]). When normalized (for example,by the decoder during decoding), the mixture weights above would read as: mixw602 1 8 mixw [0 0] 7.434275e+03 1.170e-01 1.228e-01 1.048e-01 1.546e-011.240e-01 1.297e-01 1.395e-01 1.076e-01 mixw [1 0] 8.172642e+03 1.093e-011.171e-01 1.450e-01 1.238e-01 1.450e-01 1.167e-01 9.321e-02 1.499e-01。
对于标号为0的senone,特征流,这个senone在训练语料库中出现的次数(代替写规范化得值,这个数字是被直接记录的因为它对训练中的其它步骤[代替插入,自适应,树的创建等]是有用的)。当规范化时(例如,在解码中通过解码器),上面的是这样读的:mixw 602 1 8 mixw [0 0] 7.434275e+031.170e-01 1.228e-01 1.048e-01 1.546e-01 1.240e-01 1.297e-01 1.395e-01 1.076e-01mixw [1 0] 8.172642e+03 1.093e-01 1.171e-01 1.450e-01 1.238e-01 1.450e-011.167e-01 9.321e-02 1.499e-01。
转移矩阵文件
ascii 文件看上去是这样的(The ascii file looks like this):
从左到右,从上到下读:转移矩阵为,34个HMM,每一个有4个状态(3个发射状态,一个非发射状态)。
转移矩阵为,编号为0的HMM(注意这是HMM编号,而非senone的编号),矩阵。
在所有的模型文件中,13维的cepstra ,13 dimensional delta cepstraand 13 dimensional double-delta cepstra are arranged以如下顺序被安排:ls_12c_12d_3p_12dd(在解码器标志中你可能使用s3_lx39来表示它)。字符串格式方式:1特征流, 12 cepstra, 12 deltacepstra, 3power 和12doubledeltacepstra。power部分由cepstral矢量的第0部分,d-cepstral矢量的第0部分,dd-cepstral矢量的第0组成部分组成。
In the quantizedmodels, you will see the string 24,0-11/25,12-23/26,27-38 In this string, theslashes are delimiters. The numbers represent various components occuring ineach of the 3 codebooks. In the above string, for instance, the first codebookis composed of the 24th component of the feature vector (s3_1x39) followed bycomponents 0-11. The second codeword has components 25, followed by components12-23, and the third codeword is composed of components 26 and 27-28. Thisbasically accounts for the odd order in s3_1x39. By constructing the codewordsin this manner, we ensure that the first codeword is composed entirely ofcepstral terms, the second codeword of delta cepstral terms and the thirdcodeword of double delta terms.
在量化模型中,你将会看到这样的字符串—24,0-11/25,12-23/26,27-38。在这个字符串中斜杠(斜线)是定界符。数字表示在3个码本的每个码本中出现的不同的组成部分(成分)。以上述字符串为例,第一个码本由特征矢量(s3_1x39)的第24个组成部分跟随着0-11(组份)组成部分组成。第二个码本由25成分(components)跟随者12-23成分组成。第三码本由26和27-28成分组成。这主要依赖有在s3_1x39中奇数的顺序。以这种方式构建的码字,我们能够确保第一个码字完全由cepstral项组成,第二个由delta cepstral组成,第三个由double delta cepstral 组成。
s3_1x39是过去的顺序,它能够被你写的任何新的code(编码)处理。以不同的顺序写的特征矢量组成部分(成分)对语音识别,训练,测试特征(幅度)formats没有影响。
一旦你有任何语音的声学数据和相应的脚本,及一个把在脚本中的字转换成子字单元(或者仅仅是把它们映射到看上去合理的声学单元)的字典,你就能够使用SPHINX来为那种语音训练声学模型。你不需要做其它的任何事情。
在决策树创建过程中需要的语言问题(linguistic question)由SPHIN自动设计。考虑到你为模型选择的声学单元,SPHINX能自动的那些单元的最好的组合以便组成问题。SPHINX使用的混合算法能够聚集CI音素的状态分布来获得三音素场景的语言问题。如果你想为那些其音素结构你不是很了解以至于不能设计你自己的音素类(或如果一个语音学家不能帮助你)的语言训练模型,那么这是非常有用的。一个更加重要的优势是:算法能够有效的使用在环境中,这种环境是子字单元不是按发音来构建即不是根据发音来写的。因此你能够使用任何看上去合理的声学单元为了你的目标。
如果你完全丢失了关于声学单元的东西,但是你有在脚本中的全部(或大部分)字的训练训练数据,你可以建立字模型而非子字模型。你不需一定要创建决策树( You do not have to builddecision trees)。字模型通常是场景独立的模型,所以你仅仅只需通过CI训练。字模型有一些限制,它们在这手册的非技术版本中讨论。
训练字典中的不一致将会导致一个坏的声学模型。不一致来源于音素集中那些在我们的识别器的模型空间中混淆音素的使用。为了获得你使用的音素的混淆性的概念,应该看在训练中utterance(言论)中每帧的log似然度。在字典中大量的音素一般会导致高的似然度。If you have abaseline to compare with, and this is *not* the case,(如果你有一个有来与之比较的基,这不是那个情况)它意味着音素集币模型空间更加分散(更加密集,如果你为一个更小的音素集观察其反面),并且相应的分布就更广(sharper in theother case)。一般随着在一个utterance中的使用的分布数的减少,差异会变得越来越大。(The distributions flattenout since the areas under the distributions are individually conserved (tounity) and so the overall per frame likelihoods are expected to be lower.)分布变得平坦,因为在分布下的区域是保守的,所以每帧的总体的似然度会变小。
解决方案是修正音素集,依据一个小以一种更加紧密的方式覆盖声学空间的音素集来重写字典。一种方式是使用一个更小的可改变的音素集,使用更长的声学单元。更好的方式在研究中。但是如果你是那种语言的本土说话人即那种语言是你的母语,并且你对声音有很好的感知,那么你的直接也将起作用。SPHINX能够为你提出的任何新的音素集训练模型。
为了把用sphinx3训练器训练的5状态/HMM,4特征流的半连续模型转换成sphinx2格式(与sphinx2解码器匹配的)模型,下面目录的程序必须被编译和使用:
-----------------------------------------------------------------------
program directory corresponding function
executable of executable
-----------------------------------------------------------------------
mk_s2cb mk_s2cb makes s2 codebooks
mk_s2hmm mk_s2hmm makes s2 mixture weights
mk_s2phone mdef2phonemap makes phone and map files
mk_s2seno makesendmp makes senone dmp files
-----------------------------------------------------------------------
Variables needed:
-----------------
s2dir : sphinx_2_format directory
s3dir : sphinx_3_format directory
s3mixw : s3dir/mixture_weights
s3mean : s3dir/means
s3var : s3dir/variances
s3tmat : s3dir/transition_matrices
s3mdef : s3dir/mdef_file (MAKE SURE that this mdef file
includes all the phones/triphones needed for
the decode. It should ideally be made from
the decode dictionary, if the decode vocabulary
is fixed)
Usage:
------
mk_s2cb
-meanfn s3mean
-varfn s3var
-cbdir s2dir
-varfloor 0.00001
mk_s2hmm
-moddeffn s3mdef
-mixwfn s3mixw
-tmatfn s3tmat
-hmmdir s2dir
makesendmp
s2_4x $s3mdef .semi. $s3mixw 0.0000001 $s2dir/sendump
(the order is important)
cleanup: s2dir/*.ccode s2dir/*.d2code s2dir/*.p3code s2dir/*.xcode
mdef2phonemap
grep -v "^#" s3mdef | mdef2phonemap s2dir/phone s2dir/map
确保在上述程序使用的mdef文件包括所有需要的三音素。如果来自于mdef文件的任何绑定状态丢失,那么程序(尤其是makesendmp程序)将不会工作。如果你被模型提供的字典而使用别的字典来创建一个三音素列表,则上述事件将会发生即程序不会工作。即使你使用了相同的音素,足够多的三音素的丢失会导致被剪枝的树的一些叶子被删除。(因为我们不能关联任何新的三音素的状态)。为了避免这种情况的发生,请使用提供的字典。你也许会加入新的字来扩展字典。
43 更新以存在的模型设置或自适应以存在的模型集UPDATING OR ADAPTING EXISTINGMODELS SETS
一般,如果有足够的数据(至少8-10小时)可用,那么训练说话人确定的模型会更好。如果你缺少某一说话人或某一领域的数据,那么使用你有的以存在的模型来自适应数据是个更好的选择。自适应的精确性依赖于你使用的声学模型的类别(种类)。如果你使用的是半连续模型,adaptation could be performed by interpolating speaker specific modelswith speaker-independent models.(自适应被执行通过插入说话人确定模型用说话人独立模型),对于连续HMM,你应该使用MLLR,或它的一个变种。为自适应或更新半连续模型,需采用以下步骤:
A,为新的训练数据计算其特征,特征的计算需要与你已有模型的特征的计算方式一样。事实上,对目前为止,在两种情况的特征的计算是完全一样的。
B,为新的数据准备脚本和字典,字典必须含有被训练模型使用的相同的音素集。脚本也必须以相同的方式准备。如果你有一个新的填充音素,那么填充字典必须把它映射到旧的填充音素。
C,新的训练脚本和相关的控制文件能够包括旧的训练数据,如果所有你正在做的是使用附加的来源于相同领域(你最近所要求的)的数据。如果你对轻微不同的领域或轻微不同的声学条件自适应,那么你只需使用新的数据。
D,从以存在的 deleted-interpolated模型开始,使用相同的tied mdef文件,使用相同的训练参数像差分特征,运行通过1或2次的Baum-Welch(传递)的passes。不管怎样这必须被做除了重估均值和方差外。仅仅只有混合权重被重估。如果你在进行了Baum-Welch算法后正在运行norm,你必须确保norm仅仅对混合权重进行规范化。
E,一旦混合权重被重估,新的混合权重必须被(篡改)interpolated 用你过去开始的那个。“mixw-interp”可执行命令用来做这件事。你可以用不同的混合权重来进行试验,以选择最佳的那个。最是最简单的进行更新或自适应技术的过程。更加成熟的技术将在接下介绍.
“mixw-interp”可执行命令:
它被用于模型的自适应为两混合权重文件进行 (插入代替)interpolating。它需如下参数:
FLAG |
DESCRIPTION |
-SImixwfn |
The original Speaker-Independent mixture weights file |
-SDmixwfn |
The Speaker Dependent mixture weight file that you have after the bw iterations for adaptation |
-tokencntfn |
The token count file |
-outmixwfn |
The output interpolated mixture weight parameter file name |
-SIlambda |
Weight given to SI mixing weights |
44 在sphinx-III的解码器中使用半连续和连续模型USINGTHE SPHINX-III DECODER WITH SEMI-CONTINUOUS AND CONTINUOUS MODELS
这里有两个标志被用来确认模型的类型,其它的标志是独立于模型类型的。从连续模型到半连续模型你必须改变的标志是:
A.“-senmgaufn”标志应该从“.count”改变成”.semi”。
B.”-flat”标志应该从你使用的连续模型的特征改变成你使用的半连续模型的特征(通常,s3_139是连续模型的, s2_4x是半连续模型的)。
其它的一些解码器的标志和常用设置如下所示:
-logbase 1.0001 \
-bestpath 0 \
-mdeffn $mdef \
-senmgaufn .cont. \
-meanfn $ACMODDIR/means \
-varfn $ACMODDIR/variances \
-mixwfn $ACMODDIR/mixture_weights \
-tmatfn $ACMODDIR/transition_matrices \
-langwt 10.5 \
-feat s3_1x39 \
-topn 32 \
-beam 1e-80 \
-nwbeam 1e-40 \
-dictfn $dictfn \
-fdictfn $fdictfn \
-fillpenfn $fillpenfn \
-lmfn $lmfile \
-inspen 0.2 \
-ctlfn $ctlfn \
-ctloffset $ctloffset \
-ctlcount $ctlcount \
-cepdir $cepdir \
-bptblsize 400000 \
-matchsegfn $matchfile \
-outlatdir $outlatdir \
-agc none \
-varnorm yes \
在sphinx中许多的发音是不能自动被考虑的,你必须标志正确的发音在脚本中,并且插入sliences在字间。为了这样
A) 移除non-silence填充从填充字典中,把它们放入规律字典中。
B) 移除所有的silence 标志(<s>,<sil>,和</s>)从训练脚本中。
For faligning with semi-continuous models,使用了二进制“s3align”被训练包所提供的,并有如下标志被设置。 For faligning withcontinuous models,改变标志-senmgaufn(.cont.),-topn (no. ofGaussians in the Gaussian mixture modeling each HMM state),-feat (the correct feature set):