Kaldi脚本分析(6)——解码图构建

静态解码图构建的过程,就是将数据准备和预编译阶段得到的词典FST、语言模型FST、声学建模阶段得到的HMM拓扑FST以及可能的上下文关系FST,通过如下的公式进行组合优化处理,得到最终的HCLG图。Kaldi中对FST的很多操作与参考文献[1]中稍有不同,尤其是对消歧符号和权重推移等的处理上。



其中,G为语言模型FST,输入输出标签相同,都是词,本质为FSA。

L为词典FST,输入标签为音素,输出标签为词(多音词由权重区分,同音词由词尾消歧符号区分);

C为上下文FST,输入标签为上下文音素(初始状态只有右侧上下文,结束状态只有左侧上下文),输出标签为单音素,为上下文音素中的中间音素;

H为HMM定义的声学FST,H’表示不带自环的声学FST,输入标签为trans-id(其中编码了trans-state,pdf-id等信息),输出标签为上下文音素;

o表示FST组合操作;

det表示FST确定化操作;

min表示FST最小化操作;

rds表示去除消歧符号;

asl表示增加自环转移。

上述为标准处理方法,但是,有很多细节需要进一步说明。首先,我们需要保证输出的HCLG是确定化且是最小化的(determinized and minimized),确定化通过插入消歧符号实现。同时,我们还要尽可能保证HCLG是随机的(stochastic,即从每个状态输出的概率之和为1),在传统方法中,随机性通过“权重推移”操作实现,但在Kaldi中,通过保证G的随机性以及构建过程中每个步骤都不丢失随机性来实现,Kaldi的实现方法避免了“权重推移”可能出现失败的问题,确保了组合后的HCLG不会比G本身的随机性更差。



解码图构建主要涉及的脚本文件为mkgraph.sh:

Ø  输入:lang文件夹,模型文件final.mdl,决策树文件tree

Ø  输出:解码图文件../graph/HCLG.fst

utils/mkgraph.sh--mono data/lang_test_bg exp/mono exp/mono/graph  #以单音素模型为例

 

Ø  上述三个参数:$1=data/lang_test_bg, $2=exp/mono,$3=exp/mono/graph,前两个为输入文件夹,后一个为输出文件夹。从输入文件夹$1中提取语言模型、词典、音素列表、词列表等,$2中提取上下文决策树和声学模型。输出文件夹$3保存HCLG.fst。

lang=$1

tree=$2/tree

model=$2/final.mdl

dir=$3

 

 

具体实现步骤如下:

Ø  设置转移概率尺度,普通转移和自转移分开设置。

tscale=1.0      #转移概率尺度设置

loopscale=0.1   #自转移概率尺度设置不同

 

Ø  检测是否所有输入列表中要求的文件都具备。

#输入列表,其中lang文件夹下的文件来自于数据准备阶段,模型和决策树来自于建模阶段

$lang/L.fst          #词典fst

$lang/G.fst          #语言模型fst

$lang/phones.txt     #音素列表,存储音素文本到音素id的映射

$lang/words.txt      #词列表,存储词文本到音素id的映射

$lang/phones/silence.csl   #静音id列表

$lang/phones/disambig.int  #消歧符号id列表

$model         #最终模型文件final.mdl

$tree           #决策树文件  

 

Ø 检测输出路径中是否已经有HCLG.fst文件,避免覆盖。

Ø  将词典L.fst和语言模型G.fst组合(fsttablecompose),然后进行确定化(fstdeterminizestar)和最小化(fstminimizeencoded),得到LG.fst,并确保结果stochastic,即从每个状态输出的转移概率之和为1。

  组合的作用:将每个word扩展到phone级别。(输入标签为)

  确定化的作用:在每个语言模型的状态(word)下,构建树结构的词典。

  最小化的作用:类似后缀共享(suffix-sharing)。

  上述操作的部分C++代码是Kaldi中另写的代码,与OpenFst库中代码稍有不同,包括:

  •   fsttablecompose与fstcompose类似,但是速度更快;
  •   fstminimizeencoded更便捷;
  •   fstdeterminizestar与fstdeterminize类似,但其中包含空转移去除处理;

  fsttablecompose$lang/L_disambig.fst$lang/G.fst | fstdeterminizestar --use-log=true | \

    fstminimizeencoded | fstpushspecial | \

    fstarcsort --sort_type=ilabel >$lang/tmp/LG.fst ||exit 1;

  fstisstochastic$lang/tmp/LG.fst ||echo"[info]: LG not stochastic."

 

Ø 将上下文C.fst和LG.fst组合(fstcomposecontext)得到CLG.fst,并确保结果stochastic。

  fstcomposecontext --context-size=$N --central-position=$P \

   --read-disambig-syms=$lang/phones/disambig.int \

   --write-disambig-syms=$lang/tmp/disambig_ilabels_${N}_${P}.int \

    $lang/tmp/ilabels_${N}_${P}<$lang/tmp/LG.fst|\

    fstarcsort --sort_type=ilabel >$clg

  fstisstochastic$clg  ||echo"[info]:CLG not stochastic."

 

Ø 基于HMM拓扑结构、转移概率和决策树,构建不带自转移的声学模型Ha.fst(make-h-transducer),每个转移的输入标签为“trans-id”(编码了“GMM模型的pdf-id和音素信息”)。

  make-h-transducer --disambig-syms-out=$dir/disambig_tid.int \

    --transition-scale=$tscale$lang/tmp/ilabels_${N}_${P}$tree$model \

     >$dir/Ha.fst  ||exit 1;

 

Ø 将不带自转移的声学模型Ha.fst和CLG.fst组合(fsttablecompose),然后进行确定化(fstdeterminizestar),去除消歧符号,去除空转移,然后进行最小化(fstminimizeencoded),得到HCLGa.fst,并确保结果stochastic。

  fsttablecompose$dir/Ha.fst"$clg" |fstdeterminizestar --use-log=true \

    | fstrmsymbols$dir/disambig_tid.int | fstrmepslocal | \

     fstminimizeencoded >$dir/HCLGa.fst ||exit 1;

  fstisstochastic$dir/HCLGa.fst ||echo"HCLGa is not stochastic"

 

Ø 增加每个HMM状态的自转移,从HCLGa.fst得到HCLG.fst。在最后一步加入自转移使得前面几步可以构建较大的解码图。选项reorder将自转移放在其他状态转移之后,加快解码速度。并确保最终结果stochastic。

  add-self-loops --self-loop-scale=$loopscale --reorder=true \

$model <$dir/HCLGa.fst >$dir/HCLG.fst ||exit 1;

fstisstochastic$dir/HCLG.fst ||echo"[info]:final HCLG is not stochastic."

 


[1] Mohri M, Pereira F, Riley M. Speech Recognitionwith Weighted Finite-State Transducers[M]. Springer Berlin Heidelberg, 2008.


你可能感兴趣的:(语音识别,kaldi)