基於DNN-HMMs的語音識別原理

在上一篇博客基於GMMs-HMMs的語音識別原理中,介紹了第一代較爲成熟的GMMs-HMMs語音識別模型。但隨着神經網絡技術的發展,後面又出現了基於DNN-HMMs的語音識別模型,一句話概括就是用DNN代替之前的GMMs,有更好的建模能力。這篇博客將詳細介紹它的原理。

PS:假設讀者已經有了GMMs-HMMs模型的基礎(沒有的話,請移步筆者的上一篇博客),這裏只詳細介紹兩個模型之間不同的部分,以及其對比。並且,博客中對於DNN的部分只涉及到模型的介紹,至於其訓練要用到的梯度下降、反向傳播等算法,這裏將不會涉及細節,畢竟處在深度學習時代,這些東西早應爛熟於心。

一. DNN-HMMs原理

1.1 整體思路

重溫一下語音識別模型希望最大化的概率:P(SX)=P(XS)P(S)P(S|X) = P(X|S)P(S)XX 是輸入的語音特徵,SS 是識別出的句子,P(S)P(S) 是語言模型,P(XS)P(X|S) 則是GMMs-HMMs和DNN-HMMs要進行建模的部分。

之前GMMs-HMMs對於 P(XS)P(X|S) 的建模可以展開成類似爲:

P(XS)=P(x1s1)P(s1s1)P(x2s1)P(s2s1)P(x3s2)P(s3s2)P(x4s3)....P(X|S) = P(x1|s1) P(s1|s1) P(x2|s1) P(s2|s1) P(x3|s2) P(s3|s2) P(x4|s3)....

其中的 ss 爲HMM狀態,xx 爲輸入的幀,P(sjsi)P(s_j|s_i)是HMM的轉移概率,P(xs)P(x|s)則是GMM要建模的輸出概率。

區別來了! 在DNN-HMMs模型中,P(xs)P(x|s)是用DNN來建模。

DNN模型在這裏並不是去直接構建P(xs)P(x|s)這樣一個生成模型,而是將其轉化爲:

P(xs)=P(sx)P(s)P(x)P(sx)P(s)P(x|s) = \frac{P(s|x)}{P(s)} P(x) \approx \frac{P(s|x)}{P(s)}

這裏的P(x)P(x)xx 固定時,對最終的建模沒有影響,因此可以將其捨去;P(s)P(s)爲狀態 ss 的先驗概率,可以通過統計得出。

這樣就將DNN的建模,從生成模型P(xs)P(x|s)轉化爲判別模型P(sx)P(s|x)

對判別模型P(sx)P(s|x)的建模,白話解釋就是,輸入的某個幀 xx 屬於狀態 ss 的概率。如果將輸入幀看成一幅圖片,狀態看成類別,那可不就是分類模型?再加上用DNN建模,那就是一個典型的基於深度學習的分類模型,建模每個輸入幀屬於各個狀態的概率。

這裏有一個問題就是,DNN的訓練需要 labellabel,即要提前標註好每個輸入幀是屬於哪個狀態的。這個 labellabel 要怎麼獲取?比較常用的辦法是先用 (X,S)(X, S) 訓練一個GMMs-HMMs的語音識別模型 P(XS)P(X|S),然後進行維特比譯碼,得到能使當前句子生成概率最大的狀態序列argmaxstate sequenceP(XS)argmax_{state\ sequence} P(X|S) 作爲當前 XX 的逐幀狀態標註。

舉個例子,比如訓練好的GMMs-HMMs模型一共有 NN 個HMM狀態,那麼對於輸入的每一幀,其狀態labellabel就是對應 NN 個狀態中的一個,DNN對於每幀的輸出也就希望是 NN 個(NN 分類)。

總結一下,一句話概括基於DNN-HMMs的語音識別模型的整體思路爲:

用DNN學習出分類模型P(sx)P(s|x),而後通過P(sx)P(s)\frac{P(s|x)}{P(s)}轉爲HMMs需要的輸出概率分佈(替換掉GMMs),結合HMMs構建出完整的語音識別模型。

1.2 訓練和識別流程

