建议在csdn资源页中免费下载该学习笔记的PDF版进行阅读:)点击进入下载页面
Kaldi决策树状态绑定学习笔记(二)
——如何自动生成问题集?
Kaldi决策树中使用的问题集并不是手工设计的,而是通过之前得到的统计量自动生成的。那么在Kaldi中是如何自动生成问题的?这就是本次笔记的主要内容。
在这个笔记中,我会首先介绍自动生成问题集所用到的主程序cluster-phones和主函数AutomaticallyObtainQuestions(),然后会穿插着介绍主函数用到的核心函数和完成具体工作的一些C++对象。最后再讲解程序compile-question。
建议学习Kaldi官方文档《Decision tree internals》的Classes and functions involved in tree-building部分,《How decision trees are used in Kaldi》的The tree building process部分。
若对似然这些名词和对应的公式感觉陌生,请参考论文《Tree-Based State Tying For High Accuracy Acoustic Modelling》S.J.Young的第三部分Tree-BasedClustering。
目录
cluster-phones
- 作用:Cluster phones (or sets of phones) into sets for various purpose. 对多个音素或多个音素集进行聚类。
- 输入:决策树相关统计量treeacc,多个音素集sets.int
- 输出:自动生成的问题集(每个问题由多个音素组成)
- 示例:
cluster-phones $context_opts $dir/treeacc $lang/phones/sets.int \
$dir/questions.int
- 过程:
- 从treeacc中读取统计量到BuildTreeStatsType stats;读取vector pdf_class_list,该变量指定所考虑的HMM状态,默认为1,也就是只考虑三状态HMM的中间状态;从sets.int读取vector > phone_sets;默认的三音素参数N=3,P=1。
- 若指定的mode为questions,调用AutomaticallyObtainQuestions()自动生成问题集vector > phone_sets_out;若指定的model为k-means,调用KMeansClusterPhones()。此笔记只涉及questions模式。
- 将上述函数自动生成的phone_sets_out写到questions.int。
- 文件说明:
下面以我们实验室所用的sets.int和sets.txt为例,来对sets.int文件有一个直观的感受:(左边是sets.txt,右边是sets.int,两图第一列均为行号)
AutomaticallyObtainQuestions()
void AutomaticallyObtainQuestions(
BuildTreeStatsType &stats,
const std::vector<std::vector<int32> > &phone_sets_in,
const std::vector<int32> &all_pdf_classes_in,
int32 P,
std::vector<std::vector<int32> > *questions_out
)
- 主要功能:AutomaticallyObtainQuestions()通过对音素自动进行聚类,从而获取问题集;它把音素聚类成一棵树,并且对树中的每一个结点,把从该结点可以到达的所有叶子结点合在一起构成一个问题(该树的一个叶子结点保存着一些音素,一个问题就是一个音素的集合)。(官方文档《Decision tree internals》的Classes and functions involved in tree-building中的Top-level tree-building functions部分如是说)。初看到这段描述可能并不是很清楚到底怎么一回事,在看明白代码之后就会明白这句话讲了什么。
分块解析:
(在下面我会把不重要的代码删掉,比如错误检测代码,只留下主要部分)
- 读取sets.int中的所有音素,保存在phones中。phone_sets_in由sets.int得到。
std::vector<std::vector<int32> > phone_sets(phone_sets_in);
std::vector<int32> phones;
for (size_t i =