HTK之决策树聚类

用决策树解决聚类问题 选择目标类别选择特征建立决策树输出结果简单易懂:决策树算法通俗易懂,易于理解,不需要过多的专业知识。高效性:决策树算法可以有效地分类数据,并且不需要额外的特征工程,因此可以提高分类效率。可扩展性:决策树算法可以轻松地扩展到大规模数据集,并且可以根据不同的任务需求进行适当的调整和修改。 阅读详情

可以毫不夸张的说,没有聚类的成功应用,就不会有今天的连续语音识别率(虽说不是很高)。由于语流中语音的变体十分丰富,为了能够足够精确的描述这些变体,人们往往必须设计一个较为复杂的语音单元(比如上下文音素单元)。

可是这样,问题就出现了,实际上,我们可以用于训练的语音数据总是有限的,往往不能够满足复杂语音单元训练的要求,这就形成了模型复杂度(模型描述的准确度)和训练数据规模之间的矛盾。一味的增加训练数据是不现实的,一方面这会极大的增加存储空间,人工劳动和训练费用等等;还有一个困难是致命的,就是不管你如何增大训练数据的规模,总是存在训练数据集以外的语音变体,所以仅仅依靠增加数据集来解决这个矛盾是不可行的。而聚类就可以有效的缓解这个矛盾。

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客

用于基于HMM的语音识别的模型训练的聚类方法大致可以分为两类:一是基于数据驱动的聚类方法,而另一个就是现今正广泛使用的基于决策树的聚类方法。决策树聚类的好处是:第一,它可以得到与基于数据驱动聚类方法相同的聚类性能,另一个好处更为重要,就是它可以为训练集未包含的但实际语流中又可能会出现的语音单元(称为不可见语音单元)提供一个较为可信的参数估计。

这里主要讨论的决策树聚类是:上下文语音单元状态的聚类。如上图所示。


2. 实现状态捆绑(tying)的决策树聚类

基于决策树的状态捆绑(Decision tree based state tying)是一种自顶向下的聚类过程。假设三音素(triphones)模型是上下文相关的模型(context dependent model),起初位于根节点的triphones中的状态模型从单音素模型中获得。从根节点开始像二叉树一样分裂成两个相继的节点(称为yes和no节点),然后再以相继的节点为根节点,继续向下分裂,直到满足给定的条件为止,最后,所有叶节点上的triphones集合就是tied triphones。如下所示

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客

音素决策树

这里介绍两种决策树聚类方法。

以下讨论的聚类方法都假设:模型的输出概率分布为单高斯分布,协方差矩阵为对角阵


1. 基于最大似然(ML)准则的决策树聚类

基于最大似然准则的决策树的构造如下

1. 一组一维高斯分布的上下文相关的HMM已训练好

2. 预备聚类的状态集放在决策树的根节点上并计算其对数似然值

3. 对每个节点、每个问题:计算在这个问题下分裂成的yes和no子节点的对数似然值比父节点的对数似然值增加值。记似然值增加最多的节点为HTK之决策树聚类 - 跑不快 - 沧海浮云的博客及其对应问题为HTK之决策树聚类 - 跑不快 - 沧海浮云的博客,使用问题HTK之决策树聚类 - 跑不快 - 沧海浮云的博客分裂节点HTK之决策树聚类 - 跑不快 - 沧海浮云的博客

4. 重复步骤3,直到对数似然值的增加值低于设定的域值


3-1

决策树的分裂条件是:HTK之决策树聚类 - 跑不快 - 沧海浮云的博客

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客是节点HTK之决策树聚类 - 跑不快 - 沧海浮云的博客在q提问下分裂前后的对数似然值(Log likelihood)之差,即:


3-2

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客

节点HTK之决策树聚类 - 跑不快 - 沧海浮云的博客的对数似然值HTK之决策树聚类 - 跑不快 - 沧海浮云的博客是通过训练数据观察向量的均值、方差以及节点的期望占有数(expected number of occupation)近似计算所得。


3-3

先给出节点HTK之决策树聚类 - 跑不快 - 沧海浮云的博客的均值和方差

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客


3-4

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客

其中HTK之决策树聚类 - 跑不快 - 沧海浮云的博客、HTK之决策树聚类 - 跑不快 - 沧海浮云的博客、HTK之决策树聚类 - 跑不快 - 沧海浮云的博客分别是节点HTK之决策树聚类 - 跑不快 - 沧海浮云的博客中某元素的第i个状态的均值向量、方差矩阵(对角协方差矩阵)、占有数向量。上标k表示向量的第k个分量。给定训练数据中的一观察序列HTK之决策树聚类 - 跑不快 - 沧海浮云的博客,那么节点HTK之决策树聚类 - 跑不快 - 沧海浮云的博客的对数似然值可以通过下式求得:


3-5

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客、HTK之决策树聚类 - 跑不快 - 沧海浮云的博客分别指节点HTK之决策树聚类 - 跑不快 - 沧海浮云的博客在t时刻的期望占有数和序列的期望占有数。聚类后决策树的叶节点就是求得的捆绑的triphones,对应的均值向量为HTK之决策树聚类 - 跑不快 - 沧海浮云的博客,协方差矩阵为HTK之决策树聚类 - 跑不快 - 沧海浮云的博客。这里必须指出的是,不知道为什么大多数文献直接给出HTK之决策树聚类 - 跑不快 - 沧海浮云的博客,实际上节点HTK之决策树聚类 - 跑不快 - 沧海浮云的博客的对数似然值为HTK之决策树聚类 - 跑不快 - 沧海浮云的博客,以后笔者会证明它与式(3-5)之间并不能划上等号,事实上,应该是HTK之决策树聚类 - 跑不快 - 沧海浮云的博客的辅助函数HTK之决策树聚类 - 跑不快 - 沧海浮云的博客(这里的HTK之决策树聚类 - 跑不快 - 沧海浮云的博客表示状态序列)与式(3-5)相等。

下面推导节点HTK之决策树聚类 - 跑不快 - 沧海浮云的博客的对数似然值公式:

由Baum-Welch参数估计公式:


3-6

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客


3-7

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客

令:HTK之决策树聚类 - 跑不快 - 沧海浮云的博客,HTK之决策树聚类 - 跑不快 - 沧海浮云的博客


3-8

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客


3-9

令HTK之决策树聚类 - 跑不快 - 沧海浮云的博客

其中

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客

式(3-9)重写为:


3-10

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客

重写式(3-4)如下:

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客


3-11

即:HTK之决策树聚类 - 跑不快 - 沧海浮云的博客

将式(3-11)代入式(3-10),得:

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客

下面证明HTK之决策树聚类 - 跑不快 - 沧海浮云的博客为0。

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客所以:式(3-8)HTK之决策树聚类 - 跑不快 - 沧海浮云的博客


2. 基于最小描述长度(MDL)的决策树聚类

基于最大似然(ML)准则的决策树聚类已广泛使用,但基于这种方法的聚类有一个缺点,就是需要外部提供一个域值来控制其聚类的程度。这个域值的选取是经验性的,没有可靠的理论来保证选取的最优性,且不同的训练数据需要不同的域值。较好的域值,只能通过反复凑试获得,这通常是很费时。

这里将要讨论的基于MDL的决策树聚类,可以避免外部选择域值的麻烦,算法可以根据模型复杂度和数据规模自适应的产生一个域值。有实验证明这个域值比较可靠。

MDL准则

假设有一组概率模型HTK之决策树聚类 - 跑不快 - 沧海浮云的博客和一组数据HTK之决策树聚类 - 跑不快 - 沧海浮云的博客,模型HTK之决策树聚类 - 跑不快 - 沧海浮云的博客的描述长度HTK之决策树聚类 - 跑不快 - 沧海浮云的博客计算公式如下


(1)

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客

其中,HTK之决策树聚类 - 跑不快 - 沧海浮云的博客是模型HTK之决策树聚类 - 跑不快 - 沧海浮云的博客的维数(自由参数的个数),HTK之决策树聚类 - 跑不快 - 沧海浮云的博客是模型HTK之决策树聚类 - 跑不快 - 沧海浮云的博客对应最大似然估计的参数。

式(1)中的第一项称为模型HTK之决策树聚类 - 跑不快 - 沧海浮云的博客关于数据HTK之决策树聚类 - 跑不快 - 沧海浮云的博客的编码长度。这项与ML中的对数似然值的负数等同。

式(1)中的第二项称为模型HTK之决策树聚类 - 跑不快 - 沧海浮云的博客的编码长度,该项代表了模型HTK之决策树聚类 - 跑不快 - 沧海浮云的博客的复杂度。

式(1)中的第三项称为选择模型HTK之决策树聚类 - 跑不快 - 沧海浮云的博客的编码长度,这个假设为常数。

先定性讨论一下式(1)的含义:当模型HTK之决策树聚类 - 跑不快 - 沧海浮云的博客的复杂度增加时,第一项的值变小,第二项的值变大,第二项可以看成对选择复杂模型的一种惩罚。具有最小描述长度HTK之决策树聚类 - 跑不快 - 沧海浮云的博客的模型可以认为其复杂度是适中的。从中可以看出,MDL准则不需要外部提供参数来帮助判断模型的最优性。