這裏先給出DNN-HMMs模型的整體訓練和識別流程,結合前面的整體思路,便於讀者從宏觀上把握整個模型的精髓。

PS:筆者一開始學習的時候,看到的教程基本上都是上來就講各種DNN模型,看完了過後也不知道到底輸入是啥,輸出是啥,用來幹什麼的?這裏就以“結果導向”,先把整個流程呈現出來,然後再詳細介紹裏面的細節。

DNN-HMMs模型的整體訓練和識別流程可以概括爲:

  1. 用所有的訓練數據(X,S)(X, S),訓練GMMs-HMMs模型,並根據維特比譯碼算法爲每個 XX 標註其對應的最優狀態序列state sequence=argmaxstate sequenceP(XS)state\ sequence = argmax_{state\ sequence} P(X|S),每一幀對應一個狀態標註,設爲(x,state)(x, state)
  2. 用上一步中標註好的(x,state)(x, state),訓練DNN模型,輸入爲“當前幀”(可以包含其左右的上下文),輸出爲HMM中 NN 個狀態的分數,並用交叉熵損失進行優化,這裏還有一些tricks可以用,比如SDT、SAT等。
  3. 根據上一步訓練出的DNN,重新估計HMM的轉移概率參數,而後再重新進行狀態標註,再訓練DNN,…,如此往復,直到收斂
  4. 訓練好DNN和HMMs之後,識別流程就與GMMs-HMMs一樣了。

二. DNN模型詳細介紹

前面已經從宏觀上把握了DNN-HMMs模型是怎麼運作的,那麼這裏就着重講一些主流的DNN模型,包括FFDNN、CDDNN、TDNN、RNN等,以及一些訓練中可以使用的trick等。

2.1 常用的DNN模型

再嘮叨一遍DNN模型的輸入和輸出是啥,防止前面說的不清楚。DNN模型的輸入是音頻幀特徵 XRTDX \in \R^{T * D},其中 TT 是序列(幀)長度,DD 是輸入特徵維度;輸出是每一幀在HMM的 NN 個狀態上的分數 YRTNY \in \R^{T * N};標籤是每一幀對應的狀態 labelRTlabel \in \R^{T}。可以看成是一個序列標註的任務。

2.1.1 FFDNN

FFDNN(Feed-Forward DNN)是一個最簡單的前饋DNN模型,它的結構圖長下面這個樣子:

這是對於某一“幀”(含上下文)建模的例子,輸入是除了當前幀 tt 之外,還包括 t4t+4t-4 \to t+4幀的信息,將它們concat在一起作爲當前幀的表示(這也是DNN爲啥比GMM好的原因之一,可以同時考慮輸入的上下文信息!),送入DNN網絡,中間經過一系列的全連接層,頂層的輸出爲當前幀所屬的183個HMM狀態的分數。

對於每一個含有上下文信息的幀,都是使用同一個DNN來建模。那實際上整合一下,可以發現,整個FFDNN實際上相當於在第一層是一個kernel=9, stride=1的1D卷積,後面是一系列的全連接層,輸出層的維度爲183維,需要取Softmax,而後與標註的one-hot向量進行交叉熵計算。

2.1.2 CDDNN

CDDNN(Context-Dependent DNN)可以說是對FFDNN的一個延伸,它在輸出層,映射到的是Context-Dependent的音素狀態,比如用三音素進行HMM建模的各狀態,示意圖如下:

它與FFDNN的網絡結構是一樣的,只是在最頂層的維度變爲了上下文音素(比如三音素)的HMM狀態。

2.1.3 TDNN

TDNN(Time-Delay NN)其實是卷積網絡CNN的前身(但很有意思的是,CNN大火了這麼久,筆者在接觸語音的時候,才聽說了TDNN的存在,真是造化弄人~),它的模型結構爲:

就是CNN的操作,感受野會隨着層數的加深而變大。但如果是這種密集卷積的話,其弊端就是參數多,而且計算也慢!所以可以用降採樣或者空洞卷積來進行改進,比如下面的這個降採樣的TDNN:

