基于GMM-HMM的语音识别系统
目錄
- 基于孤立詞的GMM-HMM語音識別
- 建模
- 訓練
- Viterbi訓練
- 前向后向訓練(Baum-Welch訓練)
- 解碼
- 基于單音素的GMM-HMM語音識別系統
- 基于三音素的GMM-HMM語音識別系統
- 參數共享
- 三音素決策樹
- 決策樹構建
- 基于GMM-HMM語音識別系統流程
本文介紹GMM-HMM語音識別系統,雖然現在主流端到端系統,但是傳統識別系統的學習是很有必要的。閱讀本文前,需要了解語音特征提取、混合高斯模型GMM、隱馬爾科夫模型HMM的基礎知識(可以參考我的前幾篇文章)。筆者能力有限,如有錯誤請指正!
GMM-HMM語音識別系統的框架:
語音識別的幾個概念:
- 對齊:音頻和文本的對應關系
- 訓練:已知對齊,迭代計算模型參數
- 解碼:根據訓練得到的模型參數,從音頻推出文本
基于孤立詞的GMM-HMM語音識別
問題簡化,我們考慮(0-9)數字識別。整體思路:
- 訓練階段,對于每個詞用不同的音頻作為訓練樣本,構建一個生成模型P(X∣W)P(X|W)P(X∣W),W是詞,X是音頻特征(MFCC、Fbank參考這篇博客)
- 解碼階段:給定一段音頻特征,經過訓練得到的模型,看哪個詞生成這段音頻的概率最大,取最大的那個詞作為識別結果。
Xtest\mathbf{X}_{test}Xtest?測試特征,Pw(X)P_w(\mathbf{X})Pw?(X)是詞www的概率模型,vocabvocabvocab是詞表:
answer=arg?max?w∈vocab?Pw(Xtest?)answer =\underset{w \in \text { vocab }}{\arg \max } P_{w}\left(\boldsymbol{X}_{\text {test }}\right) answer=w∈?vocab?argmax?Pw?(Xtest??)
假設我們給每個詞建立了一個模型:Pone(X),Ptwo(X)...P_{one}(X),P_{two}(X)...Pone?(X),Ptwo?(X)...,計算在每個詞上的概率,選擇所有詞中概率最大的詞作為識別結果。這樣會有幾個問題:用什么方法進行建模:DNN,GMM?這些夠可以進行建模,但是語音任務的特點是序列性,不定長性,很難使用DNN、GMM直接進行建模。為了解決這些問題,我們可以利用HMM來進行序列建模。
語音是一個序列,Pw(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訓練
- Viterbi算法得到最優的狀態序列(對齊),也就是在t時刻處于狀態i上的概率(非0即1)
- GMM模型中在t時刻處于狀態i第k個GMM分量的概率
- 更新轉移參數、GMM參數(混合系數、均值、方差)
如何初始化GMM-HMM模型的參數?把語音進行均等切分,給每個狀態分配對應的特征,然后去估計初始化的參數。
前向后向訓練(Baum-Welch訓練)
- 通過前向后向算法得到在時刻t處于狀態i的概率
- 在時刻t處于狀態i且為GMM第k個分量的概率
- 更新轉移參數、GMM參數(混合系數、均值、方差)
Viterbi和Baum-Welch學習算法的詳細內容參考我之前的文章。
解碼
輸入:各個詞的GMM-HMM模型,未知的測試語音特征。
輸出:哪個詞。
主要關鍵點:對所有的詞,如果計算Pw(Xtest)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個音素,一共有多少個三音素?N3N^3N3
問題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=1N(2πσk2)1/2∏k=1Nexp?(?12(xk?μk)2σk2)\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/21?k=1∏N?exp(?21?σk2?(xk??μk?)2?)
似然
L(S)=?12∑i=1m[∑k=1Nlog?(2πσk2)+∑k=1N(xik?μk)2σk2]=?12[m∑k=1Nlog?(2πσk2)+m∑k=1Nσk2σk2]=?12[mN(1+log?(2π))+m∑k=1Nlog?(σk2)]\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)?=?21?i=1∑m?[k=1∑N?log(2πσk2?)+k=1∑N?σk2?(xik??μk?)2?]=?21?[mk=1∑N?log(2πσk2?)+mk=1∑N?σk2?σk2??]=?21?[mN(1+log(2π))+mk=1∑N?log(σk2?)]?
假設通過某個問題將該節點的三音素對應的特征分成兩部分(l 和 r),則這兩部分的似然和為:
L(Sl)+L(Sr)=?12mN(1+log?(2π))?12[ml∑k=1Nlog?(σlk2)+mr∑k=1Nlog?(σrk2)]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?)=?21?mN(1+log(2π))?21?[ml?k=1∑N?log(σlk2?)+mr?k=1∑N?log(σrk2?)]
分裂前后的似然變化(增益)為:
L(Sl)+L(Sr)?L(S)L\left(S_{l}\right)+L\left(S_{r}\right)-L(S) L(Sl?)+L(Sr?)?L(S)
似然增益越大,說明分裂后兩部分數據之間的差異越大,則應該使用兩個單獨的GMM分別建模,則選擇似然增益最大的問題進行劃分(最優問題)。根節點一份為2后,遞歸執行該算法直至達到一定終止條件,通常是分裂達到一定數量的葉子節點或者似然增益已經低于一定閾值。
總結
基于GMM-HMM語音識別系統流程
問題:為什么先做單音素訓練?
通過單音素模型上Viterbi算法得到與輸入對應的最佳狀態序列(對齊)。
參考:
https://blog.csdn.net/Magical_Bubble/article/details/90408095
https://zhuanlan.zhihu.com/p/63753017
總結
以上是生活随笔為你收集整理的基于GMM-HMM的语音识别系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【观察】“Cloud Ready”计划
- 下一篇: 浅谈两轮平衡车的控制原理