用于语音识别的MDL的计算

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客

如上图,假设节点HTK之决策树聚类 - 跑不快 - 沧海浮云的博客分裂成HTK之决策树聚类 - 跑不快 - 沧海浮云的博客个叶节点HTK之决策树聚类 - 跑不快 - 沧海浮云的博客,则模型HTK之决策树聚类 - 跑不快 - 沧海浮云的博客的描述长度HTK之决策树聚类 - 跑不快 - 沧海浮云的博客的计算公式如下:


(2)

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客

式(2)中的变量的意义与ML中相同。

记HTK之决策树聚类 - 跑不快 - 沧海浮云的博客

模型HTK之决策树聚类 - 跑不快 - 沧海浮云的博客的维数是HTK之决策树聚类 - 跑不快 - 沧海浮云的博客(HTK之决策树聚类 - 跑不快 - 沧海浮云的博客个均值向量,HTK之决策树聚类 - 跑不快 - 沧海浮云的博客个协方差矩阵对角元素向量)

假设节点HTK之决策树聚类 - 跑不快 - 沧海浮云的博客在问题HTK之决策树聚类 - 跑不快 - 沧海浮云的博客的提问下分裂成HTK之决策树聚类 - 跑不快 - 沧海浮云的博客和HTK之决策树聚类 - 跑不快 - 沧海浮云的博客分支

记HTK之决策树聚类 - 跑不快 - 沧海浮云的博客

当HTK之决策树聚类 - 跑不快 - 沧海浮云的博客节点HTK之决策树聚类 - 跑不快 - 沧海浮云的博客分裂,否则节点HTK之决策树聚类 - 跑不快 - 沧海浮云的博客停止分裂。

这里的HTK之决策树聚类 - 跑不快 - 沧海浮云的博客相当于ML中外部提供的域值。


3. HHED模块

HTK中HHED模块的功能非常强大,它主要负责对HMM定义文件进行修改,比如将单音素模型拷贝生成上下文三音素模型(通过CL命令完成)。这里要主要讨论HHED的决策树聚类的功能(HHED也提供了基于数据驱动的聚类方法)。HHED的工作模式和Shell非常相识,用户提供命令脚本文件(文件扩展名通常为:.hed),脚本文件中一行只能写一个命令,HHED模块每次读入一行命令,解析后就执行该命令,执行完后,接着再读入下一行命令,解析后并执行,如此重复,直到执行完所有命令行。

决策树聚类主要通过QS和TB两个命令完成,每执行一条QS命令,HHED就向聚类问题集中增加一个问题,每执行一条TB命令,HHED便会构造一棵决策树并利用聚类问题集进行分裂聚类,聚类结束时,HHED便会将每个叶节点中的所有元素聚为一类(捆绑状态)。

下面先给出HHED模块程序主流程图

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客


1. QS命令

格式:QS 问题名称 {匹配字符串}

例子:QS "L-Vowel" {aa^*,ae^*,ah^*,ao^*,...}

上面例子中QS命令将所有左音素为元音的音素模型归为一类(yes节点),其他的则归为另一类(no节点)。

匹配字符串中的字符*表示匹配0个或多个任意字符,字符?表示匹配任意单个字符。

正如前面所述,执行一条QS命令,HHED便会向聚类问题集中增加一个问题。比如执行前面例子中的QS命令,HHED就会向聚类问题集增加一个名称为"L-Vowel"的问题。

HHED模块中主要由QuestionCommand ()函数负责将问题加入到聚类问题集中。

关键代码:

ChkedAlpha("QS question name", qName);

pattern = PItemList(&ilist, &type, hset, &source, NULL, trace&T_ITM);

LoadQuestion(qName, ilist, pattern);

下面的分析以命令QS "L_p" {p-*}为例

执行ChkedAlpha()后,(char*)qName存储问题名称字符串"L_p"。

PItemList()主要负责将匹配字符串所匹配的模型形成一个模型链表,由(ILink)ilist指向链表头。(char*)pattern存储的就是匹配字符串"{p-*}"。

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客

匹配的模型链表

装载问题函数LoadQuestion(),将问题信息记录到QLink数据结构中,并加入到聚类问题集链表中,(QLink)qHead和(QLink)qTail分别指向这个聚类问题集链表的头和尾。QLink所描述的问题有以下三个部分组成

1. 问题名称 (LabId)QLink->qName

2. 匹配字符串链表 (IPat*)QLink->patList

3. 匹配的模型链表 (ILink)QLink->ilist

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客


