AIBigKaldi(八)| Kaldi的解码图构造(下)(源码解析)

本文来自公众号“AI大道理”。

L.fst与G.fst经过合成、确定化、最小化、权重推移和随机性检查后成为了LG.fst。
紧接着加入C,构造了CLG.fst。
接下来继续加入H,构造HCLG.fst。

(本篇主要解析kaldi源码实现,详细算法原理请阅读

AI大语音(十二)——WFST解码器(下)(深度解析))

1 构造Ha

4.3 Ha
4.3.1 make-h-transducer
功能:
构建没有添加自跳转的H.fst。
可以使用add-self-loops后续添加。
源码解析:



过程之道:


函数解析:
GetHTransducer(ilabel_info,ctx_dep,trans_model,hcfg,&disambig_syms_out)
H传感器版本不包括自循环;必须在以后添加。
HTransducer对于ilabel_info中的每个符号都有一个单独的输出弧。

2 CLGoHa = HCLGa

4.4 CLGoHa = HCLGa

4.4.1 fsttablecompose(合成算法)
H'oCLG=HCLGa
合成(同LoG=LG)
fsttablecompose $dir/Ha.fst "$clg" |
输入Ha.fst和CLG_1_0.fst通过管道输出给下一个程序。

4.4.2 fstdeterminizestar(确定化算法)
det(HCLGa)
确定化(同LoG=LG)
| fstdeterminizestar --use-log=true |
通过管道接收上一个程序的输出结果作为输入,经过确定化算法再通过管道输出给下一个程序。

4.4.3 fstrmsymbols(去除消歧义符)
rds(det(HCLGa))
功能:
如果没有选项,则使用epsilon替换符号的子集,无论它们出现在FST的哪个位置的输入端。
使用--remove arcs=true,将删除输入中包含这些符号的圆弧。
使用--penemption=<float>,则会将指定的惩罚添加到任何在其输入端具有给定符号之一的弧的成本中。

源码解析:



过程之道:

函数解析:
 RemoveSomeInputSymbols(disambig_in, fst)
RemoveSomeInputSymbols从FST的输入端删除“to_remove”中出现的任何符号,并用epsilon替换它们。

结果之道:
这是一个简单的fst。

使用fstrmsymbol后,fst输入标签ilabel中如果有和列表中的标签一样,则将其用0代替。如原来的3被0代替。


4.4.4 fstrmepslocal(去除空转移)
功能:

删除算法中的一些(但不是全部)epsilon,该算法将始终减少弧+状态的数量。选择在热带或对数半环中保持等价,如果在热带,则在原木或热带中保持随机性。
源码解析:


过程之道:

函数解析:
RemoveEpsLocalSpecial(fst)
RemoveEpsLocal(&log_fst)
RemoveEpsLocal(fst)
RemoveEpsLocal使用一种算法来移除FST中的一些(但不一定全部)epsilon,该算法保证永远不会增加FST中的弧数(也永远不会增加状态数)。
这个算法不是最优的,但相当聪明。
它不仅删除了epsilon弧,还将输入epsilon弧和输出epsilon弧组合成一对。
RemoveEpsLocalSpecial(fst)是RemoveEpsLocal的一种,在转换为LogArc时注意保持随机性。
结果之道:
这是一个简单的fst。

使用fstrmepslocal后,不仅删除了epsilon弧,还将输入epsilon弧和输出epsilon弧组合成一对。



4.4.5 fstminimizeencoded(最小化算法)
min(rds(det(HCLGa)))
最小化(同LoG=LG)
| fstminimizeencoded > $dir/HCLGa.fst.$$
通过管道接收上一个程序的输出结果作为输入,经过最小化算法再输出HCLGa.fst文件。

4.4.6 fstisstochastic(随机性检查)
随机性检查 (同LoG=LG)
fstisstochastic $dir/HCLGa.fst

检查FST是否是随机的,如果是,则成功退出。打印出最大误差(以日志单位为单位)

3 CLGoH = HCLG


4.5 CLGoH = HCLG

4.5.1  add-self-loops(添加自循环)

asl(min(rds(det(HCLG))))

功能:

将自循环和转移概率添加到传感器,扩展到转移ID。

源码解析:


过程之道:

函数解析:

AddSelfLoops(trans_model, disambig_syms_in, self_loop_scale, reorder, check_no_self_loops, fst) 

扩展一个没有自循环的FST,并添加自循环(它还需要修改非自循环的概率,因为没有自循环的图是以随机方式创建的)


结果之道:

4.5.2 make-grammar-fst

(prepare_grammar_command)

功能:

构造GrammarFst并将其写入磁盘(或者将其转换为ConstFst并将其写入磁盘)。

源码解析:


过程之道:

函数解析:

PrepareForGrammarFst(nonterm_phones_offset, fst)

FST需要稍微修改。

此函数准备“ifst”以在GrammarFst中使用:它确保它具有预期的属性,并根据需要稍微更改它。
“ifst”应该是一个完全编译的HCLG图,打算在GrammarFst中使用。

将目标fst实例索引按状态单独存储,而不是按arc存储。

根据需要添加epsilon跃迁来确保状态之前没有最终的prob。

4.5.3  fstconvert(fstconvert-main.cc)

在/kaldi-trunk/tools/openfst-1.6.7/src/bin下面。

功能:

将FST转换为其他类型。

源码解析:


4.5.4 fstisstochastic
随机性检查 (同LoG=LG)
fstisstochastic $dir/HCLG.fst

检查FST是否是随机的,如果是,则成功退出。打印出最大误差(以日志单位为单位)



4 总结


构建了HCLG解码图后,解码识别就是在这个图上寻找一条最优路径。

最优路径上去除epsilon后的输出标签序列就是单词级别的识别结果。

下期预告

AIBigKaldi(九)|  Kaldi的解码识别

往期精选

AIBigKaldi(七)|  Kaldi的解码图构造(上)

AIBigKaldi(六)|  Kaldi的单音子模型训练(下)

AIBigKaldi(五)|  Kaldi的单音子模型训练(上)

AIBigKaldi(四)|  Kaldi的特征提取

AIBigKaldi(三)|  Kaldi的数据准备

AIBigKaldi(二)|  Kaldi的I/O机制

AIBigKaldi(一)|  Kaldi的目录结构

AI大语音(十四)——区分性训练
AI大语音(十三)——DNN-HMM
AI大语音(十二)——WFST解码器(下)
AI大语音(十一)——WFST解码器(上)

AI大语音(十)——N-gram语言模型
AI大语音(九)——基于GMM-HMM的连续语音识别系统
AI大语音(八)——GMM-HMM声学模型
AI大语音(七)——基于GMM的0-9语音识别系统
AI大语音(六)——混合高斯模型(GMM)
AI大语音(五)——隐马尔科夫模型(HMM)
AI大语音(四)——MFCC特征提取
AI大语音(三)——傅里叶变换家族
AI大语音(二)——语音预处理
AI大语音(一)——语音识别基础

 ——————

浅谈则止,细致入微AI大道理

扫描下方“AI大道理”,选择“关注”公众号

—————————————————————

​     

—————————————————————

投稿吧   | 留言吧



原文地址:https://www.cnblogs.com/AIBigTruth/p/14203366.html