kaldi学习笔记(三)生成L.fst
kaldi项目新路径:kaldi/egs/xuexi/s5
L.fst是lexicon的WFST格式,L_disambig.fst引入了消歧符号。L.fst的输入音素序列,输出词序列。在这假设大家已经知道WFST,下面我们用一个小lexicon.txt来演示怎么生成L.fst等,词典放在data/local/dict下。
1 | |
依靠这个字典我们准备以下文件:
nonsilence_phones.txt:语言直接相关的真实音素,同一行的音素是某一个音素的不同变体(重音、音调方面),故可共享决策树根,用的aishell的脚本;
1 | |
silence_phones.txt:静音类音素
optional_silence.txt:备用的静音类音素
1 | |
extra_questions.txt:同一行的音素有着相同的重音或音调,与GMM训练中自动生成的“questions”一同用于决策树的生成。
.png)
1 | |
这时候我们dict就准备好了,返回s5目录,下一步我们使用perpare_lang.sh来生成L.fst
首先连接wsj的steps和utils
1 | |
然后使用perpare_lang.sh
1 | |
这时候我们来看以下data/lang文件夹下生成的东西
.png)
我们可以通过fstprint和fstdraw进行可视化L.fst
1 | |
一般我们用第二行命令进行可视化
.png)
这个图的意思:
第16行只有一列,说明状态1是终止状态,并且没有权重。其余的都是5列,第一列是起点状态id,第二列是终点状态id,第三列是输入符号,第四列是输出符号,第五列是weight。因此第一行表示的边为:从状态0到1的边,输入是<eps>,输出是<eps>,权重为0.69314。这个WFST的初始状态是什么呢?OpenFst约定第一行的起点就是初始状态。
因此我们可以依靠此表将WFST画出来
现在再我们使用下面两行命令用fstdraw来进行可视化(因为这个词典太小可以可视化出来,一般这个命令没法用)
1 | |
%20(1).jpg)
我们现在来看一下lang文件夹下面的其他文件。
1.phones.txt,将所有音素一一映射为自然数,即音素 ID,引入“
第一列为音素,第二列为映射的自然素,可以看到总共122个音素,
.png)
.png)
2.words.txt,将词一一映射为自然数,即词ID,引入“”(句子起始处)、“”(句子结尾处),便于 FST 处理;
.png)
3.oov.txt,oov.int,集外词的替代者(此处为)及其在words.txt 中的ID;
.png)
oov.txt就是如果出现界外词,就用oov.txt中的词代替。
4.topo,各个音素HMM模型的拓扑图,通过将一个音素(或三音素)表示成一个HMM,此文件确定了每个音素使用的HMM状态数以及转移概率,用于初始化单音素GMM-HMM,可根据需要自行进行修改(并用utils/validate_lang.pl校验),实验中静音音素用了5个状态,其他音素用了3个状态;
.png)
6-117是非静音音素,1-5为静音音素
5.phones/,是dict/ 的拓展,内部文件均可以文本形式打开查看,后缀为 txt/int/csl 的同名文件之间是相互转换的,其中 context_indep.txt 标明了上下文无关建模的音素,通常为静音音素, wdisambig.txt/wdisambig_phones.int/wdisambig_words.int 分别标明了words.txt 引入的消歧符号(#0)及其在phones.txt 和words.txt 中的ID, roots.txt 定义了同一行音素的各个状态是否共享决策树的根以及是否拆分,对应的音素集则存放于sets.txt。
消歧是为了确保发音词典能够得到一个确定性的(Deterministic) WFST。 如果有些词对应的音素串是另一些词音素串的前缀,比如 good 的音素串是 goodness 的前半段音素串,需要在前者对应的音素串后面加入消歧音素,破坏这种前缀关系,这样, WFST 中一个词的路径就不会包含于另一个词的路径中。
未完待续。。。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!