2. TB命令

格式:TB 域值 宏名 {项列表}

例子:TB 000 mcep_s2_ {*.state[2].stream[1]}

上面例子中TB命令将所有音素模型的状态号2的数据流号1的所有项归为一个聚类集。这个聚类集对应于决策树的根节点。字符串"mcep_s2_"作为聚类完成后取名的前缀。

注意:HHED中的TB命令只支持单高斯连续输出分布的HMM模型的聚类。

在HHED中由TreeBuildCommand()函数完成TB命令。

下面先给出TreeBuildCommand()函数的程序流程图

1. 读入项列表 PItemList()

聚类可以是状态的聚类也可以是状态下某条数据流的聚类等等,总之模型参数的任何一项或多项都可以进行聚类。这里主要讨论状态的聚类或者状态下某条数据流的聚类。

PItemList()前面已经遇到过,这里的功能是将匹配项列表的所有HMM模型组成一个模型参数链表,(ILink)ilist指向该链表头。

以项列表"*.state[2].stream[1]"为例,执行PItemList()函数后(ILink)ilist指向HMMSet集中所有HMM模型在状态号2下的数据流号1的参数组成的模型

参数链表头。

具体到代码上,链表中每一项都记录

模型的状态2参数 ILink->item = (HLink)hmm->svec+2

模型参数 ILink->owner = (HLink)hmm

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客

由于这里是数据流聚类,所以HHED还使用一集合变量(IntSet)Streams来记录聚类的数据流号。在上面的例子中,Streams->set[1] = TRUE,其它元素都为FALSE,表示只对数据流号1聚类。

2. 初始化累加器,创建决策树

BuildTree()函数的第一步就是初始化全局yes和no分支累加器(AccSum)yes、(AccSum)no,接着就是创建决策树及其根节点。

首先要说明的是关于对节点提出的问题的回答。

聚类集由一个链表组成,(CLink)clHead指向该链表头。HHED通过模型参数链表、聚类集和聚类问题集的指针交换实现对节点提问的回答(yes和no)。

下面先给出关键代码片断

//聚类集

i = 1; clHead = NULL;

for (p=ilist;p!=NULL;p=p->next,i++)

{

. . . . . .

cl = (CLink) New(&tmpHeap,sizeof(CRec));

p->owner->hook = cl; //这是关键

cl->item = p; cl->ans = FALSE;

cl->idx = i; //模型参数链表中项的索引号

cl->next = clHead;

clHead = cl;

}

for (q=qHead; q!=NULL; q=q->next)

{

for (p=q->ilist; p!=NULL; p=p->next)

{

//问题的模型链表项 = 聚类集中相应的项

//也就是聚类集中该项对这个问题的回答是yes

p->item = p->owner->hook;

}

}

for (p=ilist;p!=NULL;p=p->next,i++)

p->owner->hook = NULL;

是不是对上面的代码所起的作用还不清楚,有些迷糊,没关系,下面的函数会帮助你更好的理解如何完成对节点提出问题的回答。

回答问题函数AnswerQuestion()的代码片断

void AnswerQuestion(CLink clist, QLink q)

{

CLink p;

ILink i;

//先设置聚类集关于问题(QLink)q的回答为no

for (p=clist;p!=NULL;p=p->next)

p->ans = FALSE;

if (q!=NULL)

{

for (i=q->ilist;i!=NULL;i=i->next)

{

if ((p=(CLink) i->item) != NULL)

p->ans = TRUE; //这是关键

}

}

}

通过关于聚类集问题的回答将聚类集分为yes (CLink->ans = TRUE)和no(CLink->ans = FALSE)两个子聚类集。

决策树由(Tree*)tree表示,开始的时候只有一个根节点,它也是叶节点,根节点对应于聚类集。

(Node*)node = tree->leaf = tree->root = CreateTreeNode(clHead, NULL);

3. 分析分裂节点的最优问题 ValidProbNode()

关键代码:ValidProbNode(node, threshold);

计算节点(Node*)node在问题聚类集中所有问题的提问下的yes和no分支的似然值之和(ClusterLogL())的最大值((double)node->sProb)并记录对应的问题((QLink)node->quest)。

如果这个最大似然值比节点node的似然值还小,则node->sProb=节点似然值,node->quest = NULL。

下面给出ValidProbNode()函数的的代码片断

qbest = NULL;

best = node->tProb; //节点似然值

for (q=qHead;q!=NULL;q=q->next)

{

AnswerQuestion(node->clist, q);

sProb = ClusterLogL(node->clist, &no, &yes, occs);

. . . . . .

if (sProb > best)

{

best = sProb;

qbest = q;

}

}

