【机器听觉】初探语音识别技术
感謝原文博主,轉自:https://blog.csdn.net/ArrowYL/article/details/79979470
??????語音識別根據實際需求的不同也會有所不同。目前主要追求大詞匯量、連續、非特定人。
?????? 語音識別主流開源框架:HTK、Kaldi、CMUSphinx。
因為目前只接觸了Sphinx,對于另外兩個框架沒有太深入研究。
??????? 1)Kaldi適用于在服務器搭建的語音識別系統,也可以適用于android,但沒有實驗過,根據官方提供方法:http://jcsilva.github.io/2017/03/18/compile-kaldi-android/
其使用模型很多:DNN-HMM、GMM-HMM等
??????? 2)PocketSphinx是應用于嵌入式而開發的(Sphinx用于聯網后臺識別系統,Sphinx現在版本是Sphinx4-5prealpha,在0.8版本時還有支持中文模型,現在已經沒有中文語音模型了)。PocketSphinx和Sphinx由于不同的解碼器使用了不同的聲學模型。
??????? 該文講解:將語音識別大概流程和涉及到的一些算法匯總,最后PocketSphinx安裝、編譯、訓練、結構以及涉及到的一些坑。
一、語音的特征
?????? 推薦http://blog.csdn.net/u013378306/article/details/65951935該博客文章,請一定細讀,講解語音產生、基本名詞和語音特征,比較詳盡。
二、識別流程及原理
???????對于語音識別系統而言,第一步要檢測是否有語音輸入,即,語音激活檢測(VAD)。在低功耗設計中,相比于語音識別的其它部分,VAD采用always on的工作機制。當VAD檢測到有語音輸入之后,VAD便會喚醒后續的識別系統。識別系統總體流程如圖2所示,主要包括特征提取、識別建模及模型訓練、解碼得到結果幾個步驟。
圖2.語音識別系統
1、VAD(語音激活檢測)
???????用于判斷什么時候有語音輸入,什么時候是靜音狀態。語音識別后續的操作都是在VAD截取出來的有效片段上進行,從而能夠減小語音識別系統噪聲誤識別率及系統功耗。在近場環境下,由于語音信號衰減有限,信噪比(SNR)比較高,只需要簡單的方式(比如過零率、信號能量)來做激活檢測。但是在遠場環境中,由于語音信號傳輸距離比較遠,衰減比較嚴重,因而導致麥克風采集數據的SNR很低,這種情況下,簡單的激活檢測方法效果很差。使用深度神經網絡(DNN)做激活檢測是基于深度學習的語音識別系統中常用的方法(在該方法下,語音激活檢測即為一個分類問題)。在MIT的智能語音識別芯片中使用了精簡版的DNN來做VAD,該方法在噪聲比較大的情況下也具有很好的性能。但是更復雜的遠場環境中,VAD仍然是未來研究的重點。
2、特征提取
???????梅爾頻率倒譜系數(MFCC)是最為常用的語音特征,梅爾頻率是基于人耳聽覺特征提取出來的。MFCC主要由預加重、分幀、加窗、快速傅里葉變換(FFT)、梅爾濾波器組、離散余弦變換幾部分組成,其中FFT與梅爾濾波器組是MFCC最重要的部分。但是近年研究表明,對于語音識別而言,梅爾濾波器組不一定是最優方案。受限的玻爾茲曼機(RBM)、卷積神經網絡(CNN)、CNN-LSTM-DNN(CLDNN)等深度神經網絡模型作為一個直接學習濾波器代替梅爾濾波器組被用于自動學習的語音特征提取中,并取得良好的效果。
???????目前已經證明,在特征提取方面,CLDNN比對數梅爾濾波器組有明顯的性能優勢。基于CLDNN的特征提取過程可以總結為:在時間軸上的卷積、pooling、pooled信號進入到CLDNN中三個步驟。
???????遠場語音識別領域,由于存在強噪聲、回響等問題,麥克風陣列波束成形仍然是主導方法。
???????另外,現階段,基于深度學習的波束成形方法在自動特征提取方面亦取得了眾多研究成果。
???????通俗形象點解釋特征提取過程:
?????? 在開始識別之前,有時需要把首尾端的靜音切除,降低對后續步驟造成的干擾。這個靜音切除的操作一般稱為 VAD,需要用到信號處理的一些技術。
要對聲音進行分析,需要對聲音分幀,也就是把聲音切開成一小段一小段,每小段稱為一幀。分幀操作一般不是簡單的切開,而是使用移動窗函數來實現,這里不詳述。幀與幀之間一般是有交疊的,就像下圖這樣:
圖中,每幀的長度為 25 毫秒,每兩幀之間有 25-10=15 毫秒的交疊。我們稱為以幀長 25 ms、幀移 10 ms 分幀。圖中,每幀的長度為 25 毫秒,每兩幀之間有 25-10=15 毫秒的交疊。我們稱為以幀長 25 ms、幀移 10 ms 分幀。
分幀后,語音就變成了很多小段。但波形在時域上幾乎沒有描述能力,因此必須將波形作變換。常見的一種變換方法是提取 MFCC 特征,根據人耳的生理特性,把每一幀波形變成一個多維向量,可以簡單地理解為這個向量包含了這幀語音的內容信息。這個過程叫做聲學特征提取。實際應用中,這一步有很多細節,聲學特征也不止有 MFCC 這一種,具體這里不講。
至此,聲音就成了一個 12 行(假設聲學特征是 12 維)、N 列的一個矩陣,稱之為觀察序列,這里 N 為總幀數。觀察序列如下圖所示,圖中,每一幀都用一個 12 維的向量表示,色塊的顏色深淺表示向量值的大小。(不過一般提取MFCC的39維特征值)
3、識別建模(解碼)
???????語音識別本質上是音頻序列到文字序列轉化的過程,即在給定語音輸入的情況下,找到概率最大的文字序列?;谪惾~斯原理,可以把語音識別問題分解為給定文字序列出現這條語音的條件概率以及出現該條文字序列的先驗概率,對條件概率建模所得模型即為聲學模型,對出現該條文字序列的先驗概率建模所得模型是語言模型。
??????通俗形象點解釋識別過程:
??????首先解釋兩個概念
1.音素:單詞的發音由音素構成。對英語,一種常用的音素集是卡內基梅隆大學的一套由 39 個音素構成的音素集,參見 The CMU Pronouncing DicTIonary。漢語一般直接用全部聲母和韻母作為音素集,另外漢語識別還分有調無調,不詳述。
2.狀態:這里理解成比音素更細致的語音單位就行啦。通常把一個音素劃分成 3 個狀態。
語音識別是怎么工作的呢?實際上一點都不神秘,無非是:
第一步,把幀識別成狀態(難點);
第二步,把狀態組合成音素;
第三步,把音素組合成單詞。
如下圖所示:
圖中,每個小豎條代表一幀,若干幀語音對應一個狀態,每三個狀態組合成一個音素,若干個音素組合成一個單詞。也就是說,只要知道每幀語音對應哪個狀態了,語音識別的結果也就出來了。圖中,每個小豎條代表一幀,若干幀語音對應一個狀態,每三個狀態組合成一個音素,若干個音素組合成一個單詞。也就是說,只要知道每幀語音對應哪個狀態了,語音識別的結果也就出來了。
那每幀音素對應哪個狀態呢?有個容易想到的辦法,看某幀對應哪個狀態的概率最大,那這幀就屬于哪個狀態。比如下面的示意圖,這幀對應 S3 狀態的概率最大,因此就讓這幀屬于 S3 狀態。
那這些用到的概率從哪里讀取呢?有個叫「聲學模型」的東西,里面存了一大堆參數,通過這些參數,就可以知道幀和狀態對應的概率。獲取這一大堆參數的方法叫做「訓練」,需要使用巨大數量的語音數據,訓練的方法比較繁瑣,這里不講。
但這樣做有一個問題:每一幀都會得到一個狀態號,最后整個語音就會得到一堆亂七八糟的狀態號,相鄰兩幀間的狀態號基本都不相同。假設語音有 1000 幀,每幀對應 1 個狀態,每 3 個狀態組合成一個音素,那么大概會組合成300個音素,但這段語音其實根本沒有這么多音素。如果真這么做,得到的狀態號可能根本無法組合成音素。實際上,相鄰幀的狀態應該大多數都是相同的才合理,因為每幀很短。
解決這個問題的常用方法就是使用隱馬爾可夫模型(Hidden Markov Model,HMM)。這東西聽起來好像很高深的樣子,實際上用起來很簡單:
第一步,構建一個狀態網絡。
第二步,從狀態網絡中尋找與聲音最匹配的路徑。
這樣就把結果限制在預先設定的網絡中,避免了剛才說到的問題,當然也帶來一個局限,比如你設定的網絡里只包含了「今天晴天」和「今天下雨」兩個句子的狀態路徑,那么不管說些什么,識別出的結果必然是這兩個句子中的一句。
那如果想識別任意文本呢?把這個網絡搭得足夠大,包含任意文本的路徑就可以了。但這個網絡越大,想要達到比較好的識別準確率就越難。所以要根據實際任務的需求,合理選擇網絡大小和結構。
搭建狀態網絡,是由單詞級網絡展開成音素網絡,再展開成狀態網絡。語音識別過程其實就是在狀態網絡中搜索一條最佳路徑,語音對應這條路徑的概率最大,這稱之為「解碼」。路徑搜索的算法是一種動態規劃剪枝的算法,稱之為 Viterbi 算法,用于尋找全局最優路徑。
這里所說的累積概率,由三部分構成,分別是:
觀察概率:每幀和每個狀態對應的概率
轉移概率:每個狀態轉移到自身或轉移到下個狀態的概率
語言概率:根據語言統計規律得到的概率
其中,前兩種概率從聲學模型中獲取,最后一種概率從語言模型中獲取。語言模型是使用大量的文本訓練出來的,可以利用某門語言本身的統計規律來幫助提升識別正確率。語言模型很重要,如果不使用語言模型,當狀態網絡較大時,識別出的結果基本是一團亂麻。
3.1 ?聲學模型
???????聲學模型是把語音轉化為聲學表示的輸出,即找到給定的語音源于某個聲學符號的概率。對于聲學符號,最直接的表達方式是詞組,但是在訓練數據量不充分的情況下,很難得到一個好的模型。詞組是由多個音素的連續發音構成,另外,音素不但有清晰的定義而且數量有限。因而,在語音識別中,通常把聲學模型轉換成了一個語音序列到發音序列(音素)的模型和一個發音序列到輸出文字序列的字典。
???????需要注意的是,由于人類發聲器官運動的連續性,以及某些語言中特定的拼讀習慣,會導致音素的發音受到前后音素的影響。為了對不同語境的音素加以區分,通常使用能夠考慮前后各一個音素的三音子作為建模單元。
???????另外,在聲學模型中,可以把三音子分解為更小的顆?!獱顟B,通常一個三音子對應3個狀態,但是這會引起建模參數的指數增長,常用的解決方案是使用決策樹先對這些三音子模型進行聚類,然后使用聚類的結果作為分類目標。
???????至此,語音識別有了最終的分類目標—狀態。最常用的聲學建模方式是隱馬爾科夫模型(HMM)。在HMM下,狀態是隱變量,語音是觀測值,狀態之間的跳轉符合馬爾科夫假設。其中,狀態轉移概率密度多采用幾何分布建模,而擬合隱變量到觀測值的觀測概率的模型常用高斯混合模型(GMM)。基于深度學習的發展,深度神經網絡(DNN)、卷積神經網絡(CNN)、循環神經網絡(RNN)等模型被應用到觀測概率的建模中,并取得了非常好的效果。下文給出各個模型的原理、所解決的問題及各自局限性,且給出了由模型的局限性而引起建模方式發展的脈絡。
1)高斯混合模型(GMM)
???????觀測概率密度函數由高斯混合模型建模,訓練中,不斷迭代優化,以求取GMM中的加權系數及各個高斯函數的均值與方差。GMM模型訓練速度較快,且GMM聲學模型參數量小,可以容易地嵌入到終端設備中。在很長一段時間內,GMM-HMM混合模型都是表現最優秀的語音識別模型。但是GMM不能利用語境信息,其建模能力有限。
2)深度神經網絡(DNN)
???????最早用于聲學模型建模的神經網絡,DNN解決了基于高斯混合模型進行數據表示的低效問題。語音識別中,DNN-HMM混合模型大幅度的提升了識別率。目前階段,DNN-HMM基于其相對有限的訓練成本及高識別率,仍然是特定的語音識別工業領域常用的聲學模型。需要注意的是,基于建模方式的約束(模型輸入特征長度的一致性需求),DNN模型使用的是固定長度的滑動窗來提取特征。
3)循環神經網絡(RNN)/卷積神經網絡(CNN)模型
???????對于不同的音素與語速,利用語境信息最優的特征窗長度是不同的。能夠有效利用可變長度語境信息的RNN與CNN在語音識別中能夠取得更好的識別性能。因而,在語速魯棒性方面,CNN/RNN比DNN表現的更好。
???????在使用RNN建模方面,用于語音識別建模的模型有:多隱層的長短期記憶網絡(LSTM)、highway LSTM、ResidualLSTM、雙向LSTM、時延控制的雙向LSTM。
???????LSTM,基于門控電路設計,其能夠利用長短時信息,在語音識別中取得了非常好的性能。另外,可以通過增加層數進一步提升識別性能,但是簡單地增加LSTM的層數會引起訓練困難及梯度消失問題。
???????Highway LSTM,在LSTM相鄰層的記憶單元間添加一個門控的直接鏈路,為信息在不同層間流動提供一個直接且不衰減的路徑,從而解決梯度消失問題
???????Residual LSTM,在LSTM層間提供一個捷徑,亦能解決梯度消失問題。
???????雙向LSTM,能夠利用過去及未來的語境信息,因而其識別性能比單向的LSTM好,但是由于雙向LSTM利用了未來的信息,因而基于雙向LSTM建模的語音識別系統需要觀察完整的一段話之后才能識別,從而不適用于實時語音識別系統。
???????時延控制的雙向LSTM,通過調整雙向LSTM的反向LSTM,實現了性能與實時性的一個折中建模方案,能夠應用于實時的語音識別系統。
???????CNN建模方面,包括時延神經網絡(TDNN)、CNN-DNN、CNN-LSTM-DNN(CLDNN)、CNN-DNN-LSTM(CDL)、深度CNN、逐層語境擴展和注意(LACE)CNN、dilated CNN。
???????TDNN,最早被用于語音識別的CNN建模方式,TDNN會沿頻率軸和時間軸同時進行卷積,因此能夠利用可變長度的語境信息。TDNN用于語音識別分為兩種情況,第一種情況下:只有TDNN,很難用于大詞匯量連續性語音識別(LVCSR),原因在于可變長度的表述(utterance)與可變長度的語境信息是兩回事,在LVCSR中需要處理可變長度表述問題,而TDNN只能處理可變長度語境信息;第二種情況:TDNN-HMM混合模型,由于HMM能夠處理可變長度表述問題,因而該模型能夠有效地處理LVCSR問題。
???????CNN-DNN,在DNN前增加一到兩層的卷積層,以提升對不同說話人的可變長度聲道(vocal tract)問題的魯棒性,對比于單純DNN,CNN-DNN性能有一定幅度(5%)的提升
???????CLDNN及CDL,在這兩個模型中,CNN只處理頻率軸的變化,LSTM用于利用可變長度語境信息。
???????深度CNN,這里的“深度”是指一百層以上。語譜圖可以被看作是帶有特定模式的圖像,通過使用比較小的卷積核以及更多的層,來利用時間及頻率軸上長范圍的相關信息,深度CNN的建模性能與雙向LSTM性能相當,但是深度CNN沒有時延問題。在控制計算成本的情況下,深度CNN能夠很好的應用于實時系統。
???????逐層語境擴展和注意(LACE)CNN及dilatedCNN,深度CNN的計算量比較大,因而提出了能夠減小計算量的 LACE CNN與dilatedCNN,其把整個話語看作單張輸入圖,因而可以復用中間結果,另外,可以通過設計LACE CNN及dilatedCNN網絡每一層的步長,使其能夠覆蓋整個核,來降低計算成本。
???????語音識別的應用環境常常比較復雜,選擇能夠應對各種情況的模型建模聲學模型是工業界及學術界常用的建模方式。但是各個單一模型都有局限性。HMM能夠處理可變長度的表述,CNN能夠處理可變聲道,RNN/CNN能夠處理可變語境信息。聲學模型建模中,混合模型由于能夠結合各個模型的優勢,是目前聲學建模的主流方式。
3.2 ?語言模型
???????語音識別中,最常見的語言模型是N-Gram。近年,深度神經網絡的建模方式也被應用到語言模型中,比如基于CNN及RNN的語言模型。
4、端到端的語音識別系統
???????在DNN-HMM或者CNN/RNN-HMM模型中,DNN/CNN/RNN與HMM是分開優化的,但是語音識別本質上是一個序列識別問題,如果模型中的所有組件都能夠聯合優化,很可能會獲取更好的識別準確度,這一點從語音識別的數學表達式也可以看出(利用貝葉斯準則變化之后的表達式),因而端到端的處理方式亦被引入到語音識別系統中。
4.1 ?CTC準則
???????其核心思想是引入空白標簽,然后基于前向后向算法做序列到序列的映射。CTC準則可分為character-basedCTC、other output units-based CTC、word-basedCTC,由于CTC準則是直接預測字符、單詞等,而不是預測音素,因而其能夠剔除語音識別中的字典等專家知識。由于在非word-basedCTC中,仍然需要語言模型及解碼器。因而,character-basedCTC與other output units-basedCTC是非純粹的端到端的語音識別系統。相反,word-based CTC模型是純粹的端到端語音識別系統。
???????基于word-based CTC準則,使用10萬個詞作為輸出目標且使用 12.5 萬小時訓練樣本得到的語音序列到單詞序列的模型,能夠超越基于音素單元的模型。但是word-based CTC模型有訓練困難及收斂慢的問題。
4.2 ?Attention-based模型
???????相比于CTC準則,Attention-based模型不需要有幀間獨立性假設,這也是Attention-based模型的一大優勢,因而Attention-based模型可能能夠取得更好的識別性能。但是相比于CTC準則,Attention-based模型訓練更加困難,且有不能單調地從左到右對齊及收斂更慢的缺點。通過將CTC 目標函數用作輔助代價函數,Attention訓練和 CTC訓練以一種多任務學習的方式結合到了一起。這種訓練策略能夠很大程度上改善Attention-based模型的收斂問題,并且緩解了對齊問題。
???????語音識別的發展過程中,深度學習起到了關鍵的作用。聲學模型遵循從DNN 到LSTM再到端到端建模的發展路徑。深度學習最大的優勢之一是特征表征。在有噪聲、回響等情況下,深度學習可以把噪聲、回響看為新的特征,并通過對有噪聲、回響數據的學習,達到比較理想的識別性能。目前階段,端到端的建模方式是聲學模型建模的重點研究方向,但是相比于其它的建模方式,其還沒有取得明顯的性能優勢。如何在端到端建模的基礎上,提升訓練速度及性能,并解決收斂問題是聲學模型的重要研究方向。
5、解碼
???????基于訓練好的聲學模型,并結合詞典、語言模型,對輸入的語音幀序列識別的過程即為解碼的過程。傳統的解碼是將聲學模型、詞典以及語言模型編譯成一個網絡。解碼就是在這個動態網絡空間中,基于最大后驗概率,選擇一條或多條最優路徑作為識別結果(最優的輸出字符序列)。搜索常用的方法是Viterbi算法。對于端到端的語音識別系統,最簡單的解碼方法是beamsearch算法。
6、遠場復雜環境下解決方案?
???????目前階段,在近場安靜環境下,語音識別能夠取得非常理想的識別效果,但是在高噪聲、多人說話、強口音等環境,特別是遠場環境下,語音識別還有諸多問題需要解決。語音模型自適應、語音增強與分離、識別模型優化等是常用的可選解決方案。
6.1 ?語音增強與分離
???????遠場環境下,語音輸入信號衰減比較嚴重,為了對語音信號增強,常采用麥克風陣列的波束形成技術,比如,GoogleHome采用雙麥的設計方案,亞馬遜Echo采用6+1的麥克風陣列設計方案。近年,深度學習方法被應用到語音增強與分離中,核心思想是把語音增強與分離轉化為一個監督學習問題,即預測輸入聲音源的問題。有研究使用DNN替代波束形成,實現語音增強,并在一定場景下取得了比較理想的效果。但是在背景噪聲很大的環境中,該方法性能還有較大提升空間。
???????在多人說話的情況下,如果不對輸入信號做分離處理,而進行語音識別的話,識別效果會很差。對于該問題,在多個說話人距離較遠的情況下,波束形成是一個比較好的解決方案,但是當多個說話人距離很近的時候,波束形成的語音分離效果也很差。為了避開波束形成所帶來的場景分類問題,傳統的方法多是在單通道下嘗試解決該問題,常用算法有computationalauditory scene analysis、非負矩陣分解、deep clustering等,但是這些方法只有當噪聲信號(除聲源外的其他信號)與聲音源信號有明顯不同的特征時,這些技術才取得比較好的效果。其它情況下,這些方法在語音分離中取得的效果一般。2016年,俞棟博士提出了一種新的深度學習訓練準則–permutation invariant training,巧妙地解決了該問題,并取得了不錯的效果。
6.2 ?語音模型自適應
??????大量且豐富(能夠提供更多信息)的數據集是提升模型泛化能力的最直接簡單的方法;
基于成本及訓練時間的考慮,一般情況下只使用有限的訓練數據。此時,在模型訓練中加入Kullback-Leiblerdivergence正則項是解決模型自適應問題非常有效的方式;
除了加入正則項外,使用非常少的參數來表征說話者特征是另一種自適應方式,其包括:奇異值分解瓶頸自適應,把滿秩矩陣分解為兩個低秩矩陣,減小訓練參數;子空間法,子空間法又包括:
??????1. 在輸入空間及深度網絡的各個層中加入i-vector、揚聲器(speaker)編碼、噪聲估計等輔助特征;
??????2. 聚類自適應訓練(CAT);
??????3. 隱層分解(FHL),相比于CAT,FHL只需要少量的訓練數據,原因在于FHL的基是秩為1的矩陣,而CAT的基是滿秩矩陣,在基數量一樣的情況下,CAT需要更多的訓練數據。
??????實時性是語音識別應用中關注度很高的問題之一,實時性直接影響用戶的體驗感,提高語音識別的實時性可以通過降低運算時間成本與提升識別硬件計算能力兩方面完成。
7、降低運算時間成本
??????SVD,基于奇異值分解的數學原理,把滿秩矩陣分解為兩個低秩矩陣,減小深度模型的參數,且能夠不降低模型識別性能;
壓縮模型,使用向量量化或者極低比特量化算法;
??????改變模型結構,主要針對LSTM,在LSTM中增加一個線性映射層,降低原有LSTM的輸出維度,從而降低運算時間成本;
??????使用跨幀的相關性來降低評估深度網絡分數的頻率,對于DNN或CNN而言,這可以通過使用跳幀策略完成,即每隔幾幀才計算一次聲學分數,并在解碼時將該分數復制到沒有評估聲學分數的幀 。
??????另外,提升識別階段硬件的運算能力,開發專用的語音識別芯片對增強語音識別的實時性意義重大,下文將會在這方面展開討論。
三、算法
?????? 至此語音識別的大體過程已經OK了,下面來看具體傳統模型GMM-HMM的算法。
?????? 語音識別過程就是輸入一段語音信號,找到一串文字(字或詞)序列的過程,
語音輸入
O?=o1,o2,o3,…,ot
對應的標注
W?=w1,w2,w3,…,wn?
這個過程一般用概率來表示,用O表示語音信號,用W表示文字序列,則是要解決下面這個問題:
由貝葉斯公式
展開,可得
由于P(O|W?)P(W?) /P(O)是對每個句子進行計算的,而對每個句子來說P(O) 是不變的,所以可以改寫成如下
即:
其中P(O|W?)稱做觀測最大釋然,由聲學模型計算可得 其中P(w)稱做先驗概率,由語言模型模型計算可得
綜上所述,語音識別就是解碼(decoding)過程,如下圖所示:
聲學模型的任務是計算P(O|W?), 即給定文字之后發出這段語音的概率(最后利用貝葉斯,求P(O|W?)是使用)。 首先第一問題: 怎么才能知道每個單詞發什么音呢? 這就需要另外一個模塊,叫做詞典,看eesen的源碼在數據準備階段就是先求出詞對應音素的dict, 它的作用就是把單詞串轉化成音素串,然后再求的語言模型和 訓練聲學模型(用lstm+ctc 訓練聲學模型).
有了dict的幫助,聲學模型就知道給定的文字串該依次發哪些音了。不過為了計算語音跟音素串的匹配程度,還需要知道每個音素的起止時間。 這是利用動歸來進行的,可以高效的找到音素的分界點,使得每一段語音與音素的匹配程度(用概率表示)之積最大。實際使用的算法稱為viterbi算法,它不僅僅考慮了每一段語音和音素的匹配程度,還考慮了各個音素之間轉換的概率(轉換概率通過HMM估計) 實際中使用的比音素更小的單位,原理一樣(不是很確定,值得是一幀數據(25ms)嗎,一幀不到不到一個音素的長度?)
在求音素分界點的過程中,以及在有了分界點后計算P(O|W?)時,聲學模型都需要知道怎樣計算一個音素與一段語音信號的匹配程度。要做這件事,需要找到一種合適的表示語音信號的方法。一般是把語音信號分成許多幀,對于每一幀,通過傅里葉變換等一系列操作,把它轉換成一個特征向量。最常用的特征是MFCC,從訓練數據中,我們可以提取出大量的特征向量,以及它們對應的音素;利用這些數據,就可以訓練從特征到音素的分類器。前些年最常用的分類器是高斯混合模型(GMM),它的大致原理是估計出每個音素的特征向量的分布,然后在識別階段,計算每一幀的特征向量x_t由相應音素s_i產生的概率P(x_t|s_i),把每一幀的概率相乘,就得到P(O|W?)?,F在,神經網絡漸漸火了起來,它可以直接給出P(s_i|x_i),用貝葉斯公式可以轉換成P(x_t|s_i),再相乘得到P(O|W?)。P(O|W?) 稱做觀測最大釋然,由聲學模型計算可得,本章就主要描述HMM+GMM來計算最大釋然的過程。
首先回顧一下:在解碼過程中
P(O|W?)由聲學模型訓練得到,
P(O|W?)是W的似然函數,結合之前講述的聲學特征也就是說,在給定的W情況,使得當前的特征向量(MFCC)的概率最大,結合HMM的概念,也就是說在在t時刻給定狀態qi?的前提下,求輸出O的概率,即p(ot|qi) ,即矩陣B,狀態對應的是word,phone或者subphone,在LVCSR中對應的是subphone
在解碼階段,在固定觀測向量ot 的前提下,我們需要計算每一個HMM狀態可能產生的概率,然后找到最大可能的狀態(subphone)序列,所以訓練過程就是計算觀測似然矩陣B的過程。
理想的方式計算MFCC的時候,可以把輸入的幀映射為一些離散的量化符號方便計算,如下圖所示
然后這么計算似然是有問題的,因為輸入音頻是連續的,特征基本變化很大的,很難進行比較好的聚類,因此提出連續空間的概率密度函數(PDF),最常用的計算聲學似然的方式是高斯混合模型,即GMM模型(當然SVM,CRF,NN也可以)。
高斯分布也是一種正態分布,函數如下所示
不同的均值,方差下,對應的高斯分布如下所示:
離散情況下,均值,方差計算如下所示:
??
當高斯函數用來當做概率密度函數時,曲線下的面積和應該為1,如下所示,灰色區域面積為0.341
我們可以用單GMM pdf來估測一個特定的HMM狀態j,產生一個單一維度的聲學特征向量O的概率,(假設
ot 服從正態分布),換句話說,就是用對一維特征來說,一元高斯來代表觀測似然函數bj(ot) ?,
假設HMM狀態j 對應的均值方式是μj?和σ2j ?,那么計算似然 ?bj(ot) 可以通過Gaussian PDF來計算,如下所示:
有了以上公式,我們就可以來進行HMM decoding了
然而如何計算均值和方差呢,按理來說可以通過如下公式進行計算
然而,狀態是HMM隱藏狀態,我們不知道Ot是由哪個狀態產生的,
但是我們可以通過HMM中t時刻在狀態i的概率來按比例分配,即把每個Ot分配給每個可能的狀態i。
把ξt?(i) 記做在t時刻狀態i產生Ot的概率,
那么通過Baum-Welch 迭代算法進行計算,如下所示:
也叫作HMM前向-后向(Baum-Welch)訓練。
以上討論的是一維特征,在實際中,MFCC是39維特征,因此我們使用了多元高斯模型,
多元高斯分布函數如下所示:
協方差計算公式如下:
則,高斯概率似然函數b?j?(ot?)?如下所示:
因為對角協方差計算量更小,所以可以簡化為對角協方差
可以表述為:在t時刻,狀態j產生聲學特征向量Ot的似然函數可以表述為對角協方差多元高斯,
上述公式可以簡化成如下公式:
ξt?(i) 記做t時刻,狀態i產生Ot的似然,對應均值方差為:
以上的前提聲學特征符合正態分布,但是實際倒譜特征MFCC不是正態分布,因此我們可以改進為
加權的混合多遠高斯模型,即GMM,對應函數公式如下所示:
對應的輸出似然函數bj(ot)?如下所示:
把ξtm(j)記做t時刻,狀態j,在m元 混合模型情況下產生聲學特征Ot的概率,公式如下
對應均值方差,同樣可以由Baum-Welch 迭代算出來,公式如下:
在實際計算中,一個句子的似然是一串概率相乘,導致概率數值非常低,如.00000001=10?8?容易下溢出,而且不方便計算,,所以常常用log來計算,則上述輸出似然函數b?j?(ot?)可以改寫如下所示:
重寫可得:
其中C為:
C為常數,可以再decoding之前提前計算出來,節省計算時間
以上就是GMM在訓練聲學模型中的應用。
本章主要講解HMM訓練過程,首先回顧上章的HMM模型如下:
Q?=q1q2…qN ? 狀態集合(subphone集合)
A?=a01a02…an1…ann ? 狀態(subphone)轉移矩陣,Q和A構成了發音字典
B=bi(ot) ?觀測似然,也叫作發射概率 ,表述為:每個subphone狀態i產生倒譜特征Ot的概率
最簡單的方式是給定手工標注的孤立詞和對應的音頻文件,計算每個子音素(subphone)對應的標注來計算矩陣B,然而實際中卻無法做到,因為每個subphone對應的Ot是很難用手工去標注的。(用手工去在一斷連續的音頻上標注一個子因素是不可行的)因此,訓練每個phone的HMM是嵌入在整個句子中進行的,音素的分割和對其是在訓練過程中自動進行的,所以整個這個訓練過程叫做嵌入式訓練(embedded training?)
數據準備:在訓練過程前,需要準備wav音頻文件,對應的標注文本,還有發音字典,基于句子的HMM構建如下:
接下來就是訓練狀態轉移矩陣A和似然估計矩陣B了,
用ξj(t) 表示:在t時刻,狀態i生成觀測序列O的概率。
在初始階段,我們需要對ai j和bj(ot)?一個初始的估計 ,最簡單的做法叫做flat start,
在flat start中,狀態轉移矩陣中,狀態的自環和跳轉到下一個狀態(subphone)的概率相同,為0.5,高斯的均值方差取全局訓練數據的均值和方差?,F在有了基礎的HMM-GMM參數了,接下來就要在整個訓練集合上跑Balum-Welch算法,每次迭代,都要修改HMM參數,直到系統趨于一致不變。首先在給定初始的矩陣A和B的情況下,計算前向-后向概率,然后,用前向-后向概率重新估算新的矩陣A和矩陣B,具體推導會在下一篇文章《HMM基礎-HMM訓練-前向后向算法》章節詳細討論。同時用EM算法來更新多元高斯模型的均值和方差。
綜上所述,標準的嵌入式訓練過程如下所述:
給定訓練音頻文件,標注文件,發音字典情況下
1)如上圖所述,對每個句子,構建一個句子的HMM模型。
2)初始化狀態轉移中的非零元素(自環為0.75,和跳轉到下一個狀態的為0.25)
3)初始化發射概率矩陣每個高斯的均值方差為所以訓練集合的全局均值和方差。
4)EM迭代多次,用Viterbi來計算ξj(t) (在t時刻,狀態i生成觀測序列O的概率),
為計算ξj(t) ,要累計所有可能的路徑,這樣計算太慢了,一個更高效的算法是Viterbi 算法,
在訓練算法中,不再是用前向-后向算法累計所有的路徑來計算ξj(t),而是通過重復的跑Viterbi路徑(最大概率路徑)
來接近估測這個值。
用Viterbi來訓練數據過程,也叫作強制Viterbi對齊,或強制對齊過程
在Viterbi對齊過程中,因為已經知道觀察序列對應的詞序列,所以合適的設置aij ,就可以強制Viterbi算法來通過某個指定的詞。
Viterbi對齊其實是Viterbi解碼的一個簡化版,因為,Viterbi強制對齊過程中只需要找到觀測值Ot對應正確的狀態(或subphone)序列,而不需要找到正確的詞序列。訓練結果就是Viterbi強制對齊:即,對應觀測序列O的,一條最優狀態序列。
接下來,我們可以用對齊的HMM狀態到累計counts,從而重新估計HMM參數。
Viterbi對齊中重新訓練高斯模型參數的公式如下所示:
高斯混合模型的計算參加上一篇文章。
以上就是嵌入式訓練過程。
上一篇討論了語音識別中的訓練過程,本章討論語音識別中,解碼的過程。
解碼的過程就是在給定聲學特征的情況下,找到最可能對應的詞組的過程,再次看如下求解目的的公式:
其中似然概率是在一系列給定聲學frame情況下,計算每個對應的分類器得分,然后相乘得出的概率,使得其值變得很小,而P(W)比較大,這樣就導致
P(w)權重太大了,所以需要對齊進行縮放,以平衡貢獻值,所以把上面公式改寫如下:
因為P(w)小于1,使LMSF大于1,(5-15),這樣就減小了P(w)對整個公式的貢獻,以達到縮放的目的。
但是在P(w)中以上懲罰對詞插入的情況下是有副作用的,所以改寫如下:
在log形式展開,最后解碼的目標就是如下公式所示:
有了上述的目標公式,接下來就要討論,如何解碼取其最大值
解碼中最常用的是Viterbi算法,首先看一下語音識別中HMM模型:
Q?=q1q2…qN ? 對應subphone的狀態序列
A?=a01a02…an1…ann ? 狀態轉移矩陣(自環和轉到下一個狀態)
B?=bi(ot) ? 觀測似然,或者叫做發射概率,代表在t時刻,狀態i產生聲音倒譜特征O的概率
其中A和B由上一章中的嵌入式訓練得到。下圖為識別數字的HMM結構圖。
首先我看用前向算法O(N2T)?來進行解碼的過程,
舉例如下:英文字母five,有對應狀態[f], [ay], 和[v] ,觀測序列O,如下所示:
? ? ?
首先我們引入αt(j) ?,記做:在看見前t個觀測值之后,處于狀態j的概率。
這里qt=j 表示在狀態序列中,t時刻狀態為j,
αt?(?j) 可以理解為,所有能到到達當前狀態的所有路徑的概率之和,即:
其中,αt?1(i) 表示前一個(t-1)之前的路徑的概率,
aij 表示概率轉移矩陣,表示從狀態qi ?到當前狀態q?j 的概率
bj(ot) 叫做狀態觀測似然,也叫作發射概率,表示給定狀態j,觀測到ot ?的概率
前向算法如下所示:
qF 表示結束狀態。
假設矩陣A自環概率概率為0.5,假設矩陣B如下所示:
則單詞“five”的前向算法過程如下所示:
接著討論Viterbi算法,
Viterbi算法是返回最可能的狀態序列,雖然不是最可能的次序列,但是也足夠接近了,其時間復雜度為
O(N2T) ,
使得vt(j)記做:在給定 λ 的情況下,在看到前t個觀測特征Ot,且通過了最可能的q1…qt?1 狀態序列的情況下,HMM當前狀態為j的概率,即:
根據動態規劃算法,可以理解為t-1時刻的在狀態i時候的最大概率路徑到當前時刻t時候,狀態為j的概率,記做:
vt?1(i) 表示:前一時刻,Viterbit路徑的概率;
ai j 表示:狀態qi 到狀態qj的概率 ;
bj(ot) 表示:狀態觀測似然,表示為給定狀態j,產生觀測向量ot ?的概率。
根據上式可知,Viterbi算法是在給定觀測序列o= (o1o2o3…oT) 情況下,找到最優的狀態序列q=(q1q2q3…qT)的過程
,同時找到對應的最大的概率。對比上面的前向算法可知,他們目標都是一致的,但是Viterbi算法是求其最大值。
Viterbi具體解碼算法如下所示:(假設起始狀態為0,結束狀態為qF,是非發射狀態)
例子:
假設矩陣A自環概率概率為0.5,假設矩陣B如下所示:
則對應的計算數值如下所示:
Viterbi解碼的真正用處不僅僅是在詞內解碼,更重要的是可以解碼一串詞,為了使Viterbi能夠進行詞間進行解碼,我們得增加矩陣A,使其不僅要有詞內的狀態轉移概率,還需要增加從一個詞末尾,到另一個詞開始的狀態轉移概率。
下圖補充了2-gram間的轉移概率,
下圖展示了2-gram詞間解碼的過程:
一旦一句話的Viterbi解碼計算完畢,就可以用過后項指針回溯,來找到最大概率的狀態序列,即最大概率的詞序列。
如下圖所示:最后的回溯詞序列為w1wN···w2?
實際上Viterbi解碼過程中需要進行beam剪枝,通過設定beam的寬度θ?來進行beam剪枝。
Beam剪枝算法我們以后章節繼續討論。
以上就是語音識別過程中,解碼的所有細節,謝謝!
由于本人實在看不懂這些算法,這也是個人理出來的算法流程邏輯,如有錯誤請見諒!
詳情請參考博客 http://blog.csdn.net/quhediegooo?viewmode=contents
四、PocketSphinx的安裝、編譯、訓練以及一些坑
?????? 先說一些遇到的問題:1、我說過在Sphinx0.8以后,Sphinx就沒有支持中文model,(后面是猜測)所以Sphinx并沒有更新和優化中文相關的邏輯,也就是中文模型的訓練沒搞好,在實際應用的時候在他的網站訓練后的Grammer存在一定誤識別率,我想原因就是因為它的訓練集比不是很多。2、在0.8之后,現在最新的版本中沒有中文模型,所以面臨的問題也是訓練數據集不足,也會出現誤識別率很高,所以根據官網給出的建議,200人5小時的訓練時長(非特定人)和覆蓋較大的字典(需大詞匯量,否則小詞匯量會導致分類較少)是比較好的選擇。
?????? 具體安裝、編譯、訓練方法,請根據http://www.cnblogs.com/bhlsheji/p/4514475.html描述進行,已驗證過可行。這里不做過多描述了。注意的細節我之后會總結!
?????? 對于PocketSphinx的代碼框架結構網上沒有找到解析,但是可以根據http://ishare.iask.sina.com.cn/f/66428902.html這篇文章(講解Sphinx4的代碼結構)其中氛圍預處理模塊、搜索管理模塊、語言模塊。大部分邏輯在SphinxBase項目中、PocketSphinx做一些封裝調用(猜的)。
五、總結
?????? 說一些我個人看法。
1)以我們當前只做非特定人、小詞匯量、半連續語音識別,注意的同樣在于訓練數據集較少,導致誤識別率很高。
2)語音識別框架最好用C/C++,好處:可移植性強、高效、安全。
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀
總結
以上是生活随笔為你收集整理的【机器听觉】初探语音识别技术的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【机器视觉】计算机视觉如何入门
- 下一篇: 【数学】Why Study Math 为