kaldi008 -- pdf id and phone

最近需要解决一个问题:

在Kaldi下做完DNN训练之后,要怎么得到一段录音feature的后验概率,以及在有了这个后验概率之后怎么知道每一帧对应的是哪个状态,同时又是对应哪个phone。


首先,如何得到一段录音feature的后验概率。

由于DNN训练已经做完,已经得到了训练后的网络,那么只要把feature放进这个网络里面进行一遍从头到尾的运算,就可以得到这个后验概率。

在Kaldi里面用来完成这个穿行网络的过程的命令行工具叫做nnet-forward。

具体的使用方法是(文件具体路径已省略):

[plain]  view plain  copy
  1. nnet-forward --feature-transform=transformFile --apply-log=false --use-gpu=no nnet ark:featureFile ark,t:fwd.ark  

于是就可以得到fwd.ark这个文件,这个文件里面是什么内容呢?

里面就是这段feature经过这个网络的处理之后生成的一个矩阵。

那么这个矩阵的含义是什么呢?

我刚开始对这个矩阵的模糊理解是每一行表示一帧,每一列表示一个状态。


于是我就有了一个疑问,那么每一列对应的是哪一个状态呢?

首先我打开了.mdl文件,文件的第一部分是HMM的拓扑结构的描述,第二部分是(取前面几行):

<Triples> 2045 
1 0 0 
1 1 56 
1 2 48 
2 0 57 
2 0 125 
2 0 211

...

我在想这个部分的内容是否和state有关系。

那么就需要理解这个部分表示的是什么内容,后来经过在Kaldi群里面得到的指点知道了官方解释的地址:

http://kaldi.sourceforge.net/hmm.html#transition_model

  • A triple means a triple (phone, hmm-state, pdf) which is mappable to and from a transition-state.
所以最后的理解就是,第一列代表的是monophone的序号,第二列代表的是前面phone的三个状态的其中一个状态,第三列代表的是pdf,也就是概率分布函数的序号。

经过观察,有两个特点:

1. 总共有2045个这样的三元组

2. 第三列只有0-1963这1964个值

理解就是,2045代表的是triphone的个数,1964代表的是1964种不同的pdf。

这个时候还观察到的一点就是:

nnet-forward跑出来的矩阵的列数也是1964。

那么可以猜测:

这个矩阵的列对应的就是不同的pdf。


那么就有了下一个问题,怎么把pdf对应到state?

在翻阅资料下,我找到了一个工具:show-transitions。

这个工具的使用方法是(已省略文件具体路径):

[plain]  view plain  copy
  1. show-transitions phones.txt final.mdl  

输出内容如下(取前几行):

[plain]  view plain  copy
  1. Transition-state 1: phone = sil hmm-state = 0 pdf = 0  
  2.  Transition-id = 1 p = 0.728349 [self-loop]  
  3.  Transition-id = 2 p = 0.27165 [0 -> 1]  
  4. Transition-state 2: phone = sil hmm-state = 1 pdf = 56  
  5.  Transition-id = 3 p = 0.809842 [self-loop]  
  6.  Transition-id = 4 p = 0.190158 [1 -> 2]  
  7. Transition-state 3: phone = sil hmm-state = 2 pdf = 48  
  8.  Transition-id = 5 p = 0.475911 [self-loop]  
  9.  Transition-id = 6 p = 0.524089 [2 -> 3]  
可以看到,通过这个工具,能够找到phone-state和pdf的一个关联关系。

但很明显,并不是一一对应的关系,一个pdf可能对应多个phone。

一开始我也觉得这样似乎没法找到那个矩阵列项对应的phone。但后来在Kaldi官网上看到了一句话:

[plain]  view plain  copy
  1. If two states have the same pdf_class variable, then they will always share the same probability distribution function (p.d.f.)  

也就是说,如果两个状态有着同样的pdf,那么它们就会共享同样的概率分布函数。

这说明了什么呢?

后来我突然想到,既然有着同样的概率分布函数,那么说明共享这个pdf的那些状态都是对应同一列后验概率呀。

所以现在实际上已经知道了每一帧与所有状态对应的后验概率。


基本上知道这个已经可以解决我目前的需要了。如有理解不对还望指出。

但是关于知道了每个状态的后验概率之后怎么转换成phone序列?

这个似乎是decoding的事情,如果是decoding的话那么nnet-forward的用法是有所不同的。

有个参数--no-softmax=true,去掉后面的softmax,还有一个----class-frame-counts=xx用来加入一个先验概率。

后面好像是用HCLG这个东西,但是其中怎么运作的还不是很懂。有时间再看看

猜你喜欢

转载自blog.csdn.net/u012361418/article/details/73506448
id