. . . . . .

node->sProb=best; node->quest=qbest;

4. 分析叶节点中最优的分裂节点 FindBestSplit()

关键代码:node = FindBestSplit(tree->leaf, threshold);

计算所有叶节点中分裂前后后的似然值之差(node->sProb-node->tProb)中的最大值并返回其节点指针。如果这个最大值小于域值(double)threshold,则返回NULL。

下面给出FindBestSplit()函数的代码片断

Node *FindBestSplit(Node *first, double threshold)

{

Node *best, *node;

double sProb, imp;

best = NULL;imp = 0.0;

for (node = first;node != NULL;node = node->next)

{

sProb = node->sProb - node->tProb;

if (sProb>imp && sProb>threshold)

best = node;imp = sProb;

}

return(best);

}

5. 分裂节点 SplitTreeNode()

关键代码:SplitTreeNode(tree, node);

节点(Node*)node在问题(QLink) node->quest提问下分裂成(Node*)yes和(Node*)no两分支。

首先将node在问题(QLink) node->quest提问下回答no的子聚类集赋予子节点(Node*)no,将node在问题(QLink) node->quest提问下回答no的子聚类集赋予子节点(Node*)yes。

接着调整(Node*)tree->leaf仍指向叶节点链表头,并调整yes和no节点的相关指针。

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客

根节点示意图

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客

第一次分裂后示意图

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客

第二次分裂后示意图

下面给出SplitTreeNode()函数的代码片断

void SplitTreeNode(Tree *tree, Node *node)

{

CLink cl,nextcl;

if (node->quest == NULL) return;

cprob += node->sProb - node->tProb;

AnswerQuestion(node->clist, node->quest);

node->yes = CreateTreeNode(NULL,node);

node->yes->ans= TRUE;

node->no = CreateTreeNode(NULL,node);

node->no->ans=TRUE;

//分裂聚类集

for(cl=node->clist;cl!=NULL;cl=nextcl)

{

nextcl=cl->next;

switch(cl->ans)

{

case FALSE:

cl->next=node->no->clist;

node->no->clist=cl;

break;

case TRUE:

cl->next=node->yes->clist;

node->yes->clist=cl;

break;

default:

HError(2694,"SplitTreeNode: Unspecified question result");

}

}// for(cl=node->clist;cl!=NULL;cl=nextcl)

node->clist = NULL;

//调整yes和no分支指针,以及叶节点链表

node->yes->next = node->no;

node->no->prev = node->yes;

node->no->next = node->next;

node->yes->prev = node->prev;

if (node->next!=NULL)

node->next->prev=node->no;

if (node->prev==NULL)

tree->leaf = node->yes;

else

node->prev->next=node->yes;

numTreeClust++; //叶节点数++

}

6. 对所有叶节点进行聚类 TieLeafNodes()

关键代码:TieLeafNodes(tree, macRoot);

决策树分裂结束后,执行TieLeafNodes()将每个叶节点中所有元素聚为一类(新构造一个宏),聚类宏名以(char*)macRoot为前缀,后接序号。聚类的输出概率的均值向量和协方差矩阵取其对应节点的均值向量HTK之决策树聚类 - 跑不快 - 沧海浮云的博客和协方差矩阵HTK之决策树聚类 - 跑不快 - 沧海浮云的博客(具体公式见前)。

以前的讨论都没有涉及到聚类模型,所以在这里有必要说明一下。

在HTK中主要通过使用计数(->nUse)标志聚类(捆绑)。如果对模型的状态参数或者状态下某些数据流参数捆绑,那么这些参数都指向同一个同类型的参数,这个参数中的使用计数(>1)记录捆绑参数的个数。

明白了吗?是不是太抽象了,不用担心,下面的代码片断会帮助你进一步弄清是这么回事的。

TieLeafStream()函数实现状态下某条数据流的捆绑

void TieLeafStream(ILink ilist, LabId macId, int stream)

{

ink i;

StreamInfo *sti;

. . . . . .

sti = ((StateElem *)ilist->item)->info->pdf[stream].info;

sti->nUse = 1; //使用计数为1

NewMacro(hset, fidx, 'p', macId, sti);//构造一个新聚类的宏

//捆绑集中所有数据流参数

for (i=ilist->next; i!=NULL; i=i->next)

{

((StateElem *)i->item)->info->pdf[stream].info = sti;

++sti->nUse;

}

}

TieState ()函数实现状态的捆绑

void TieState(ILink ilist, LabId macId)

