Kaldi的解码搜索(源码解析)
构建了HCLG解码图后,解码就是在这个图上寻找一条最优路径。最优路径上去除epsilon后的输出标签序列就是单词级别的识别结果。本篇主要剖析kaldi源码实现。解码
decode.sh
https://p26.toutiaoimg.com/large/pgc-image/0c18022357f94a48baa04d95e270cc38
源码剖析:
https://p26.toutiaoimg.com/large/pgc-image/ae4678e420c34009b33280ff18eebc89
过程:
https://p5.toutiaoimg.com/large/pgc-image/4d5b848e6b6d4f84b5f6ca4e968dff04
Viterbi静态解码
功能:使用基于GMM的模型对特性举行解码。接纳维特比算法举行解码,仅产生线性序列。产生的任何lattice都是线性的,即只有一个解码结果。输入:GMM声学模型、HCLG.fst解码图、测试语音声学特性输出:解码结果(词序列、对齐序列、lattice)
过程之道:
https://p26.toutiaoimg.com/large/pgc-image/beaddb8c0be7463cb84db85b9206261c
1)解码第一帧时,从状态节点0出发,首先举行ProcessEmitting处置处罚的发射状态转移弧,节点0转移到节点3、2、6。接着ProcessNonemitting沿着虚线非发射转移弧将6传播到同一时候下的状态节点1。
2)解码第二帧时首先切换Token列表,把cur_toks列表转变到pre_toks列表后,将cur_toks置空。然后再举行ProcessEmitting、ProcessNonemitting。
3)随着时间的推移,帧地举行,到达末了一帧,选择最低累计代价的Token,然后以次Token回溯最优路径。
kaldi的gmm-decode-simple实现了这个过程。
https://p6.toutiaoimg.com/large/pgc-image/c4cb8713cb4d4a62addc36fb4e7cfaa5
函数剖析:
1)decoder.Decode(&gmm_decodable)
解码过程:
https://p6.toutiaoimg.com/large/pgc-image/dd72744e130f4724a4657000b30aa8a3
https://p6.toutiaoimg.com/large/pgc-image/9e8877ddb8fc4a0aba181d017e3dcbf8
https://p26.toutiaoimg.com/large/pgc-image/d8be4a6c22a64ecb93de13e7953ac3e9
● DecodableAmDiagGmmScaled gmm_decodable()
根据声学模型,计算出某一帧的声学分数。声学得分是通过高斯混淆概率密度函数计算得到的。
● GetBestPasth()
根据末了一个token举行回溯,得到解码结果。
把结果放到这个词格中,词格中是单一路径。
● GetLinearSymbolSequence(decoded,NULL,&words,NULL)
从线性词格中取出结果,写入到words中。words中是word ID,要根据辞书把id真正转化为单词序列,得到末了的结果。
Lattice静态解码
gmm-latgen-faster功能:
解码识别:基于GMM模型生成lattices网格,生存N-best路径。(不能保证viterbi给的最优路径就是真正的对的路径)
源码剖析:
https://p3.toutiaoimg.com/large/pgc-image/55fd3eb040f447b58e5f13dcbeee83fd
https://p6.toutiaoimg.com/large/pgc-image/89c29147ba5e45bd93e9e34249315599
过程:
lattice生成的解码结果并非单一路径,而是N-best路径。
在每次令牌通报过程中,lattice也像viterbi解码那样删除旧令牌的方法来生成,而是通过独特的ForwardLink前向链接机制来生成lattice。
前向链接ForwardList与转移弧不同,用来链接前后两帧之间的发射转移弧之间的Token,或同一时候非发射转移弧之间的Token。
基于WFST的Lattice静态解码过程:
https://p3.toutiaoimg.com/large/pgc-image/6553ea462e434504b2e8161a5ae35114
kaldi中的gmm-latgen-faster实现了lattice解码。
https://p9.toutiaoimg.com/large/pgc-image/7bdc80e9a13447d8b8e01926f302d0fa
函数剖析:
https://p6.toutiaoimg.com/large/pgc-image/3101c4be0cd749429222bb354efccbbc
其中解码、回溯部分、写入文件部分也包含在这个函数内。
decoder.Decode(&decodable)举行解码。
https://p6.toutiaoimg.com/large/pgc-image/5e24015fb65445f3948d2b47bdcfa871
https://p26.toutiaoimg.com/large/pgc-image/c296d49071c344d6bd82351b24234837
令牌通报:
LatticeDecode并不是向viterbi解码那样通报令牌自己,而是在创建新令牌后,使用一个前向链接把令牌链接起来。
https://p3.toutiaoimg.com/large/pgc-image/3c330fe006e34e08a6743c82fbc16737
诊断评分
https://p9.toutiaoimg.com/large/pgc-image/d1ec0382ecf34bf480facc86511588ae
https://p6.toutiaoimg.com/large/pgc-image/70a8f9dffa554266b4f96d8718ab44d0
末了从所有错误率中找到最低的那个错误率。
https://p6.toutiaoimg.com/large/pgc-image/9344483e6d804ee1a3984661397a1e52
Kaldi的YesNo实例解码识别错误率0%。
其中 N 是 num总数,C 是 corr 准确数,S 是 sub 替换错误,D 是 Del 是删除错误,I 是 INS 插入错误。
解码结果
https://p3.toutiaoimg.com/large/pgc-image/a99ba55b8f20450699941a263fa83f47
页:
[1]