它與前面未進行降採樣的TDNN最大的不同,在於中間計算的時候沒有同時對連續的一段進行計算,而是隻挑了頭尾兩個狀態進行計算。比如密集卷積的標識爲[2,2][-2, 2],則代表對 t2t+2t-2 \to t+2 的5個幀進行卷積,而降採樣的卷積標識爲{2,2}\{-2, 2\},表示僅對 t2t-2t+2t+2 這2個幀進行卷積。可以發現參數量和計算量都下來了。

2.1.4 RNN

這類模型就不用多說了吧。。LSTM、GRU之類的,簡直如雷貫耳。不懂LSTM的讀者可以移步http://colah.github.io/posts/2015-08-Understanding-LSTMs。總之是一種很好的對序列建模的方式,還可以用雙向的。爲了保持完整性,放一張RNN的整體示意圖吧:

2.2 訓練的Tricks

在對於DNN的訓練過程中,有一些tricks很好用。比如預訓練初始化、SDT(Sequence Discriminative Training,序列判別性訓練)、SAT(Speaker Adaption Training,說話人適應性訓練)等。下面簡單介紹一下:

2.2.1 預訓練初始化

這個方法感覺比較老了,至少筆者對於網絡的初始化從來沒用過這個方式。它是用一層一層訓練DBN(Deep Belief Network,深度信念網絡)的方式(一種生成模型),來得到一個較爲合理的參數初始化。具體的細節,筆者也沒有過於細究,還請見諒,若有推薦的相關教程相關,歡迎回復~

2.2.2 SDT

這個其實不僅僅可以用於DNN的訓練中,也同樣能用到GMMs-HMMs模型的訓練中。

回顧一下,之前在訓練模型的時候,不管是GMMs-HMMs,還是DNN-HMMs,都是希望能最大化似然概率:(MLE,最大似然估計)

FMLE=u=1UlogPλ(XuWu)F_{MLE} = \sum_{u=1}^U log P_\lambda (X_u | W_u)

其實最原始的一種方式是希望能最大化條件似然概率:(MMIE,最大互信息估計)