{

ILink i,ti;

StateInfo *si,*tsi;

StateElem *se;

. . . . . .

if (hset->hsKind==TIEDHS || hset->hsKind==DISCRETEHS)

ti = ilist;

else

ti = TypicalState(ilist, macId); //选择较好的状态参数来代表这个聚类

se = (StateElem *) ti->item;

tsi = se->info;

tsi->nUse = 1; //使用计数为1

NewMacro(hset, fidx, 's', macId, tsi); /构造一个新聚类的宏

//捆绑集中所有状态参数

for (i=ilist; i!=NULL; i=i->next)

{

se = (StateElem *)i->item; si = se->info;

if (si != tsi)

{

se->info = tsi;

++tsi->nUse;

}

}

}


3. ST命令

聚类完成后,ST命令可以将内存中的决策树列表输出到文件中。其中包括聚类时使用的问题集,一组构建好的决策树。

文件的存储方式如下:

问题集

决策树列表

问题集中的问题的存储格式和前面的QS命令相同。

下面给出决策树的存储的典型格式

m[3].stream[1]

{

0 C-Vowel -1 -3

-1 C-silences -2 "s3_4"

-2 C-Unvoiced_Stop "s3_6" "s3_5"

-3 C-l -4 "s3_1"

-4 C-Low_Vowel "s3_3" "s3_2"

}

其中,第一行,指明树的名称(m)和聚类的类型(状态号3下的数据流号1的聚类)。

以第三行为例,"C-Vowel"是用来分裂决策树节点号为0(根节点)的问题名称,后面分别是yes子节点(序号为1)和no子节点(序号为3),如果子节点是非叶节点则用序号表示,否则用聚类宏名显示。

HTK之决策树聚类 - 跑不快 - 沧海浮云的博客


4. LT命令

将由ST命令输出的决策树列表文件装入。

通达信浮筹多空波段抓牛擒龙指标公式源码 VAR33:=VA3>=REF(VA4,1) AND C<REF(C,1) AND VAR19=60 AND VAR18=0 AND 活跃线>=REF(活跃线,1) AND VA12<REF(VA13,1);DRAWTEXT(VAR28 AND COUNT(VAR28,30)=1,65,' ★超涨注意风险'),COLOR0000FF;DRAWTEXT(VAR26 AND COUNT(VAR26,30)=1,90,' ←继续等'),COLOR00FFFF;浮筹线:VA3,COLORFF00FF; 阅读详情

相关推荐

ESP32驱动GC9A01圆形屏实战:Arduino平台LVGL移植与图像显示优化

本文详细介绍了在Arduino平台上使用ESP32驱动GC9A01圆形屏的实战指南,包括硬件连接、LVGL移植与图像显示优化。通过SPI配置、LVGL库安装和双缓冲机制等技巧,帮助开发者快速实现高效显示效果,适用于智能家居控制面板等应用场景。

weixin_29182481的博客 734

HTK HHED命令错误原因

最近在使用HTK的HHED命令对HMM模型进行编辑的时候出现如下错误: WARNING [-2637] HeaviestMix: mix 4 in n2-O+sh2 has v.small gConst [-140000002048.000000] in HHEd 解决的办法是:在训练后再添加HMM模型的混合高斯数。。。。。。。。。。。。

xiaoding133的专栏【Stay hungry,Stay foolish】 2522

Windows Server 2012 R2虚拟机安装全攻略:从镜像选择到网络配置一步到位

本文提供Windows Server 2012 R2虚拟机安装全攻略,涵盖从镜像选择到网络配置的完整流程。详细讲解在Oracle VM VirtualBox中的安装步骤、TCP/IP网络设置、系统优化及常见问题解决方案,帮助用户快速搭建可立即投入使用的服务器环境。特别适合IT初学者和系统管理员学习传统服务器应用的部署与配置。

weixin_28363123的博客 538

HTK搭建大词汇量连续语音识别系统(三)

十、绑定三音素 脚本mktri.led: WB sp WB sil TC 执行命令: HLEd -n labels/triphones1 -i labels/wintry.mlf scripts/mktri.led labels/aligned.mlf 脚本mktri.hed由脚本命令生成: perl scripts/maketrihed data/monophones1 la

cdj0311的专栏 4580

群晖NAS断电后IP变了?3步搞定静态IP设置(附Linux挂载指南)

本文针对群晖NAS因断电重启导致IP地址变化的问题,提供了从根源到实践的完整解决方案。核心内容包括如何为NAS配置静态IP以彻底解决连接中断,并详细讲解了在Linux系统中通过NFS协议稳定挂载NAS共享文件夹的步骤与指南,确保网络存储服务持久可靠。

weixin_29271263的博客 851

