kaldi 学习笔记-三音素训练1(Decision Tree)
2017-09-22 20:19
507 查看
开始介绍kaldi三音素训练大致流程。本文主要介绍决策树(Decision Tree)部分。
输入:模型,特征,对齐序列
输出:决策树的统计量
首先读入Transition Model,从 contex_indep.csl中读取要训练的所有三音素, 保存在 AccumulateTreeStatsInfo 对象的ci_phones中。然后对于每帧语音特征和与其相应的对齐序列,进行统计量的计算。调用以下函数:
该函数累计统计量,保存在BuildTreeStatsType中。
BuildTreeStatsType也就是
EventTpye也是一个vector,里面存的是一个
例如:
对于每帧语音,由其对齐序列可以得知transition-id,也就知道了对应哪个phone。因此我们可以统计phone出现的次数以及该条特征的均值方差等统计量存放在GaussClusterable的结构体中。因此,对所有的特征数据、对齐数据执行这个函数后,我们得到了所有的EventType和每个EventType对应的统计量,我们之后用它来进行决策树,问题集的构建。
输入:决策树统计量,音素集
输出:问题的文本表示
该命令的核心函数如下,根据统计量stats,问题集phones,输出问题集phone_sets_out。pdf-class-list和P表示用于过滤的phone或者state。
pdf-class-list = 1表示只用中间状态的统计量,其他都抛弃。
4000
P = 1表示中间音素,我们累加某一固定中间音素的所有三音素的统计量
得到split_stats
依照sets.int 音素集文件将每行共享的统计量累加,再调用TreeCluster用Kmeans算法依照统计量对所有三音素进行聚类。
最后如下用ObtainSetsOfPhones输出树中每个节点所含的phones。这里包含叶子节点和它的parent(非叶子节点),因此同一个phone可能在多个节点(多个问题)出现。注意kaldi里一个问题就是一个phone set。
输入:拓扑结构topo,question.txt
输出:question.qst
分为两个部分,音素位置相关的问题 和 HMM状态位置的问题。
当key为0,1,2时,问题是基于音素位置的问题,即对三音素中的每个音素分别问问题.
kaldi里用Questions 和 QuestionsForKey 这两个类来表示。Questions里面为音素位置和QuestionsForKey,QuestionsForKey为问题即一些音素集,初始化均为question.txt。
当key为-1时,问题是基于HMM的某个状态的,这和HMM的状态数目有关,通常为三个,得到的问题集为[[0],[0,1]], 如果为5个,则为[[0],[0,1],[0,1,2], [0,1,2,3]].
输入:关于tree的统计量,root文件,问题集,topo文件
输出:决策树tree
主要调用如下函数
qo是问题集,phone_set是由roots文件得到,roots文件里说明了是否要share相同决策树根结点和是否需要进一步进行划分的的phone。
该函数由roots文件中的所有音素集首先用GetStubMap()递归构初始的决策树,总的来说GetStubMap()对每一个音素集创建一个初始的叶子结点,一个音素集就是roots.int中的一行中的音素的集合,每个节点其实都是一个小决策树的树根,之后会进一步由这个叶子节点划分。
首先对于EvenType的每一个key(-1,0,1,2),在该key对应的问题集中(由q_opts给出每个key的问题集)找到一个问题,使得对叶子结点划分后获得的似然提升最大。
1. acc-tree-stats
Usage: acc-tree-stats [options] <model-in> <features rspecifier> <alignments-rspecifier> <tree-accs-out>
输入:模型,特征,对齐序列
输出:决策树的统计量
首先读入Transition Model,从 contex_indep.csl中读取要训练的所有三音素, 保存在 AccumulateTreeStatsInfo 对象的ci_phones中。然后对于每帧语音特征和与其相应的对齐序列,进行统计量的计算。调用以下函数:
AccumulateTreeStats(trans_model, acc_tree_stats_info, alignment, mat, &tree_stats);
该函数累计统计量,保存在BuildTreeStatsType中。
BuildTreeStatsType也就是
vector <EventType, GaussClusterable*> stats
EventTpye也是一个vector,里面存的是一个
pair<EventKeyType, EventValueType>, EventKeyType是一个int,表示三音素位置(0,1,2)或者HMM的state(-1),EventKeyValue也是int,表示三音素的phone-ID或者对应HMM(-1)的state-id(通常为0,1,2 )。
例如:
EventType e = { (-1, 1), (0, 10), (1, 11), (2,12) }中,表示三音素为(10,11,12)中第一个HMM state。
对于每帧语音,由其对齐序列可以得知transition-id,也就知道了对应哪个phone。因此我们可以统计phone出现的次数以及该条特征的均值方差等统计量存放在GaussClusterable的结构体中。因此,对所有的特征数据、对齐数据执行这个函数后,我们得到了所有的EventType和每个EventType对应的统计量,我们之后用它来进行决策树,问题集的构建。
2. cluster-phones
Usage: cluster-phones [options] <tree-stats-in> <phone-sets-in> <clustered-phones-out>
输入:决策树统计量,音素集
输出:问题的文本表示
该命令的核心函数如下,根据统计量stats,问题集phones,输出问题集phone_sets_out。pdf-class-list和P表示用于过滤的phone或者state。
AutomaticallyObtainQuestions(stats, phone_sets, pdf_class_list, P, &phone_sets_out);
pdf-class-list = 1表示只用中间状态的统计量,其他都抛弃。
4000
BuildTreeStatsType retained_stats; FilterStatsByKey(stats, kPdfClass, all_pdf_classes, true, // retain only the listed positions &retained_stats);
P = 1表示中间音素,我们累加某一固定中间音素的所有三音素的统计量
得到split_stats
std::vector<BuildTreeStatsType> split_stats; // split by phone. SplitStatsByKey(retained_stats, P, &split_stats);
依照sets.int 音素集文件将每行共享的统计量累加,再调用TreeCluster用Kmeans算法依照统计量对所有三音素进行聚类。
TreeCluster(summed_stats_per_set, summed_stats_per_set.size(), // max-#clust is all of the points. NULL, // don't need the clusters out. &assignments, &clust_assignments, &num_leaves, topts);
最后如下用ObtainSetsOfPhones输出树中每个节点所含的phones。这里包含叶子节点和它的parent(非叶子节点),因此同一个phone可能在多个节点(多个问题)出现。注意kaldi里一个问题就是一个phone set。
ObtainSetsOfPhones(phone_sets, assignments, clust_assignments, num_leaves, questions_out);
3. compile-question
Usage: compile-questions [options] <topo> <questions-text-file> <questions-out>
输入:拓扑结构topo,question.txt
输出:question.qst
分为两个部分,音素位置相关的问题 和 HMM状态位置的问题。
当key为0,1,2时,问题是基于音素位置的问题,即对三音素中的每个音素分别问问题.
kaldi里用Questions 和 QuestionsForKey 这两个类来表示。Questions里面为音素位置和QuestionsForKey,QuestionsForKey为问题即一些音素集,初始化均为question.txt。
当key为-1时,问题是基于HMM的某个状态的,这和HMM的状态数目有关,通常为三个,得到的问题集为[[0],[0,1]], 如果为5个,则为[[0],[0,1],[0,1,2], [0,1,2,3]].
4. build-tree
Usage: build-tree [options] <tree-stats-in> <roots-file> <questions-file> <topo-file> <tree-out>
输入:关于tree的统计量,root文件,问题集,topo文件
输出:决策树tree
主要调用如下函数
to_pdf = BuildTree(qo, phone_sets, phone2num_pdf_classes, is_shared_root, is_split_root, stats, thresh, max_leaves, cluster_thresh, P);
qo是问题集,phone_set是由roots文件得到,roots文件里说明了是否要share相同决策树根结点和是否需要进一步进行划分的的phone。
该函数由roots文件中的所有音素集首先用GetStubMap()递归构初始的决策树,总的来说GetStubMap()对每一个音素集创建一个初始的叶子结点,一个音素集就是roots.int中的一行中的音素的集合,每个节点其实都是一个小决策树的树根,之后会进一步由这个叶子节点划分。
EventMap *tree_split = SplitDecisionTree(*tree_stub, filtered_stats, q_opts, thresh, max_leaves,&num_leaves,&impr, &smallest_split);
首先对于EvenType的每一个key(-1,0,1,2),在该key对应的问题集中(由q_opts给出每个key的问题集)找到一个问题,使得对叶子结点划分后获得的似然提升最大。
相关文章推荐
- kaldi 学习笔记-单音素训练
- Kaldi单音素GMM学习笔记
- OpenCV学习笔记(2)——opencv方法训练.xml文件过程
- tensorflow学习笔记之简单的神经网络训练和测试
- [caffe学习笔记]用自己的数据进行训练和测试
- [转载]kaldi学习笔记:run.sh(egs/timit/s5)详细分析:从数据准备到特征提取
- 深度学习笔记之关于基本思想、浅层学习、Neural Network和训练过程(三)
- 深度学习笔记 (二) 在TensorFlow上训练一个多层卷积神经网络
- Caffe_Windows学习笔记(二)用自己的数据训练和测试CaffeNet
- OpenCV学习笔记---- 挨个读取图像文件夹下的所有文件,进行样本训练
- 薛开宇学习笔记二之总结笔记(用一个预训练模型提取特征)--Linux语法总结
- 算法竞赛入门经典训练指南-4.1.1学习笔记
- 算法竞赛入门经典训练指南-4.1.2学习笔记
- 深度学习笔记——Word2vec和Doc2vec训练实例以及参数解读
- [学习笔记]BP神经网络原理以及训练步骤
- tensorflow学习笔记六:保存和加载训练模型
- CTC学习笔记(二) 训练和公式推导
- Kaldi三音素GMM学习笔记
- Caffe学习笔记(六)—— Windows下训练自己的数据
- 台湾大学林轩田机器学习技法课程学习笔记9 -- Decision Tree