FMMIE=u=1UlogPλ(WuXu)=u=1UlogPλ(XuWu)P(Wu)wPλ(Xuw)P(w)F_{MMIE} = \sum_{u=1}^U log P_\lambda (W_u | X_u) = \sum_{u=1}^U log \frac{P_\lambda (X_u | W_u) P(W_u)}{\sum_{w'} P_\lambda (X_u | w') P(w')}

其中分子部分是當前句子生成當前音頻的概率,分母部分是所有可能的句子生成當前音頻的概率,那麼最大化 FMMIEF_{MMIE} 就是希望能最大化分子,最小化分母,即希望不僅能使真正的groudtruth的句子,生成當前音頻的概率更大,也同時希望使那些非groudtruth的句子生成當前音頻的概率更小。這就叫判別性訓練,分類就是一種判別性訓練,它希望真正的類別概率更大,其他類別概率更小。

實際上對於分母的估計非常困難,因爲可能的句子空間實在是太龐大了,這裏實際上就要用到近似,用訓練好的模型先生成lattice(詞圖,包含所有最可能被當前模型識別出來的句子們),然後在這個有限集合上面計算,比如下面這種:

PS:有一種方式不需要先生成詞圖,叫LF-MMI(Lattice-Free MMI),它是對這種方式的改進,計算更簡單。筆者沒細究細節,感興趣的讀者可以去搜論文"Purely sequence-trained models for ASR based on lattice-free MMI",或移至文末的傳送門~

還有一種更爲直接的序列訓練方式,是希望能直接對最關心的評估指標進行優化,比如PER(Phone Error Rate),這時希望優化的是:(MPE,最小音素錯誤)

FMPE=u=1UlogWPλ(Xu,W)P(W)A(W,Wu)WPλ(XuW)P(W)F_{MPE} = \sum_{u=1}^U log \frac{\sum_W P_\lambda (X_u, W) P(W) A(W, W_u)}{\sum_{W'} P_\lambda (X_u | W') P(W')}

其中的 A(W,Wu)A(W, W_u) 表示任意一個句子 WW 與真實句子 WuW_u 之間音素的正確率(1 - PER,用編輯距離計算),這個公式是用A(W,Wu)A(W, W_u)對之前的FMMIEF_{MMIE}做一個加權平均,直接在PER上進行優化,希望能找到具有最小PER的句子。

後面介紹的兩種FMMIEF_{MMIE}FMPEF_{MPE}都是SDT的一種方式,當然也可以根據別的需求設計類似的方式,這些訓練都要在交叉熵訓練之後進行訓練,感覺像是finetune。

2.2.3 SAT

SAT是說話人適應性訓練,同樣不僅侷限於DNN模型的訓練中。

在識別過程中,不同的人說話口音、風格以及人類本身的發聲道的不同,都會導致不同人識別的難度不一樣。那麼這裏就需要進行一個說話人自適應性的訓練。

可以有如下幾個層面的適應性訓練:

  1. 模型相關,比如MAP(最大後驗適應,針對GMM模型)、MLLR(最大似然線性迴歸,針對GMM模型)和LHUC(學習隱層狀態貢獻,針對NN)等
  2. 說話人歸一化,比如cMLLR(限制MLLR)等
  3. 說話人建模,比如i-vectors等

下面簡單介紹其中的一些(更多細節請移至文末的傳送門):

  1. MAP

這是一個對已經訓練好的GMM參數,根據不同的說話人,進行重新估計的方式:

原先的參數估計爲:

μmj=nγjm(n)xnnγjm(n)\mu_{mj} = \frac{\sum_n \gamma_{jm}(n) x_n}{\sum_n \gamma_{jm}(n)}

現在的參數估計爲:

μ^=τμ0+nγ(n)xnτ+nγ(n)\hat \mu = \frac{\tau \mu_0 + \sum_n \gamma (n) x_n}{\tau + \sum_n \gamma(n)}

其中的τ\tau是調節說話人數據估計的權重

  1. MLLR

上面的MAP方式有一個弊端就是,如果某個說話人的數據比較少,則進行參數重估的GMM就不完全,只能對少數的GMM進行參數重估。所以可以用線性變化的方式,共享所有GMM之間的線性權重:

μ^=Aμ+b\hat \mu = A \mu + b

然後用說話人數據的最大似然概率進行估計即可。當然,對於方差也可以進行變換和重新估計。

  1. cMLLR

這是對MLLR的一種改進,用相同的線性參數同時對GMM中的均值和方差進行變換,所以稱爲限制MLLR:

μ^=Aμb\hat \mu = A'\mu - b'

Σ^=AΣAT\hat \Sigma = A'\Sigma {A'}^T

其實這個在對參數重新估計的過程中,就相當於是先對說話人數據進行如下變換,然後直接估計均值和方差:

x=Ax+b,A=A1,b=Abx = Ax + b, A' = A^{-1}, b' = Ab

  1. LHUC

針對神經網絡的,就有很多種方式了,比如在輸入層加一個變換層,用於將說話人相關的網絡變換成說話人無關的網絡,如下圖:

在訓練階段,網絡可以一起訓練,在適應階段,就把上面的部分固定,然後根據說話人的數據finetune下面的變換網絡。

LHUC(Learning Hidden Unit Contribution)是另外一種,如下圖:

這裏就是在每個hidden unit上都乘上一個可學習的說話人相關的幅值。

  1. i-vectors

是一種固定維度的可以代表說話人的向量(通常是40~100維),通過訓練得到,方式爲:

  • 先訓練GMM模型,得到均值μ0\mu_0
  • 然後對均值進行適應性變換,μs=μ0+Mλs\mu_s = \mu_0 + M \lambda_s
  • 用EM算法,估計λs\lambda_sMM
  • λs\lambda_s就是學習出的i-vectors向量。

傳送門

  1. Neural network acoustic models 1: Introduction
  2. Neural network acoustic models 2: Hybrid HMM/DNN systems
  3. Neural network acoustic models 3: Context-dependent DNNs and TDNNs
  4. Neural Networks for Acoustic Modelling 4: LSTM acoustic models; Sequence discriminative training
  5. Lattice-free MMI
  6. Speaker Adaptation

都是愛丁堡大學的講義,講得很詳細~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章