INMP441麦克风与ESP32的I2S音频采集实战指南

本文提供了INMP441数字麦克风与ESP32开发板通过I2S接口进行高质量音频采集的完整实战指南。详细讲解了硬件连接、软件配置、数据读取及基础处理,并分享了常见的避坑技巧与性能优化建议,帮助开发者快速构建物联网音频应用。

weixin_28396629的博客 598

HTK关于HHEd的错误

最近依然在研究师兄留下来的实验 对于HMM还是一知半解

u014414916的专栏 975

常规波束形成——时域波束形成、频域波束形成

本文介绍了波束成形,包括时域波束成形和频域波束成形,并解释了在实现过程可能存在疑惑的相位补偿。

Candy_Editor的博客 3657

基于HTK的连续语音识别系统搭建学习笔记(二)

[step 5]数据的特征提取 这里所用特征为MFCC。工具HCopy可以实现提取特征的工作。 创建文件夹:config 创建文件:config1(要设置的参数) 创建位置:config 创建内容: 创建文件:codetr.scp(制定训练输入和输出列表) 创建位置:根目录下 执行: HCopy -T 1 -C .\config\config1 -S codetr.scp

James Zhang's Blog 5396

安卓模拟器绕过检测全解析:雷电、MuMu、蓝叠、逍遥、夜神与WSA完整指南

随着手机游戏和应用的普及,越来越多的用户选择在PC上通过模拟器来运行安卓应用。然而,许多应用和游戏为了防止作弊或出于安全考虑,会检测是否运行在模拟器环境中。本文将详细介绍各大主流模拟器的检测绕过方法,帮助用户在电脑上流畅体验各类安卓应用。1. 获取模拟器系统镜像2. 使用ROM厨房工具修改系统文件3. 替换模拟器的系统镜像雷电模拟器:适合游戏,推荐使用MAGISK + EdXposed方案MuMu模拟器:适合中度游戏,推荐太极框架蓝叠模拟器:适合国际应用,推荐MAGISK方案逍遥模拟器。

专注技术分享 3万+

ATAC-seq差异分析实战:从原始数据到GO富集(R/Bioconductor全流程)

本文提供了ATAC-seq差异分析的完整R/Bioconductor实战流程,涵盖从原始数据准备、一致峰集构建、计数矩阵生成,到使用DESeq2进行差异可及性分析,以及差异峰的基因组注释与GO富集分析。文章详细讲解了关键步骤、参数设置和常见问题,旨在帮助研究者获得可靠且可解释的生物学结果。

weixin_29246195的博客 228

HTK语音识别中的决策树

1.为什么需要决策树 我们在使用HTK进行语音识别模型训练的过程中,首先进行的是单音素、单个高斯的模型训练。抛开单个高斯不说,单音素模型本身有很大缺点:没有考虑到本音素前后音素的发音对本音素的影响。比如,同样是一个音素iy,如果它前面的音素分别是h和p,那么iy这个音素在这两种情况下的发音会有所不同,那么模型参数也就会受到其影响,此时,如果用同一个模型来描述音素iy,那么就会不合理。

brandon2015的博客 969

在SAP系统中创建物料 860000000000000082(物料描述为“8680月球广寒宫坦克车”)时,系统报出了一个错误

摘要:SAP系统创建物料"8680月球广寒宫坦克车"时出现"C+020"错误,提示评估区域C916未在物料分类账中设置为生产性。解决方案需进入"会计-控制-产品成本控制-实际成本核算"路径,将评估区域C916手动设置为生产性状态。该操作需由具备权限的系统管理员或FICO顾问执行,建议操作前进行数据备份或在测试环境验证。完成设置后即可重新创建物料。

金牌架构师 391

应用HTK搭建语音拨号系统3:创建绑定状态的三音素HMM模型

选自:http://maotong.blog.hexun.com/6261873_d.html 苏统华 哈尔滨工业大学人工智能研究室 2006年10月30日 声明:版权所有,转载请注明作者和来源 该系统能够识别连续说出的数字串和若干组姓名。建模是针对子词(sub-word, eg. 音素),具有一定的可扩充性。当加入一个新名字时,只需修改发音词典和任务语法即可。模型...

aig8440的博客 472

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

基于HTK的连续语音识别系统搭建学习笔记(四)

3.创建绑定状态的三音素HMM模型 目的是加入上下文依赖(context-dependent)三音素模型并得到稳健的训练。包括两步,先由单音素得到三音素并重估参数,第二步就是绑定三音素的状态以使输出更加稳健。 [step 9]得到三音素HMM 上下文依赖三音素模型可以用单音素作为初始,再进行重估。由于重估时要三音素级标注文本,就先生成标注文本。 创建文件:mktri.led 创建位置:根

