剛入門ASR的時候一直能聽到HMM模型的相關字眼,這裏就補一下用GMMs-HMMs進行語音識別的原理,雖然這個方法很古老,而且已經近乎被神經網絡所取代,但它背後的思想仍然值得我們去了解和學習~
筆者看了一些教程,包括課程講義、博客還有一些工具書,總算大致理清了思路,相信至少在文章邏輯上比一些沒有相關背景設定、無厘頭、不知所云的教程要好,原理上至少也是能用到的都有介紹。而有些地方太深入的原理筆者也沒有去細究,感興趣的讀者根據筆者的邏輯自己去深入探索即可。
整體的行文思路按照“結果導向”,需要什麼數學知識和原理再去介紹什麼,而不是上來就用GMM和HMM進行轟炸,導致前後脫節。在數學原理上,也是儘量做到通俗易懂,加入自己的理解,而不是甩一堆高深莫測的公式。
文章目錄
一. 最簡單的場景:孤立詞識別
1.1 整體思路
孤立詞識別是語音識別中最簡單的場景,即一個音頻文件裏面只包含一個詞的語音。訓練和識別的整體思路爲:
(1)訓練階段:對於每個詞,用不同人錄製的這個詞的音頻特徵作爲訓練樣本,構建一個生成模型,表示詞,表示音頻文件提取出的特徵(如FBank、MFCC等,參見這篇博客)。
(2)識別階段:給定一段音頻特徵,經過上面學習到的每個詞的模型,看哪個詞生成這段音頻特徵的概率最大,取最大的那個詞作爲識別詞。
形象化的圖如下:
這裏的重點就是這個生成模型的建立。因爲對於每個孤立詞都是分別採用一個生成模型來獨立建模的,所以後面介紹的原理都是以一個孤立詞爲例講解。
1.2 模型結構
對於這種時間序列的建模,自然就是採用HMM模型。其結構圖如下:
不大張旗鼓地講那麼多關於HMM沒用的東西,就看這個圖來講解。它的構建思路就是認爲音頻特徵是由一些隱藏狀態生成的,這些狀態內部會有轉移,並且滿足馬爾可夫性,狀態個數是超參數,需要自己設置(一般3~5個)。
對於除了開始()和結束()這兩個狀態之外的狀態,都有兩種轉移選擇,要麼就轉向自己,要麼就轉向下一個狀態。因爲音頻特徵的序列長度往往要比狀態個數多,所以這裏要有轉向自己的,因此每個狀態可能對應多個音頻特徵的“幀”。
以這個圖裏面的3個狀態和對齊爲例,生成模型可展開爲:。
這裏主要有兩部分概率需要學習:
(1):,狀態轉移概率
(2):,輸出生成概率
其中一般採用GMM進行建模,這也就是爲什麼叫GMM-HMM。直接給出GMM的公式:
即認爲輸出生成概率由高斯混合模型生成,先根據概率選擇一個高斯模型,然後根據這個模型的概率分佈生成 。
總結一下,要學習的參數有:
- :HMM的狀態轉移概率矩陣
- :各狀態對應的GMM中的混合權重(如果是單高斯建模,則不用學習)
- :各狀態對應的GMM中各高斯分量的均值向量
- :各狀態對應的GMM中各高斯分量的協方差矩陣
建立好這樣的模型之後,後面就是如何根據樣本進行訓練了。
1.3 訓練過程
這裏的訓練,確切來講應該叫參數估計,用一定的算法來估計參數,使其能夠擬合數據分佈(即最大化數據的似然概率)。下面循序漸進地來講這種參數估計算法:
1.3.1 單樣本、單高斯
這是一種最簡單的情況,假設一個詞的訓練樣本只有一個音頻文件,並且對於輸出概率採用單高斯建模,即 ,。此時需要估計的參數爲:
- :HMM的狀態轉移概率矩陣
- :各狀態對應的單高斯模型的均值向量
- :各狀態對應的單高斯模型的協方差矩陣
這裏進行參數估計的一大難點就是:各個狀態對應哪些音頻幀是不知道的,不像1.2裏面給出的那個圖那樣具有對齊信息。所以輸出概率根本不知道具體去擬合哪些音頻幀數據。
爲了解決這個問題,引入一種軟對齊策略,即給出各個音頻幀屬於各個狀態的概率(各個時刻處於各個狀態的概率),此時對於各個單高斯模型的參數估計就可以寫爲:
這個地方不好理解的話,再說得深入一些:
如果最理想情況下給出了各個狀態對應的音頻幀,像1.2節的圖那樣。則每個狀態對應的高斯模型需要擬合的數據就確定了,此時根據最大似然概率,均值和方差分別應該估計爲:
但是這裏沒有這種“硬對齊”信息,所以要用“軟對齊”的概率來代替。
同樣的,對於轉移概率,也引入軟對齊轉移概率,表示在 時刻的狀態在,而在 時刻的狀態爲的概率。此時轉移概率可以估計爲:
即狀態轉到狀態(在各個時刻下求和)的概率除以狀態轉到其他所有狀態(在各個時刻下求和)的概率。
綜上,在進行參數估計前,需要先拿到和這兩個概率。
那麼,這兩個軟對齊概率要怎麼計算呢?此時就需要用到HMM中經典的前向-後向概率計算公式。引入兩個概率:
(1):前向概率,展開爲,即已經輸出,並且在時刻 處在狀態的概率。
(2):後向概率,展開爲,在時刻 處在狀態時,後續輸出爲的概率。
在給出了這兩個概率時,就可以計算和,如下:
這裏的實際上就是。
綜上,在計算和這兩個概率之前,需要先計算和。
那麼如何計算前向和後向概率呢?先放一張圖:
這是一個典型的所有可能路徑的示意圖,即計算從起點的紫色圓圈到其中某個青色圓圈的所有路徑的概率和,即計算從某個青色圓圈到終點的紫色圓圈的所有路徑的概率和。計算方式採用動態規劃算法,迭代進行:
具體地,對於,計算方法爲:
(1)初始化:,
(2)迭代:
(3)終止:
下圖是迭代計算過程中拆分出的某一步的示意圖,展示了動態規劃的計算方法。
同樣地,對於,計算方法爲:
(1)初始化:
(2)迭代:
(3)終止:
下圖是迭代過程中拆分出的某一步的示意圖:
到這裏,所有在參數估計中需要用到的概率都已經計算完畢了,下面展示整個流程。
整個參數估計的流程,其實還是需要迭代的,這裏採用EM算法(一種對含有隱變量模型進行參數估計的迭代算法,在HMM的場景裏,也叫前向-後向算法或Baum-Welch算法):
- 初始化:
筆者看到的有:對於GMM,一種做法是用所有數據進行估計,另一種是用K-Means先聚類一波;對於HMM的轉移概率,是用的平均。
- 對於每一次迭代:
(1)E步:用上一步估計出的參數,迭代計算前向概率和後向概率,進而計算軟對齊概率和。
(2)M步:基於E步計算的4組概率,對、和進行估計。
其中每一步的計算公式,前面都已經詳細說明了。
1.3.2 擴展到高斯混合模型
一般在對於輸出概率分佈的建模,都會採用GMM方法。理論上,足夠的單高斯模型的混合可以擬合任意的分佈。1.3.1的單高斯建模只是一種特例,目的還是爲了方便擴展到GMM的場景。
這裏需要估計的參數就要加上GMM的混合權重,即:
- :HMM的狀態轉移概率矩陣
- :各狀態對應的GMM中的混合權重
- :各狀態對應的GMM中各高斯分量的均值向量
- :各狀態對應的GMM中各高斯分量的協方差矩陣
對於GMM的參數估計中,與之前HMM是同樣的道理。因爲在音頻幀對應到某個狀態後,還是不知道其是GMM中的哪個分量生成的。所以還是需要一種軟對齊概率,具體表現在上,此時需要改爲,表示在時刻t,屬於狀態以及第個高斯分量的概率。
筆者猜測的計算公式爲:(因爲沒找到相關的資料,如果有錯誤,還請指出~)
相應的,對於和的參數估計就要改爲:
GMM的混合參數估計如下:
即處於狀態 和分量 的概率,除以處於狀態 和其他所有分量的概率。
而前向概率、後向概率 和 的計算公式不變,轉移概率的估計公式也不變。
那麼EM的流程就變爲:
(1)E步:用上一步估計出的參數,迭代計算前向概率和後向概率,進而計算軟對齊概率和。
(2)M步:基於E步計算的4組概率,對、、和 進行估計。
1.3.3 擴展到多個訓練樣本
前面1.3.1和1.3.2討論的都是隻有一個訓練樣本的情況,實際上對於每個詞,都會有很多個音頻文件與之對應,從而提升模型建模的魯棒性。
假設某個詞一共有 個音頻文件,則前面的就要改爲,表示第 個訓練樣本中的第 幀。此時EM的流程變爲:
(1)E步:對每個樣本都計算出:、、和。
(2)M步:對於參數的估計需要在全部的訓練樣本上進行,具體爲
在訓練完成後,就是如何利用訓練好的模型對新音頻進行識別了。
1.4 識別過程
識別的過程,就是給定一段音頻,對於每個詞的模型,都計算出其生成的概率,然後取最大的那個作爲識別出的孤立詞。
這裏的實際在前面已經提到了,就是,但一般在識別過程中,不會對所有路徑的概率計算總和,而是會選擇最大的那一條概率作爲最終的概率。這其實就是HMM中經典的維特比算法。
定義概率,表示在時刻 到達狀態的所有路徑中概率的最大值,對應到1.3中第一張路徑圖,即從起始的紫色圓圈到某個青色圓圈的所有路徑概率中,最大的那一個。同時定義回溯指針,即時刻 到達狀態的所有路徑中概率最大的那一條路徑對應的前一個狀態,便於之後進行狀態回溯。
與前向概率類似,對於和的計算也是採用動態規劃進行迭代計算,具體的計算方式爲:
(1)初始化:
(2)迭代:
(3)終止:
下面兩個圖是拆分出的中間某一步的迭代計算過程:
最後的識別詞爲:。
至此,對於孤立詞識別的全部內容就已經介紹完畢!
二. 擴展到通用場景:連續語音識別
2.1 整體思路
連續語言識別是比較通用的場景,即一個音頻文件裏面包含一個連續的句子,而不是一個詞,其難點在於不知道每個詞對應音頻文件的起止位置。如果有這種標註好的切分,那麼仍然可以沿用前面的孤立詞識別方式進行訓練和識別,但這樣着實費時費力,而且會有人工誤差。那麼,能不能在沒有切分的情況下,對一整段音頻,識別一整個句子?當然可以,下面將詳細介紹。
與孤立詞識別類似,這裏是希望構建一個判別模型,其中是音頻特徵,是其對應的句子。訓練是希望能最大化,識別是希望能找到。對於的建模通常會通過貝葉斯公式轉爲來處理,其中即爲生成模型,爲語言模型(這裏不涉及到語言模型的細節)。
其訓練和識別的整體思路爲:
(1)訓練階段:對於所有的句子,構建生成模型,最大化每個句子的似然概率。
(2)識別階段:給定一段音頻特徵,用構建好的生成模型和語言模型,得到識別出的句子。
2.2 模型結構
對於生成模型的構建,可以使用“嵌入訓練(embedded training)”的方式。
理想情況下,在詞表比較小的時候,可以對每個詞進行一個HMM建模(與之前孤立詞識別一樣),而後將整個句子中所有詞的HMM狀態都串起來,作爲一個超長的HMM,其訓練方式與1.3節的一樣。
但在真實場景中,詞表往往很龐大,此時如果對所有的詞建模,HMM模型將非常多。所以,一般都是將句子轉成音素串(可以將音素理解爲音標,一個詞會對應一條音素序列)進行處理,音素表往往會小很多,這樣對每個音素建模較爲簡便。
總結一下,在連續語音場景中,是爲每個音素建立一個HMM模型,將句子轉爲音素串之後,將句子中所有音素對應的HMM狀態都串在一起(中間的開始和結束狀態會去掉),成爲一個超長的HMM模型,如下圖:
這裏的句子“six quid”轉爲音素串爲“/s/ /ih/ /k/ /s/ … /d/”,每個“beg mid end”是對一個音素的3狀態HMM建模。
2.3 訓練過程
在串成2.2節中超長的HMM之後,訓練的方式就與1.3節中的類似了,只不過1.3節中是每次對一個HMM模型進行訓練,這裏是一次對很多個HMM模型進行並行訓練。
其訓練流程爲:
- 獲取下一個句子;
- 轉成音素串後,按照2.2節構建成超長的HMM模型,當成一個HMM模型來處理;
- E步:迭代計算前向概率和後向概率,進而計算軟對齊概率和;
- M步:基於E步計算的4組概率,對、、和 進行估計;
- 重複整個流程,直到所有的句子遍歷完成。
在訓練完成之後,每個音素的HMM模型也就訓練好了。
2.4 識別過程
識別過程與孤立詞識別的差別就比較大了,因爲要考慮“音素->詞->句子”的層級傳遞。這裏介紹一個比較常用的識別算法——“token passing算法”,屬於剪枝的維特比譯碼算法的一種。
PS:其實這個算法本身不難理解,但因爲相關資料比較少,而且說的都比較模糊。筆者也是看了很久才明白原理,希望能用通俗的方式把它呈現出來,細節上如果有不周到的地方,還望指出~
2.4.1 較簡單的情況:假設是對詞進行HMM建模
雖然2.2節和2.3節介紹的內容都是對音素建模,但從音素到句子要經過“音素->詞->句子”的兩層識別傳遞。這裏爲了方便更好地講明白原理,先假設之前構建和訓練的都是針對每個詞的HMM模型,這樣只需要經過“詞->句子”的一層識別傳遞,更容易理解原理。後面再進一步擴展到對音素建模的情況。
首先需要聲明的是,因爲只針對訓練樣本中有的詞構建了HMM模型,所以在識別時,只能識別這些已有的詞。假設詞表中只有“one”、“two”和“three”這三個詞,那麼識別的示意圖可以畫成下面這樣:
其實還是與之前1.4節孤立詞識別同樣的方法,只不過這裏是並行對所有詞進行識別。同時,在孤立詞識別過程中,如果到達了結束狀態,則識別就結束了;但在這裏,如果到達了結束狀態,還是要繼續識別下一個詞,所以在圖裏是一個循環。
在每個HMM內部,還是採用維特比識別方法,用動態規劃,在每個時刻對於每個狀態選擇一條最大概率的路徑。因爲是並行的,那麼在某個時刻,可能同時會有多個詞到達結束狀態,分別對應着一段已識別出的句子(路徑),然後又都要同時再進行下一個詞的識別。這裏爲了避免多餘的計算,採用與維特比識別一樣的思路,只需要取一個最大概率的句子,而扔掉其他的。那麼,在這個過程中,就需要記錄概率和路徑,這個就叫“token”。看下面這個圖:
每個“token”裏面存儲score和WLR,前者是這條路徑的概率,後者是“word link record”,記錄當前的路徑(包括score:分數;path id:它是從之前哪個WLR過來的;model id:當前識別出的詞是哪個;time:時間等)。這樣在某個時刻,每條到達結束狀態的路徑,都會有一個對應的token,從這些“tokens”裏面選一個具有最大score的token保留,扔掉其他所有的token後,繼續下一步的識別。
寫成僞代碼就是:
先定義兩個特殊的token:
(1)“start token”(P=1,score=logP=0,WLR=null),
(2)“null token”(P=0,score=logP=-inf,WLR=null)
假設時間長度爲T,狀態數目爲N+2,其中0和N+1分別表示開始狀態和結束狀態
初始化:在開始狀態中放入“start token”,在其他狀態中放入“null token”
迭代:for time t = 1, ..., T
for state i <= N
將狀態i的token複製到與其連接的所有不是結束狀態的狀態j中
更新token的score爲:score += log a_ij + log b_j(y_t)
end
for state i in (與結束狀態連接的狀態集合)
將狀態i的原始token複製到結束狀態
更新token的score爲:score += log a_iE
創建一個新的WLR,其path id指向token的WLR,model id爲這個token對應的識別詞,time爲t,score爲當前token的分數
更新token的WLR爲這個新建的WLR
end
扔掉所有的原始token
for state i <= N+1
保留狀態i中所有tokens中最大score的那個token,扔掉其他所有的tokens
end
將結束狀態的token複製到開始狀態中
返回結束狀態的token
識別結果:根據token的model id以及path id一層一層向前回溯,得到整個句子
上面的過程能夠得到的句子,識別的目標是。語言模型可以通過兩種方式加進去:
- rescore:即重打分排序,這就需要前面保留token的時候,要保留NBest(參考beam search的思想),然後對NBest識別出來的句子,通過LM進行rescore即可。
- fusion:直接融合進去,每次識別出一個詞之後,可以用語言模型,根據它之前的句子和這個詞,得到當前這個詞的分數,一起加到token的計算裏面,具體加入的位置可以是
更新token的score爲:score += log a_iE + (LM分數 log P(w_t|w_1, ..., w_{t-1}))
,找了一個比較形象的圖:
2.4.2 擴展到對音素建模的情況
有了上面的對詞建模的識別過程之後,既可以很容易地擴展到對音素建模的情況,只是這裏要多加一層從“音素->詞”的傳遞,通過發音詞典即可完成,比如下圖:
可以將一個詞的所有音素的HMM狀態都串起來,作爲一整個HMM(改一下矩陣的連接方式應該就可以)。而後進行與2.4.1一樣的識別過程即可。
三. 延伸:上下文建模
3.1 三音素建模
前面討論的都是對單音素進行HMM建模的方式,但實際上一個音素的發聲是依賴於其上下文(即鄰居音素)的,只用一個模型對其進行建模,信息量難免會有丟失。因此,應當在建模時考慮到這種上下文信息。
一種較普遍的做法是,對三音素(tripone)進行建模。對於音素 ,假設它左邊的音素是 ,右邊的音素是 ,那麼音素 的三音素形式就可以表示爲 。比如don't ask
就可以表示爲sil sil-d+oh d-oh+n oh-n+t n-t+ah t-ah+s ah-s+k s-k+sil sil
這樣的三音素串。
這樣在建模的時候就是對類似d-oh+n
這樣的三音素(三個音素當成一個音素)進行建模。
3.2 優化:參數共享
只考慮單音素的情況下,音素表可能比較小,方便建模。但如果考慮三音素的情況,音素表可能就呈指數級增長了。
簡單計算一下,假設單音素表有40個音素,那麼可能的三音素就會有個,在實際情況下,可能有個是真實存在的。那麼,要對這個三音素進行三狀態的HMM建模,假設用個混合分量的GMM模型,那麼一共需要的高斯模型。假設用39維的音頻特徵,那麼每個高斯模型需要約個參數,總的參數量就高達。這是十分驚人的,需要有大量的數據來進行擬合,同時還要保證每個三音素都有足夠的數據,這點比較困難。
爲了對其進行優化,通常會採用共享參數的方式,減少建模的參數量,方便訓練。共享可以發生在不同的層面:
- 共享高斯模型:所有狀態都用同樣的高斯模型,只是混合權重不一樣(捆綁混合物)
- 共享狀態:允許不同的HMM模型使用一些相同的狀態(狀態聚類)
- 共享模型:相似的三音素使用同樣的HMM模型(三音素泛化)
所有的方法都是數據驅動的,下面進行一些簡單介紹:(筆者沒有過多細究這部分,只是大概瞭解了原理,對此感興趣的讀者可以前往傳送門查找細節)
3.2.1 共享狀態
這部分的重點,其實是對狀態進行聚類。找到相似的一堆狀態,然後讓不同的HMM模型之間共享這些狀態,比如下圖:
具體怎麼找這些相似的狀態?可以採用自頂向下的拆分,建立決策樹來聚類,看下面這個形象的圖:
頂層節點是所有中間音素爲/iy/
的三音素,然後通過問各種問題,比如左邊是鼻音嗎?右邊是濁音嗎?等等,將這些三音素進行劃分,最後在同一個葉子節點裏面的所有三音素的中間狀態就可以共享。
3.2.2 共享模型
這部分的重點,其實就是對三音素進行泛化,找到一堆相似的三音素,用同一個泛化的三音素來表示,有點兒像詞幹的感覺。看下面這個圖:
這裏就是將s-iy+l
和f-iy+l
泛化爲(s,f)-iy+l
,將t-iy+n
和t-iy+m
泛化爲t-iy+(n,m)
,模型個數縮減了一半。
具體怎麼找這些相似的三音素?可以採用自底向上的合併,比較具有不同三音素的異音素(allophone)模型,合併相似的那些。(PS:這句話筆者是翻譯過來的,,只能意會)
傳送門:
HTK Book:HTK工具包的說明文檔(需要先註冊才能看),第一章的教程對於整體脈絡的把握很清晰
HMM acoustic modelling: HMMs and GMMs:英國愛丁堡大學的ASR課程講義,主攻HMM和GMM模型和孤立詞識別,在數學原理上很詳細
HMM acoustic modelling: Context-dependent phone modelling:英國愛丁堡大學的ASR課程講義,考慮上下文的建模