精华内容
下载资源
问答
  • 基于GMM-HMM的语音识别系统
    千次阅读
    2021-05-28 16:56:26

    本文介绍GMM-HMM语音识别系统,虽然现在主流端到端系统,但是传统识别系统的学习是很有必要的。阅读本文前,需要了解语音特征提取、混合高斯模型GMM、隐马尔科夫模型HMM的基础知识(可以参考我的前几篇文章)。笔者能力有限,如有错误请指正!


    GMM-HMM语音识别系统的框架:

    1. 数据准备:数据源准备(wav/txt)、其他数据(词典、音素集等)、验证集、测试集
    2. 特征提取:MFCC
    3. 单音素GMM-HMM训练:单音素为三音素提供对齐
    4. 三音素GMM-HMM训练
    5. 解码

    语音识别的几个概念:

    • 对齐:音频和文本的对应关系
    • 训练:已知对齐,迭代计算模型参数
    • 解码:根据训练得到的模型参数,从音频推出文本

    基于孤立词的GMM-HMM语音识别

    问题简化,我们考虑(0-9)数字识别。整体思路:

    • 训练阶段,对于每个词用不同的音频作为训练样本,构建一个生成模型 P ( X ∣ W ) P(X|W) P(XW),W是词,X是音频特征(MFCC、Fbank参考这篇博客)
    • 解码阶段:给定一段音频特征,经过训练得到的模型,看哪个词生成这段音频的概率最大,取最大的那个词作为识别结果。

    X t e s t \mathbf{X}_{test} Xtest测试特征, P w ( X ) P_w(\mathbf{X}) Pw(X)是词 w w w的概率模型, v o c a b vocab vocab是词表:

    a n s w e r = arg ⁡ max ⁡ w ∈  vocab  P w ( X test  ) answer =\underset{w \in \text { vocab }}{\arg \max } P_{w}\left(\boldsymbol{X}_{\text {test }}\right) answer=w vocab argmaxPw(Xtest )

    假设我们给每个词建立了一个模型: P o n e ( X ) , P t w o ( X ) . . . P_{one}(X),P_{two}(X)... Pone(X),Ptwo(X)...,计算在每个词上的概率,选择所有词中概率最大的词作为识别结果。这样会有几个问题:用什么方法进行建模:DNN,GMM?这些够可以进行建模,但是语音任务的特点是序列性,不定长性,很难使用DNN、GMM直接进行建模。为了解决这些问题,我们可以利用HMM来进行序列建模。

    语音是一个序列, P w ( X ) P_w(X) Pw(X)可以用HMM的概率问题来描述,并且其中的观测是连续概率密度分布,我们可以为每个词建立一个GMM-HMM模型。

    建模

    语音识别中的GMM,采用对角GMM(协方差为对角阵),因为一般我们使用MFCC特征,MFCC特征各维之间已经做了去相关处理,各维之间相互独立,直接使用对角阵就可以描述,而且对角GMM参数量小。

    语音识别中的HMM,采用3状态,左右模型的HMM:

    • 为什么采用3状态?这是前人大量实验给出的经验值;
    • 左右模型的HMM:对于每个状态,它只能跳转到自身或者下一个状态。类似于人的发音过程,连续不可逆。

    HMM、GMM语音识别中如何结合?

    对于每个状态有一个GMM模型,对于每个词有一个HMM模型,当一段语音输入后,根据Viterbi算法得到一个序列在GMM-HMM上的概率,然后通过Viterbi回溯得到每帧属于HMM的哪个状态(对齐)。

    训练

    GMM-HMM模型参数:

    • 初始化参数(左右HMM):这参数没必要
    • 转移参数:自跳或者跳向下一个(两个参数)
    • 观测参数:混合系数、均值、方差

    Viterbi训练

    1. E步
      • Viterbi算法得到最优的状态序列(对齐),也就是在t时刻处于状态i上的概率(非0即1)
      • GMM模型中在t时刻处于状态i第k个GMM分量的概率
    2. M步
      • 更新转移参数、GMM参数(混合系数、均值、方差)
    3. 重复E、M步

    如何初始化GMM-HMM模型的参数?把语音进行均等切分,给每个状态分配对应的特征,然后去估计初始化的参数。

    前向后向训练(Baum-Welch训练)

    1. E步
      • 通过前向后向算法得到在时刻t处于状态i的概率
      • 在时刻t处于状态i且为GMM第k个分量的概率
    2. M步
      • 更新转移参数、GMM参数(混合系数、均值、方差)
    3. 重复E、M步

    Viterbi和Baum-Welch学习算法的详细内容参考我之前的文章。

    解码

    输入:各个词的GMM-HMM模型,未知的测试语音特征。

    输出:哪个词。

    主要关键点:对所有的词,如果计算 P w ( X t e s t ) P_w(X_{test}) Pw(Xtest)。可以通过:前向后算法,或者Viterbi算法(可以回溯到最优的状态序列),一般采用Viterbi算法。

    解码主要在图上做,我们现在看one two两个数字识别问题:

    构建HMM模型的拓扑图,下图是紧凑的解码图:

    通过Viterbi算法,找过最优的路径得到最终输出的词。那么如果我们需要对连续的多个词识别,需要如何建模?

    我们只需要再拓扑图上加一个循环连接,对于孤立词,如果达到了识别状态就结束了,对于连续词,如果达到了结束状态,就继续识别下一个词。每个HMM内部还是采用Viterbi算法,在每个时刻对于每个状态选择一条最大概率的路径。因为是并行的,在某个时刻,可能同时会有多个词达到结束状态,分别对应着一段路径,然后又要同时进行下一个词的识别,那么为了避免多余的计算,采用和Viterbi一样的思路,只选取最大概率的路径,扔掉其他。

    基于单音素的GMM-HMM语音识别系统

    孤立词系统的缺点:

    • 建模单元数、计算量和词典大小成正比
    • OOV(out of Vocabulary)问题,训练中没有这个词,测试中存在这个词;
    • 词的状态数对每个词不用,长词使用的状态数更多

    为了克服上边的问题,采用音素建模。每个音素使用3状态结构:

    简化问题:假设一句话中包含一个单词,比如one(W AA N),我们可以很容易得到三个音素的HMM状态图,将状态图进行平滑连接得到one的一整个HMM,然后进行和上述孤立词相同的过程。

    问题:如果一句话中包含多个单词?

    这个采用和上述相同的方法,加入循环结构,当到达结束状态时进行下一个词的识别。

    基于三音素的GMM-HMM语音识别系统

    单音素缺点:

    • 建模单元数少,一般英文系统的音素数30-60个,中文的音素数100个左右;
    • 音素的发音受上下文影响,比如:连读、吞音。

    可以考虑音素的上下文,一般考虑前一个/后一个,称为三音素,表示为A-B+C。比如:KEEP K IY P => #-K+IY, K-IY+P, IY-P+#。

    问题1:假设有N个音素,一共有多少个三音素? N 3 N^3 N3

    问题2:有的三音素训练数据少或者不存在,怎么办?

    问题3:有的三音素在训练中不存在,但在测试中有怎么办?

    问题2和问题3通过参数共享解决,下文将介绍决策树。

    参数共享

    共享可以在不同层面:

    • 共享高斯模型:所有状态都用同样的高斯模型,只是混合权重不一样;
    • 共享状态:允许不同的HMM模型使用一些相同的状态;
    • 共享模型:相似的三音素使用同样的HMM模型。

    笔者主要介绍共享状态,可以采用自顶向下的拆分,建立决策树来聚类。

    三音素决策树

    决策树是一个二叉树,每个非叶子节点上会有一个问题,叶子节点是一个绑定三音素的集合。绑定的粒度为状态(A-B+C和A-B+D的第1个状态绑定在一起,并不表示其第二第三个状态也要绑定在一起),也就是B的每个状态都有一颗小的决策树。

    问题集

    常见的有:

    • 元音 AA AE AH AO AW AX AXR AY EH ER …
    • 爆破音 B D G P T K
    • 鼻音 M N NG
    • 摩擦音 CH DH F JH S SH TH V Z ZH
    • 流音 L R W Y

    问题集的构建:语言学家定义,Kaldi中通过自顶向下的聚类自动构建问题集。

    决策树构建

    初始条件类似图中的根节点,"*-zh+*",从问题集中选择合适的问题,分裂该节点,使相近的三音素分类到相同的节点上。假设根节点所有三音素对应的特征服从一个多元单高斯分布,可以计算出该单高斯分布的均值和方差,则可以计算出该节点任意一个特征在高斯上的似然。

    模型:假设其服从单高斯分布,并且各维独立,也就是对角GMM
    Pr ⁡ [ x ] = 1 ∏ k = 1 N ( 2 π σ k 2 ) 1 / 2 ∏ k = 1 N exp ⁡ ( − 1 2 ( x k − μ k ) 2 σ k 2 ) \operatorname{Pr}[x]=\frac{1}{\prod_{k=1}^{N}\left(2 \pi \sigma_{k}^{2}\right)^{1 / 2}} \prod_{k=1}^{N} \exp \left(-\frac{1}{2} \frac{\left(x_{k}-\mu_{k}\right)^{2}}{\sigma_{k}^{2}}\right) Pr[x]=k=1N(2πσk2)1/21k=1Nexp(21σk2(xkμk)2)
    似然
    L ( S ) = − 1 2 ∑ i = 1 m [ ∑ k = 1 N log ⁡ ( 2 π σ k 2 ) + ∑ k = 1 N ( x i k − μ k ) 2 σ k 2 ] = − 1 2 [ m ∑ k = 1 N log ⁡ ( 2 π σ k 2 ) + m ∑ k = 1 N σ k 2 σ k 2 ] = − 1 2 [ m N ( 1 + log ⁡ ( 2 π ) ) + m ∑ k = 1 N log ⁡ ( σ k 2 ) ] \begin{aligned} L(S) &=-\frac{1}{2} \sum_{i=1}^{m}\left[\sum_{k=1}^{N} \log \left(2 \pi \sigma_{k}^{2}\right)+\sum_{k=1}^{N} \frac{\left(x_{i k}-\mu_{k}\right)^{2}}{\sigma_{k}^{2}}\right] \\ &=-\frac{1}{2}\left[m \sum_{k=1}^{N} \log \left(2 \pi \sigma_{k}^{2}\right)+m \sum_{k=1}^{N} \frac{\sigma_{k}^{2}}{\sigma_{k}^{2}}\right] \\ &=-\frac{1}{2}\left[m N(1+\log (2 \pi))+m \sum_{k=1}^{N} \log \left(\sigma_{k}^{2}\right)\right] \end{aligned} L(S)=21i=1m[k=1Nlog(2πσk2)+k=1Nσk2(xikμk)2]=21[mk=1Nlog(2πσk2)+mk=1Nσk2σk2]=21[mN(1+log(2π))+mk=1Nlog(σk2)]

    假设通过某个问题将该节点的三音素对应的特征分成两部分(l 和 r),则这两部分的似然和为:
    L ( S l ) + L ( S r ) = − 1 2 m N ( 1 + log ⁡ ( 2 π ) ) − 1 2 [ m l ∑ k = 1 N log ⁡ ( σ l k 2 ) + m r ∑ k = 1 N log ⁡ ( σ r k 2 ) ] L\left(S_{l}\right)+L\left(S_{r}\right)=-\frac{1}{2} m N(1+\log (2 \pi))-\frac{1}{2}\left[m_{l} \sum_{k=1}^{N} \log \left(\sigma_{l k}^{2}\right)+m_{r} \sum_{k=1}^{N} \log \left(\sigma_{r k}^{2}\right)\right] L(Sl)+L(Sr)=21mN(1+log(2π))21[mlk=1Nlog(σlk2)+mrk=1Nlog(σrk2)]
    分裂前后的似然变化(增益)为:
    L ( S l ) + L ( S r ) − L ( S ) L\left(S_{l}\right)+L\left(S_{r}\right)-L(S) L(Sl)+L(Sr)L(S)
    似然增益越大,说明分裂后两部分数据之间的差异越大,则应该使用两个单独的GMM分别建模,则选择似然增益最大的问题进行划分(最优问题)。根节点一份为2后,递归执行该算法直至达到一定终止条件,通常是分裂达到一定数量的叶子节点或者似然增益已经低于一定阈值。

    总结

    1. 初始状态(单因素系统对齐,一个根节点)
    2. 选择一个节点,从问题集中选择似然增益最大的问题作为该节点问题,建立该节点左右子节点,并将该节点一分为二
    3. 重复2,直至满足一定的终止条件。

    基于GMM-HMM语音识别系统流程

    1. 数据准备:音素列表、词典、训练数据
    2. 特征提取:MFCC特征
    3. 单音素GMM-HMM:Viterbi训练
    4. 三音素GMM-HMM:三音素决策树、Viterbi训练
    5. 解码

    问题:为什么先做单音素训练?

    通过单音素模型上Viterbi算法得到与输入对应的最佳状态序列(对齐)。

    参考:

    https://blog.csdn.net/Magical_Bubble/article/details/90408095

    https://zhuanlan.zhihu.com/p/63753017

    更多相关内容
  • 简单的GMMHMM模型的Python实现,用于隔离数字识别。 此实现包含3个模型: 单一高斯:使用具有对角协方差的单一高斯对每个数字进行建模。 高斯混合模型(GMM):每个数字都是使用高斯混合模型来建模的,并通过...
  • 首先明确这是一个基于GMM-HMM的嵌入式命令词识别系统,它和基于GMM-HMM的孤立词识别系统有很大不同,孤立词识别系统的很好的一个参考文章是这篇,下面将简要介绍两个模型的区别,图和说明都是为了表述而简化的概念性...

    一、准备

    首先明确这是一个基于GMM-HMM的嵌入式命令词识别系统,它和基于GMM-HMM的孤立词识别系统有很大不同,孤立词识别系统的很好的一个参考文章是这篇,下面将简要介绍两个模型的区别,图和说明都是为了表述而简化的概念性版本,和我们实际操作的细节会有一些区别。

    简要地说,孤立词的GMM-HMM模型是每个需要识别的词对应一个GMM-HMM,如图所示:

    假设我们需要识别的词包括“前进”、“后退”、“左转”、“右转”,那么我们就会建立四个模型,每个模型对应其中的一个词,模型训练的时候,每个词的音频就用来训练其对应的GMM-HMM,最大化似然概率,训练完成之后,当我们遇到新的输入 x x x的时,我们把 x x x分别输入到这四个模型中,然后计算出四个似然概率,哪个大我们就认为 x x x是哪个词。

    在这个模型中,每个词的训练数据只用来训练它自己的GMM-HMM,而与其他词无关,因而称为一个孤立词识别系统,这样的模型搭建简单,容易训练,针对性强,但是你会发现它有个问题,明明左转和右转里都有一个“转”字,那“左转”和“右转”的音频里应该有相似的部分可以让模型从二者的共性中学的更好啊,而且,如果我要新加一个命令词“跳跃”,我就要重新收集数据然后训练这个GMM-HMM,在命令词较多或需要动态扩充命令词的时候就十分麻烦。

    因而,我们可以考虑建立一个嵌入式的GMM-HMM命令词识别系统,这个系统如图所示

     

    我们不再把每个词对应一个GMM-HMM,而是把每个声韵母对应一个GMM-HMM,训练的时候,我们只需要将声韵母序列对应的GMM-HMM连接起来(具体怎么连实验步骤中有),然后训练,比如“前进”的声韵母序列是“q”,“ian”,“j”,“in”,因此我们只需要把“q”,“ian”,“j”,“in”分别对应的GMM-HMM连起来,然后来训练这个样本即可。当我们遇到新的输入 x x x的时,我们把 x x x分别输入到这四个连起来的GMM-HMM中,然后计算出四个似然概率,哪个大我们就认为 x x x是哪个词。

    由于我们的模型是音素级别的,当我们遇到需要识别的词时,我们只需要把对应的音素序列的GMM-HMM连接起来,这个过程就是一个嵌入的过程,因此称它为嵌入式的模型,注意到这个时候,我们甚至不需要准备“前进”、“后退”这样的训练数据,我们可以准备任意语音-句子对,只要保证我们的数据集中包括“q”,“ian”,“j”,“in”等音素即可,而且,当我们需要新增一个命令词“跳跃”时,我们只需要将“t”,“iao”,“y”,“ue”四个因素的GMM-HMM连接起来计算似然概率即可,无须重新训练模型,这样的模型可以用来识别几乎任意命令词(只要训练集中包含相应的音素),灵活性大大提高,只不过训练需要较多的数据、模型搭建较复杂。

    二、开始

    下面开始构建一个嵌入式命令词识别系统,其目的就是识别“前进”、“后退”、“左转”、“右转”
    数据准备

    首先来了解一下训练数据到底是什么样的,录音总共350句话,一句话对应一个音频,内容举例:

        毛巾上有一个洞。
        很抱歉,他们都在忙。很抱歉,他们都在忙。
        你能帮我将这个东西抬起来吗?
        请问,这个座位有人坐了吗?

    可以看到,这些数据并没有刻意为“前进”等命令词准备,而是随机的日常对话。

    为了建立嵌入式的音素级命令词识别系统,我们需要首先将这些句子都转化成音素序列,这里我用的是DaCiDian,里面有每个字对应的音素,其实就是一个简单的字到音素的映射过程,转化结果如下:

    其中sil代表silence,因为每段录音的前后总会有一段静音的时间,需要在HMM里加入sil音素来对应这段时间的音频,这里的音素我使用的是带声调的版本。实际转化中存在多音字的错误问题,然而无伤大雅,只要一致即可,因此没有人为去处理这些问题(主要是因为懒),最后一共有181种音素。

    我们日常说话中,说出来的各个音素的次数都是不同的,在这个数据集中,不同音素的出现次数如图所示:

    其中,出现次数前五的音素分别是:’sil’ 700次,’i_0’413次,’y’390次,’d’387次,’sh’264次,出现次数仅为1次的音素有10种,这种不平衡问题会导致出现次数较少的音素所对应的模型无法得到充分训练,由于我们使用的是GMM-HMM模型,GMM模型在数据少的时候协方差矩阵难以估计,因此,将所有出现次数小于5次的音素使用特殊音素’UNK’替代,采用这种方法,数据集中总共有27类共67出现频次的音素被“UNK”替代,最后得到的音素类别为155个。

    音频特征我们使用各个维度独立的13维MFCC特征,这也是我们GMM模型的重要假设。

    三、模型建立及初始化

     因为GMM-HMM是使用EM算法进行训练,所以需要参数初始化。

    1. HMM初始化

    根据数据预处理结果,我们需要建立155个GMM-HMM模型,这里我们每个音素的GMM-HMM采用通常的参数设置方法,其HMM共有4个状态(省略了开始状态),除了结束状态,中间三个状态都为发射状态(一般我们认为它们分别对应音素的开始,中间和结束),每个发射状态对应一个由3个高斯分布组成的GMM,然后先初始化HMM的初始分布和状态转移矩阵,以uang_1为例:

    2. GMM初始化

     那么如何来初始化每个状态对应的GMM呢?为了初始化GMM,我们需要把音素的GMM-HMM连起来,之前说了很多遍连起来,具体怎么连还是看下图,这是一个我对“彩虹”连接的示例:

    其实就是将GMM-HMM首尾相连嘛,连接之后,去掉中间的end状态,仅保留最后的end状态(包括之前去掉start状态,这些是我为了我编程时的方便的做法,具体操作因人而异),连接好之后,还需要将参数整合到一起,如果音素的小HMM转移矩阵如上图所示,那么连接后的大HMM的转移矩阵就是:

    显然,初始的状态分布应该是:

     

    而对于GMM参数,因为每个状态与其自己的GMM状态参数一一对应,所以在连接的时候也不需要什么特别的操作。

    当然回到主题,这里连接GMM-HMM是为了初始化GMM参数,见下图:

    与HMM不同,我们需要根据音频特征来初始化GMM的参数(因为GMM-HMM的训练对GMM初始参数很敏感,因此不能像HMM那样随便初始化),我们首先来数一数上图中的发射状态数,共有12个,假设T=24,那么每个状态就会分到两个特征,具体地,就是第一个s1分到o1 o2,第一个s2分到o3 o4,以此类推,就是通过均分特征序列将两个序列有序地对齐起来。

    注意到我们每个音素不仅仅是在一个句子中出现(甚至也会在一句话中出现多次),因此在我们对整个数据集进行此操作之后,每个音素的三个状态都会被分配到很多特征,从而我们可以对每个音素每个状态对应的GMM进行初始化(使用k-means算法),这样我们就初始化好了GMM的参数。

    四、训练

    初始化完成后,我们终于可以开始训练模型啦,这里使用的是Viterbi训练方法,整个过程是一个EM算法,分为E步和M步,概括地说,在E步,我们用当前参数重新根据Viterbi算法计算出一个特征和状态的对齐结果(刚刚初始化的时候我们用的是平均分割的对齐方法),然后在M步我们根据新的对齐结果重新估计参数。其实前面两个步骤理解完成之后,这个步骤就相对简单了。

    1. E step

    E步的时候就是重算对齐结果,这里直接使用Viterbi算法就可以了,如果不了解可以直接看网上的关于Viterbi算法的教程,简单说,我们使用了Viterbi算法,就可以计算出一个新的特征序列和状态序列的对齐结果,也就是知道哪些特征对应哪些状态,从而可以继续进行M step,下面就是一个Viterbi对齐结果:

    这里呢,在E step额外要做的就是使用前向算法计算每个训练数据的似然概率,然后计算整个数据集的平均似然概率,作为模型训练程度的一个参考数值,通过前后两轮的似然概率之差,我们可以决定在何时终止模型的训练。

    在整个数据集上完成上述操作即可开始M step。

    2. M step

     

    在M step,我们需要重新估计模型的参数,这些参数包括HMM的状态转移矩阵,以及GMM的参数,首先,对于HMM的状态转移矩阵参数估计,其本质上就是个数数的过程,以上图的结果为例,s1对应o1 o2 o3,s2对应o4 o5,s3对应o7 o8,第二个s1对应o9 o10 o11 o12,那么第一个s1就有两次转移到自身(o1->o2, o2->o3),一次转移到s2(o3->o4),因此 之后的各个转移概率就这样一个个更新,需要注意的是,这里举的例子是一个语音——状态对的统计结果,实际训练时,我们是按照整个训练集上的统计结果进行状态转移矩阵更新的。

    对于GMM的参数,那就更简单了,每个状态直接根据被分配到的特征来更新(k-means初始化或者训练GMM)就可以了。

    3. 训练过程

    模型在整个数据集上的对数似然和训练轮次如图所示:

     在验证集(专门录制的“前进”、“后退”、“左转”、“右转”每个5句共20句的数据集)上的准确率如图所示:

     

    可以看到模型的验证集最好的结果是95%准确率,模型训练初始阶段平均对数似然不断上升,随后发生震荡。

    4. 训练结果

    Viterbi算法最有趣的部分就是它可以对其两个序列,而无需我们进行这种精度的标注,最后95%准确率模型的Viterbi对齐结果示例如图所示:

    可以看到对齐的结果还是很准,这种模型的解释性也就挺好。


    五、细节问题

    为了行文的顺畅,很多细节问题都没有加以讨论,在此简单讨论其中几个关键问题:

    1. 过拟合问题

    其实最开始写完模型,是有严重的过拟合问题的,模型几乎瞬间在验证集上达到顶峰,随后一直在25%不变,为了解决这个问题,我选择了13维的MFCC特征而不是通常差分过的39维MFCC特征,这样减少了GMM的参数,一定程度上降低了过拟合问题,另一个想到的解决方法是使用不带声调的声韵母系统,不过我还没尝试。

    2. 数值问题

    用numpy和scipy从零开始搭这个系统,就需要自己解决其中存在的很多数值问题,比如有的音素的状态的GMM中某个高斯的协方差矩阵数值太小等问题,当然,导致这些问题的原因其实也是数据量不均匀,有的音素数据多,有的音素数据少,就使得你不可能单纯通过降低模型参数来解决这个问题(会导致数据多的音素欠拟合),为了解决这个问题,代码中我但凡碰到这种协方差矩阵,就将该高斯直接从GMM成分中舍弃,这样做其实是建立了一个动态K的GMM模型。

    3. 标点符号

    日常用语中带停顿的标点符号我也按照通常的做法使用’sp’音素代替了。

    4. GMM

    我在hmm_learn里面看到他们会使用协方差的对角矩阵来简化协方差矩阵,也算是减少参数的方法,因此我所有的GMM中使用的也是对角矩阵

    5. 参数重估

    HMM的状态转移参数重估的时候我加入了平滑,也就是分母和分子都+1,来保护一些较小的转移

    6. 概率

    GMM的参数重估方法我仅仅用K-means对其进行重新初始化了,这里我实在不清楚到底是要将GMM训练到收敛还是仅仅重新初始化它,因此我选了一个比较快的方法

    7. LogSumExp

    永远不要自己尝试去写什么logsumexp softmax之类的东西,就算你知道算的时候要减去一个最大值来保证exp的数值稳定,可你写的还是会爆炸…

    本项目的数据在这个地址:链接: https://pan.baidu.com/s/1Ewz8ZyzEM8F6VYVZGynn8w 提取码: aonm

     

     

    展开全文
  • 扫描下方“AI大道理”,选择“关注”公众号上一专题GMM-HMM声学模型中讲述了其理论知识,这一章利用理论搭建一套GMM-HMM系统,来识别连续0123456789的英文语音。本系统是单音素,未涉及后面三音子的训练以及决策树的...

    9e2244991dcfbca322f132455b441728.png

    扫描下方“AI大道理”,选择“关注”公众号

    上一专题GMM-HMM声学模型中讲述了其理论知识,这一章利用理论搭建一套GMM-HMM系统,来识别连续0123456789的英文语音。

    本系统是单音素,未涉及后面三音子的训练以及决策树的内容。

    3e2564107011601ad56f40beb6eb7273.png

    在GMM专题和HMM专题中分别讲述了其训练都是EM算法,那么融合形成GMM-HMM模型后会如何训练?是应用一个EM算法还是分别应用EM算法呢?

    1 Viterbi解码

    在HMM专题中,HMM解码有两种方法,分别为Viterbi算法和近似算法,本系统采用Viterbi算法进行解码。

    针对一句语料进行解码,提取该句语料特征:68*12,其中,68表示帧数,12表示MFCC特征。

    预先训练了HMM对由孤立数字组成的数据的观察概率,这就是初始模型,将用来解码(识别、预测、测试)。

    即给定模型λ=(A,B,Π)和观测序列O={o1,o2,...oT},求给定观测序列条件下,最可能出现的对应的状态序列。

    Viterbi解码作为识别结果(预测结果),可以在此基础上进行优化训练模型。

    系统文件:

    13063a18920dd8157fbdb734729acfe5.png

    ​src/

    580895ee67cdc3127dece1b21eb02eb5.png

    ​步骤一:传入音频数据

    输入:GMM参数、状态转移参数、音频数据、单词标签

    输出:chart

    c5f08f5cff543126237331ddeda2fc28.png

    870242813ab5e2b4ddc1fed90db4d895.png

    步骤二:前段信号处理(计算mfcc,gmm_probs等)

    3c6690937b9a4042e5aa24fd3a3a3b1f.png

    mainObj.init_utt():

    5cbff2af23ef0005029f05d9a3aeb418.png

    计算每帧MFCC特征:

    e1fd301f316fb2810107f054047f3cbf.png

    ​计算每帧gmm_probs:

    8d225e22bb0fd89722c021a6af233f06.png

    步骤三:Viterbi解码

    随机数字串的识别网络:

    串接HMM

    b276a61d2ca68a5b0c4b8d337dcec12e.png

    随机数字串的解码网络:

    第一帧可从任意一个数字的HMM的开始状态开始,对比所有路径,选择概率最大的那条路径作为解码结果。

    88ebd1e5e9b24f0b6147ac0a8778d97c.png

    Viterbi算法流程:

    efe9b8144ab83d25ef6206f6f648d696.png

    ​算法实现:

    cdea072e29ba413f137cf9f77dd4ca21.png

    输出chart:

    b13093f3b90267e79107a5c80f20f2f3.png

    ​步骤四:Viterbi回溯

    实际上chart图最后一帧即为最大似然概率对应的弧号,可以基于此回溯得到完成的弧号序列,弧号与状态之间存在映射关。

    a87ffc126157c8b678629eeebab17c2f.png

    ​回溯结果:

    16adb08754baf0d83157ac72e2bdd190.png

    对于输入一段语音,解码结果为:

    Nine Two Nine Four Five Two Five Eight Nine Two

    (解码实际上是获得最可能的状态系列,状态可以组成音素,音素可以组成单词)

    2 GMM训练
    Viterbi-EM训练

    上述Viterbi解码是为GMM-HMM训练做准备的,提供了对齐的数据。

    在HMM专题中,HMM训练有两种方法,分别为Viterbi训练和Baum-Welch训练。

    Viterbi学习算法是一种硬对齐,所谓硬对齐就是只有0或者1的归属,即一帧只归宿于某个状态,而Baum-Welch学习算法是一种软对齐,即一帧以一定概率归宿于某个状态。

    模型的训练即给定观测序列O={o1,o2,...oT}和初始模型,调整模型λ=(A,B,Π)的参数,使该模型下观测序列的条件概率P(O|λ)最大。

    (不能无中生有的训练一个λ=(A,B,Π),要有一个坏的初始模型为基础来调整参数。GMM参数训练必须依托于HMM,随着HMM的E步更新而更新)

    Viterbi-EM训练全过程:
    首先初始化对齐,平均分配帧给状态,可以得到初始GMM-HMM模型,利用初始模型和初始参数进行Viterbi解码,得到新的对齐。对齐后进行hard count。这里hard count 是HMM训练的E步,也是GMM训练的基础,GMM训练的数据就是count后得到的。
    count后HMM可以进行M步得到转移概率,这就是模型中的A参数。GMM则在count基础上进行E步计算后验概率,再进行M步得到新的均值和方差参数,这是模型中的B参数。

    至于Π,就是[1,0,0,0...],一开始在状态一的概率是100%。

    在语音识别应用中由于HMM是从左到右的模型,第一个必然是状态一,即P(q0=1)=1。所以没有pi这个参数了。

    24a4812d5e11af0d521015f2d3420373.png

    注释:

    没有考虑HMM中所有可能的路径来计算每个帧处每个弧的后验计数,而是使用维特比解码来找到HMM中的单个最可能路径。

    步骤一:传入数据

    输入:初始GMM参数、Viterbi解码的最优状态序列、音频数据、迭代次数

    输出:新GMM参数

    de3e6c04c50bd8a6e4880ed6fe4f77ed.png

    272e614ead29139761263eae5d4b3291.png

    ​步骤二:HMM的E步:hard count

    43ec4dfa7687a12c1530dfd2818a43b0.png

    gmmStates.updata():

    00301f051d377eb89f1aeb14429c9a70.png

    步骤三:GMM的EM步

    add_gmm_count:

    根据count获得多少帧对应一个状态,而这个状态对应着一个GMM,以这些帧的数据重新计算GMM参数。

    d3f8dde11a5852e5be41b83c2a247687.png

    ​步骤四:更新GMM参数

    gmmStates.reestimate():

    b18a4928c38ba5ca93553d51cc9651db.png

    ​GMM新参数与初始参数对比:

    d904ef5a0c45fdf59748255ab1af372b.png

    3 前向后向算法训练
    基于Viterbi-EM算法来估计模型对于计算语料中帧对应状态的弧号存在计算复杂度指数级增加的问题,为解决上述问题,可以用前向后向算法来估计模型中参数。

    Baum-Welch学习算法也叫前向后向算法,是一种软对齐,即一帧以一定概率归宿于某个状态。

    Baum-Welch训练全过程:
    首先初始化对齐,平均分配帧给状态,可以得到初始GMM-HMM模型(也可以任意初始化所有参数),利用初始模型和初始参数进行Baum-Welch算法。

    Baum-Welch算法考虑所有的路径,对于某个状态,将所有时刻的状态占用概率相加,可以认为是一个软次数,即进行soft count,估计状态占用概率(期望),即EM算法的E步。

    基于估计的状态占用概率,重新估计参数 λ (最大化),即EM算法的M步。

    至于Π,就是[1,0,0,0...],一开始在状态一的概率是100%。在语音识别应用中由于HMM是从左到右的模型,第一个必然是状态一,即P(q0=1)=1。所以没有pi这个参数了。

    a0a60098df18a5d67355d3ec63f56be4.png

    注释:

    我们的词汇由十二个单词(一到九,零,OH和静默)组成,总共包含34个音素。每个音素使用3个HMM状态(不包括nal状态),总共有102个状态。这些状态中的每一个都有我们需要向其分配概率的两个输出弧,以及我们需要进行估计的GMM/高斯曲线。为简单起见,我们将忽略转移概率(将它们全部设置为1)。实际上,转移概率对性能的影响很小。

    步骤一:传入数据

    输入:初始GMM参数、状态转移参数(fsm图)、音频数据、迭代次数

    输出:更新后GMM参数

    c3c9d94078b19f104f467c8519711848.png

    2e47af21424cad5b1348fff7e9f61593.png

    步骤二:前向后向算法计算后验概率

    69ce4c4ebd4269766ca5810ebee11513.png

    forward_backward():

    7025e8f9cc8ddda41a18203f8dd8e544.png

    ​算法实现:

    8cc407f060af5277a30f5afb52808a98.png

    ​步骤三:GMM的EM步(与上同)

    gmmStates.update()

    步骤四:更新GMM参数(与上同)

    gmmStates.reestimate()

    9e46eae386b7bcd4f7efe4366547a747.png

    da725b73e4a9c88c38384759bc667a77.png

    6ab753858588f5be711adf3f82fe401f.png

    5f5f7ec5eb301db0c50916490f7ebd7c.png

    最终将前向概率与后向概率以及gmm模型的权重写入值chart图中,其中gmm权重在代码中表示为后验概率,最后后验概率表示如下图所示。

    从上图可知,gmm权重大部分为0,这样大大减少了模型计算量且便于参数计算。

    4 GMM-HMM模型测试

    f3eaefa6d11d93845a4c2b75b00e19aa.png

    这是前向后向算法进行五次迭代训练出来的GMM-HMM模型。其中N是num总数,C是corr准确数,S是sub替换错误,D是Del是删除错误,I是INS插入错误。

    模型识别率为68%。

    5 总结

    如果不是针对数字,而是所有普通词汇,可能达到十几万个词,解码过程将非常复杂,识别结果组合太多,识别结果不会太理想。因此需要引入语言模型来约束识别结果。让“今天天气很好”的概率高于“今天天汽很好”的概率,得到声学模型概率高,又符合表达的句子。

    ——————

    浅谈则止,细致入微AI大道理

    扫描下方“AI大道理”,选择“关注”公众号

    58f6883300a10ea28b6cab3bd9f09764.png

    欢迎加入!

    4b5b4c444e7ae16532055f1a6c1cc6bb.png

    下期预告

    AI大语音(十)——语言模型

    往期精彩回顾

    AI大语音(一)——语音识别基础

    AI大语音(二)——语音预处理

    AI大语音(三)——傅里叶变换家族

    AI大语音(四)——MFCC特征提取

    AI大语音(五)——隐马尔科夫模型(HMM)

    AI大语音(六)——混合高斯模型(GMM)

    AI大语音(七)——基于GMM的0-9语音识别系统

    AI大语音(八)——GMM-HMM声学模型

    留你心,言你想

    展开全文
  • hmm模型matlab代码HMM-GMM 这是我个人实现的隐马尔可夫模型和高斯混合模型,这是统计机器学习中的两个经典生成模型。 HMM是在无监督的情况下进行训练的,代码实现了前向后退算法,以在给出部分/全部观测值的任何时间...
  • GMM-HMM方法(滑动查看解码) DNN-HMM方法(滑动查看解码) (点击查看大图) 实践项目 本门课程采用理论与实践相结合的教学方式,通过8个实践项目,让大家将课上所学知识,即学即用,通过亲自动手实践达到灵活掌握...

    语音识别是智能交互中大家接触极其广泛的技术,随着深度学习的突破,语音识别技术得到了长足的发展并且具备 “快” “易” “Hands-Free” 等特点及优势。

    语音识别技术不断发展,落地应用远不止于“替代输入法”,手机语音助手、智能家居、无人驾驶、移动机器人语音指令交互等众多场景中,语音识别技术都扮演着不可或缺的角色。

    落地应用虽然广,但高端语音识别专业人才却是急缺,这主要因为语音识别具有典型的跨学科特点,涉及声学、语音语言学、信号处理、概率论、机器学习及算法设计等多个方面的专业知识。

    对于学习者而言,语音识别系统模块众多,入门具有较高门槛,很多伙伴在学习中会遇到各种问题:

    ·了解语音识别系统的组成模块,但不知道各模块作用是什么;

    · 在特征提取过程中,如何保留有用信息,抑制无关信息?

    · 声学模型是如何在语音特征和因素之间建立映射关系的?

    · 在海量的句子中,解码器怎样才能快速找到比较好的识别结果?

    那怎样高效系统学习语音识别,并达到精通的水平?

    基于此,深蓝学院推出『语音识别:从入门到精通』在线课程,内容涵盖了语音识别的核心方法与前沿技术,希望通过本门课程的学习,让大家可以系统高效地搭建语音识别系统的众多模块,快速入门语音识别,少走弯路。

    课程大纲

    (点击图片,查看大图)

    本期课程部分章节全新录制,并新增核心算法系统流程,通过形象且详细的流程图,从孤立词到单音素,由浅入深,帮助大家在学习中梳理思路,更清晰理解知识脉络。

    GMM-HMM方法(滑动查看解码)

    DNN-HMM方法(滑动查看解码)

    (点击查看大图)

    实践项目

    本门课程采用理论与实践相结合的教学方式,通过8个实践项目,让大家将课上所学知识,即学即用,通过亲自动手实践达到灵活掌握,融会贯通的效果。

    (点击查看大图)

    讲师阵容

    (点击图片,查看大图)

    学后收获

    1. 掌握系统性的语音处理及语音识别专业知识

    2. 掌握核心及当前主流的语音识别算法及模型

    3. 具备独立实现算法与完成实践项目的能力

    4. 洞察业界主流语音识别技术与前沿方法

    还能收获什么?

    1. 优质的学习圈子

    伙伴们大多是来自985、211及海外院校硕博,在这里大家一起学习、进行讨论与研究。独一无二的优质圈子将是你未来学习与就业的宝贵资源。

    2. 企业认可的证书

    学完课程后将有机会收获优秀学员证书、毕业证书,为你的简历加分添彩。

    课程服务

    1. 三师助力

    讲师&助教及时答疑解惑,班主任全程带班督学,帮你克服拖延,不断进步。

    (左右滑动查看更多)

    2. 定期班会

    助教会对作业进行1V1讲评和指导;在班会中,学习更多技巧;在交流中收获更多思路。


    抢占学习名额

    最后12个学习名额!

    扫码备注“22”,优先通过哦~

    添加客服『叶子

    免费获取近期基于end-to-end 

    ASR论文集~

    展开全文
  • GMM-HMM声学模型实例详解 GMM-HMM为经典的声学模型,基于深度神经网络的语音识别技术,其实就是神经网络代替了GMM来对HMM的观察概率进行建模,建模解码等识别流程的格个模块仍然沿用经典的语音识别技术 接下来我将从...
  • 动手搭建一个基于GMM-HMM的嵌入式命令词识别系统 。,。 写在前面 尽管如今基于深度学习的语音识别系统在性能上远远超过普通的语音识别系统,但是尝试去编写并理解一个传统语音识别系统也是一个非常有趣的过程。这个...
  • 都知道语音识别有GMM-HMM模型,也分别了解了什么是: GMM(混合高斯模型)https://blog.csdn.net/qq_37385726/article/details/89198387 MMC(马尔可夫链)...
  • GMM-HMM孤立词识别

    千次阅读 2019-09-19 16:45:34
    之前做过的GMM-HMM孤立词识别,现在整理一下。 这里我们把输入的语音当做语音识别中的一个音素来建模,假定建模的HMM状态链是7状态的,因此,孤立词识别就是只用到了声学模型部分,没有涉及语言模型这些。 1、将...
  • Python实现的GMM用于语音识别,里面有数据和相关的PDF论文。
  • gmm-hmm就是把我们的特征用混合高斯模型区模拟,然后把均值和方差输入到hmm的模型里。 此外,dnn-hmm的模型图: 最后是dbn-hmm:   希望我寒假过来可以很好的解释这三个图,如果有人...
  • 孤立词语音识别.zip

    2020-05-12 18:07:33
    基于GMM-HMM的孤立词语音识别系统,内含训练和测试数据,是1-10的数字的音频,测试数据也是1-10,当然你可以自己改,只要改了标签即可。运行需要安装hmmlearn,scipy,numpy
  • GMM-HMM语音识别

    2015-09-10 21:46:07
    GMM-HMM语音识别模型原理篇(主要) http://blog.csdn.net/abcjennifer/article/details/27346787 GMM的EM算法实现  http://blog.csdn.net/abcjennifer/article/details/8198352 隐马尔科夫模型HMM自学(联系实际...
  • 在孤立词语音识别(Isolated Word Speech Recognition) 中,DTW,GMMHMM 是三种典型的方法: 动态时间规整(DTW, Dyanmic Time Warping) 高斯混合模型(GMM, Gaussian Mixed Model) 隐马尔可夫模型(HMM, Hidden ...
  • 这是基于Kaldi工具包和GStreamer框架并以Python实现的实时全双工实时语音识别服务器。 广告 塔林工业大学正在寻找一名从事语音识别的博士生,重点是轻度代码转换的语音(例如,芬兰语包含很多英语技术术语)。 。 ...
  • GMM-HMM在语音识别中的应用

    千次阅读 2018-01-04 13:47:58
    3.GMM高斯混合模型 3.1高斯混合模型的基本概念   高斯混合模型是指具有如下形式的概率分布模型: p(y⏐θ)=∑k=1kαkϕ(y⏐θk)p(y\arrowvert\theta)=\sum_{k=1}^{k}{\alpha_{k}}\phi(y\arrowvert\theta_{k})...
  • 声学模型学习笔记(三) DNN-HMM hybrid system
  • https://github.com/jayaram1125/Single-Word-Speech-Recognition-using-GMM-HMM- 数据集得自己造: # -----------------------------------------------------------------------------------------...
  • 声纹识别之GMM-UBM系统框架简介

    万次阅读 多人点赞 2018-07-17 18:25:11
    GMM-UBM实际上是一种对GMM的改进方法,我们既然没法从目标用户那里收集到足够的语音,那就换一种思路,可以从其他地方收集到大量非目标用户的声音,我们将这些非目标用户数据(声纹识别领域称为背景数据)混合起来...
  • gmm的matlab代码高斯混合模型 ...Calinon的pbdlib-python资料库[Link:]中演示的GMM / HMM / HSMM模型的过程,以便训练机器人轨迹,以实现从演示中学习LfD的目的。 程序 创建文件夹 克隆存储库 git clone ...
  • 使用python建立HMM-GMM孤立词识别模型 里面有代码链接,还有hmmlearn的文档链接。还是再贴一下文档链接吧,便于自己查找。 hmmlearn文档 这个例子使用的训练和测试语音,好像是德语的1到10,不是德语也无所谓啦,...
  • 基于Kaldi的DNN-HMM语音识别系统,run.sh文件包含从前期数据准备到最后解码的整个过程,该脚本是语音识别各个步骤的封装。 #!/bin/dash # Copyright 2016 Tsinghua University (Author: Dong Wang, Xuewei Zhang)...
  • 欢迎大家关注我的博客 ... 本部分是对Kaldi thchs30 中run.sh的代码的line 106-107 行研究和知识总结,主要内容为Kaldi中nnet1的DNN-HMM模型训练。 概览 首先放代码: #train dnn model ...
  • 附0-9孤立词识别(python),代码整体介绍:训练--对每一个GMM使用预料进行五次迭代训练;测试--对每条测试预料求每一个GMM模型下的似然,求argmax得到似然最大的模型最为输出结果,并和标签进行对比求正确率。
  • LiJian-kaldi搭建在线语音识别系统 资料汇总

    千次阅读 多人点赞 2021-06-08 20:17:45
    graph P5 GMM-HMM算法&HCLG过程&训练脚本讲解 GMM+HMM的理论部分我建议学习李航老师的《统计学习方法(第二版)》,主要学习:HMM评价、解码和参数估计问题,视频的话建议学习李琳山老师的数字语音处理,b站上也有...
  • 上一篇文章详细解析了 GMM+HMM语音识别模型,在这篇文章中,我们将重点介绍DNN+HMM语音识别模型 将DNN应用在语音识别有两种方式: 1. 令DNN取代GMM+HMM中的GMM, 但是首先要训练一个GMM+HMM的语音识别模型,得到...
  • 说明 Baum-Welch 也是马氏三问之一,是模型学习的方法。 内容 还是使用上一篇的例子,黑箱摸球。...from hmmlearn import hmm states = ['box1','box2','box3'] n_states = len(states) observations = ['red','whi
  • GMM中使用EM算法 一、高斯混合模型(GMM) 1、一维高斯分布 2、多维高斯分布 3、高斯混合模型 从几何角度来看:多个高斯分布叠加而成 πk是x点属于哪个高斯分布的权重 二、EM算法:是一种迭代方法 E-step:...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,026
精华内容 410
关键字:

gmm-hmm python