成长日记的博客 1719

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

应用HTK搭建语音拨号系统--创建单音素HMM模型

应用HTK搭建语音拨号系统--创建单音素HMM模型 哈尔滨工业大学人工智能研究室 2006年10月30日   该系统能够识别连续说出的数字串和若干组姓名。建模是针对子词(sub-word, eg. 音素),具有一定的可扩充性。当加入一个新名字时,只需修改发音词典和任务语法即可。模型为连续混合高斯输出,运用语音决策树聚类形成的绑定状态式三音素。

qqh19910525的博客 1571

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

kaldi中基于决策树的状态绑定

为什么要做状态绑定 假如我们有218monophone,然后现在要考虑上下文音素对发音的影响,这时候我们通常使用triphone。那么会有几个triphone呢?答案是218的3次方。如果不进行聚类,我们需要建立(218的3次方)*3个混合gmm模型(假设每个triphone有3个状态),计算量巨大,另一方面会引起数据稀疏。所以通常我们会根据数据特征对triphone的状态进行绑定。 常见的状态绑...

nlpgeek 11万+

基于HTK的连续语音识别系统搭建学习笔记(一)

放假之前,就已经对HTK上完成连续语音识别的实验充满兴趣。于是找了很多资料,准备在放假的时候好好学习,仔细琢磨,HTK博大精深,光学习和完成孤立词识别肯定是不够。从今天开始,开始同步学习和记录基于HTK的连续语音识别系统搭建工作,这一学习笔记主要记录学习过程,具体自己的实践后面会继续,本次学习的参考资料主要以:苏统华的《应用HTK搭建语音拨号系统》为主,同时,使用HTK BOOK作为参考。

James Zhang's Blog 9711

基于HTK的语音拨号系统

为什么80%的码农都做不了架构师?>>> ...

weixin_34355715的博客 410

语音识别中的决策树

1. 为什么需要决策树 我们在使用HTK进行语音识别模型训练的过程中,首先进行的是单音素、单个高斯的模型训练。抛开单个高斯不说,单音素模型本身有很大缺点:没有考虑到本音素前后音素的发音对本音素的影响。比如,同样是一个音素iy,如果它前面的音素分别是h和p,那么iy这个音素在这两种情况下的发音会有所不同,那么模型参数也就会受到其影响,此时,如果用同一个模型来描述音素iy,那么就会不合理。 为了解决这...

huashui2009120的博客 1935

应用HTK搭建语音拨号系统1:数据准备

选自:http://maotong.blog.hexun.com/6204849_d.html 应用HTK搭建语音拨号系统--数据准备 苏统华 哈尔滨工业大学人工智能研究室 2006年10月30日 声明:版权所有,转载请注明作者和来源 该系统能够识别连续说出的数字串和若干组姓名。建模是针对子词(sub-word, eg. 音素),具有一定的可扩充性。当加入一个新名...

aig8440的博客 252

高准确率声学模型基于决策树的状态聚类

本文是对《Tree-Based State Tying For High Accuracy Acoustic Modelling》S.J.Young 的部分翻译,主要目的是为了促进个人对HMM状态绑定算法的理解。如有不妥或者有误的地方,欢迎指出,谢谢! Abstract 本文介绍了一种使用因素决策树创建状态绑定连续语音识别系统的方法,这种基于树的聚类方法和早期的数据驱动的方法识别性能相

Leora的博客 2926

HMM/GMM识别之三音素训练——决策树

三音素训练 决策树 为什么需要决策树 我们进行语音识别模型训练的过程中,首先进行的是单音素、单个高斯的模型训练。抛开单个高斯不说,单音素模型本身有很大缺点:没有考虑到本音素前后音素的发音对本音素的影响。比如,同样是一个音素iy,如果它前面的音素分别是h和p,那么iy这个音素在这两种情况下的发音会有所不同,那么模型参数也就会受到其影响,此时,如果用同一个模型来描述音素iy,那么就会不合理。 为了解...

audio_algorithm的博客 3202

5-基于决策树的状态绑定

本文会讨论关于context-dependent model的优化——基于决策树的状态绑定(Tree-based state tying)。 Outline: Context-dependent model Tree-based state tying 1. Context-dependent model 在《GMM-HMMs语音识别系统》中,默认的建模单...

bangdan0851的博客 417
上一篇: 修改HTK代码,让其支持中文
下一篇: C/C++文件输入输出操作——FILE*、fstream、windowsAPI
xiaoding133
博客等级 码龄19年 415粉丝 159原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值