語音識別是以語音為研究對象,通過語音信號處理和模式識別讓機器自動識別和理解人類口述的語言。語音識別技術就是讓機器通過識別和理解過程把語音信號轉變為相應的文本或命令的高技術。語音識別是一門涉及面很廣的交叉學科,它與聲學、語音學、語言學、信息理論、模式識別理論以及神經生物學等學科都有非常密切的關系。語音識別技術正逐步成為計算機信息處理技術中的關鍵技術,語音技術的應用已經成為一個具有競爭性的新興高技術產業。
語音識別的基本原理
語音識別系統本質上是一種模式識別系統,包括特征提取、模式匹配、參考模式庫等三個基本單元,它的基本結構如下圖所示:
未知語音經過話筒變換成電信號后加在識別系統的輸入端,首先經過預處理,再根據人的語音特點建立語音模型,對輸入的語音信號進行分析,并抽取所需的特征,在此基礎上建立語音識別所需的模板。而計算機在識別過程中要根據語音識別的模型,將計算機中存放的語音模板與輸入的語音信號的特征進行比較,根據一定的搜索和匹配策略,找出一系列最優的與輸入語音匹配的模板。然后根據此模板的定義,通過查表就可以給出計算機的識別結果。顯然,這種最優的結果與特征的選擇、語音模型的好壞、模板是否準確都有直接的關系。
語音識別系統構建過程整體上包括兩大部分:訓練和識別。訓練通常是離線完成的,對預先收集好的海量語音、語言數據庫進行信號處理和知識挖掘,獲取語音識別系統所需要的“聲學模型”和“語言模型”;而識別過程通常是在線完成的,對用戶實時的語音進行自動識別。識別過程通常又可以分為“前端”和“后端”兩大模塊:“前端”模塊主要的作用是進行端點檢測(去除多余的靜音和非說話聲)、降噪、特征提取等;“后端”模塊的作用是利用訓練好的“聲學模型”和“語言模型”對用戶說話的特征向量進行統計模式識別(又稱“解碼”),得到其包含的文字信息,此外,后端模塊還存在一個“自適應”的反饋模塊,可以對用戶的語音進行自學習,從而對“聲學模型”和“語音模型”進行必要的“校正”,進一步提高識別的準確率。
語音識別是模式識別的一個分支,又從屬于信號處理科學領域,同時與語音學、語言學、數理統計及神經生物學等學科有非常密切的關系。語音識別的目的就是讓機器“聽懂”人類口述的語言,包括了兩方面的含義:其一是逐字逐句聽懂并轉化成書面語言文字;其二是對口述語言中所包含的要求或詢問加以理解,做出正確響應,而不拘泥于所有詞的正確轉換。
自動語音識別技術有三個基本原理:首先語音信號中的語言信息是按照短時幅度譜的時間變化模式來編碼;其次語音是可以閱讀的,即它的聲學信號可以在不考慮說話人試圖傳達的信息內容的情況下用數十個具有區別性的、離散的符號來表示;第三語音交互是一個認知過程,因而不能與語言的語法、語義和語用結構割裂開來。
聲學模型:語音識別系統的模型通常由聲學模型和語言模型兩部分組成,分別對應于語音到音節概率的計算和音節到字概率的計算。
搜索:連續語音識別中的搜索,就是尋找一個詞模型序列以描述輸入語音信號,從而得到詞解碼序列。搜索所依據的是對公式中的聲學模型打分和語言模型打分。在實際使用中,往往要依據經驗給語言模型加上一個高權重,并設置一個長詞懲罰分數。
系統實現:語音識別系統選擇識別基元的要求是,有準確的定義,能得到足夠數據進行訓練,具有一般性。英語通常采用上下文相關的音素建模,漢語的協同發音不如英語嚴重,可以采用音節建模。系統所需的訓練數據大小與模型復雜度有關。模型設計得過于復雜以至于超出了所提供的訓練數據的能力,會使得性能急劇下降。
聽寫機:大詞匯量、非特定人、連續語音識別系統通常稱為聽寫機。其架構就是建立在前述聲學模型和語言模型基礎上的HMM拓撲結構。訓練時對每個基元用前向后向算法獲得模型參數,識別時,將基元串接成詞,詞間加上靜音模型并引入語言模型作為詞間轉移概率,形成循環結構,用Viterbi算法進行解碼。針對漢語易于分割的特點,先進行分割再對每一段進行解碼,是用以提高效率的一個簡化方法。
對話系統:用于實現人機口語對話的系統稱為對話系統。受目前技術所限,對話系統往往是面向一個狹窄領域、詞匯量有限的系統,其題材有旅游查詢、訂票、數據庫檢索等等。其前端是一個語音識別器,識別產生的N-best候選或詞候選網格,由語法分析器進行分析獲取語義信息,再由對話管理器確定應答信息,由語音合成器輸出。由于目前的系統往往詞匯量有限,也可以用提取關鍵詞的方法來獲取語義信息。
語音識別技術原理-工作原理解讀
首先,我們知道聲音實際上是一種波。常見的mp3等格式都是壓縮格式,必須轉成非壓縮的純波形文件來處理,比如Windows PCM文件,也就是俗稱的wav文件。wav文件里存儲的除了一個文件頭以外,就是聲音波形的一個個點了。下圖是一個波形的示例。
圖中,每幀的長度為25毫秒,每兩幀之間有25-10=15毫秒的交疊。我們稱為以幀長25ms、幀移10ms分幀。
分幀后,語音就變成了很多小段。但波形在時域上幾乎沒有描述能力,因此必須將波形作變換。常見的一種變換方法是提取MFCC特征,根據人耳的生理特性,把每一幀波形變成一個多維向量,可以簡單地理解為這個向量包含了這幀語音的內容信息。這個過程叫做聲學特征提取。實際應用中,這一步有很多細節,聲學特征也不止有MFCC這一種,具體這里不講。
至此,聲音就成了一個12行(假設聲學特征是12維)、N列的一個矩陣,稱之為觀察序列,這里N為總幀數。觀察序列如下圖所示,圖中,每一幀都用一個12維的向量表示,色塊的顏色深淺表示向量值的大小。
消除噪聲和不同說話人的發音差異帶來的影響
接下來就要介紹怎樣把這個矩陣變成文本了。首先要介紹兩個概念:
音素:單詞的發音由音素構成。對英語,一種常用的音素集是卡內基梅隆大學的一套由39個音素構成的音素集,參見The CMU Pronouncing Dictionary。漢語一般直接用全部聲母和韻母作為音素集,另外漢語識別還分有調無調,不詳述。
狀態:這里理解成比音素更細致的語音單位就行啦。通常把一個音素劃分成3個狀態。
語音識別是怎么工作的呢?實際上一點都不神秘,無非是:
第一步,把幀識別成狀態(難點)。
第二步,把狀態組合成音素。
第三步,把音素組合成單詞。
如下圖所示:
圖中,每個小豎條代表一幀,若干幀語音對應一個狀態,每三個狀態組合成一個音素,若干個音素組合成一個單詞。也就是說,只要知道每幀語音對應哪個狀態了,語音識別的結果也就出來了。
那每幀音素對應哪個狀態呢?有個容易想到的辦法,看某幀對應哪個狀態的概率最大,那這幀就屬于哪個狀態。比如下面的示意圖,這幀在狀態S3上的條件概率最大,因此就猜這幀屬于狀態S3。
那這些用到的概率從哪里讀取呢?有個叫“聲學模型”的東西,里面存了一大堆參數,通過這些參數,就可以知道幀和狀態對應的概率。獲取這一大堆參數的方法叫做“訓練”,需要使用巨大數量的語音數據,訓練的方法比較繁瑣,這里不講。
但這樣做有一個問題:每一幀都會得到一個狀態號,最后整個語音就會得到一堆亂七八糟的狀態號,相鄰兩幀間的狀態號基本都不相同。假設語音有1000幀,每幀對應1個狀態,每3個狀態組合成一個音素,那么大概會組合成300個音素,但這段語音其實根本沒有這么多音素。如果真這么做,得到的狀態號可能根本無法組合成音素。實際上,相鄰幀的狀態應該大多數都是相同的才合理,因為每幀很短。
解決這個問題的常用方法就是使用隱馬爾可夫模型(Hidden Markov Model,HMM)。這東西聽起來好像很高深的樣子,實際上用起來很簡單:
第一步,構建一個狀態網絡。
第二步,從狀態網絡中尋找與聲音最匹配的路徑。
這樣就把結果限制在預先設定的網絡中,避免了剛才說到的問題,當然也帶來一個局限,比如你設定的網絡里只包含了“今天晴天”和“今天下雨”兩個句子的狀態路徑,那么不管說些什么,識別出的結果必然是這兩個句子中的一句。
那如果想識別任意文本呢?把這個網絡搭得足夠大,包含任意文本的路徑就可以了。但這個網絡越大,想要達到比較好的識別準確率就越難。所以要根據實際任務的需求,合理選擇網絡大小和結構。
搭建狀態網絡,是由單詞級網絡展開成音素網絡,再展開成狀態網絡。語音識別過程其實就是在狀態網絡中搜索一條最佳路徑,語音對應這條路徑的概率最大,這稱之為“解碼”。路徑搜索的算法是一種動態規劃剪枝的算法,稱之為Viterbi算法,用于尋找全局最優路徑。
這里所說的累積概率,由三部分構成,分別是:
觀察概率:每幀和每個狀態對應的概率
轉移概率:每個狀態轉移到自身或轉移到下個狀態的概率
語言概率:根據語言統計規律得到的概率
其中,前兩種概率從聲學模型中獲取,最后一種概率從語言模型中獲取。語言模型是使用大量的文本訓練出來的,可以利用某門語言本身的統計規律來幫助提升識別正確率。語言模型很重要,如果不使用語言模型,當狀態網絡較大時,識別出的結果基本是一團亂麻。
這樣基本上語音識別過程就完成了,這就是語音識別技術的原理。
語音識別技術原理-語音識別系統的工作流程
一般來說,一套完整的語音識別系統其工作過程分為7步:
①對語音信號進行分析和處理,除去冗余信息。
②提取影響語音識別的關鍵信息和表達語言含義的特征信息。
③緊扣特征信息,用最小單元識別字詞。
④按照不同語言的各自語法,依照先后次序識別字詞。
⑤把前后意思當作輔助識別條件,有利于分析和識別。
⑥按照語義分析,給關鍵信息劃分段落,取出所識別出的字詞并連接起來,同時根據語句意思調整句子構成。
⑦結合語義,仔細分析上下文的相互聯系,對當前正在處理的語句進行適當修正。
音識別系統基本原理框圖
語音識別系統基本原理結構如圖所示。語音識別原理有三點:①對語音信號中的語言信息編碼是按照幅度譜的時間變化來進行;②由于語音是可以閱讀的,也就是說聲學信號可以在不考慮說話人說話傳達的信息內容的前提下用多個具有區別性的、離散的符號來表示;③語音的交互是一個認知過程,所以絕對不能與語法、語義和用語規范等方面分裂開來。
預處理,其中就包括對語音信號進行采樣、克服混疊濾波、去除部分由個體發音的差異和環境引起的噪聲影響,此外還會考慮到語音識別基本單元的選取和端點檢測問題。反復訓練是在識別之前通過讓說話人多次重復語音,從原始語音信號樣本中去除冗余信息,保留關鍵信息,再按照一定規則對數據加以整理,構成模式庫。再者是模式匹配,它是整個語音識別系統的核心部分,是根據一定規則以及計算輸入特征與庫存模式之間的相似度,進而判斷出輸入語音的意思。
前端處理,先對原始語音信號進行處理,再進行特征提取,消除噪聲和不同說話人的發音差異帶來的影響,使處理后的信號能夠更完整地反映語音的本質特征提取,消除噪聲和不同說話人的發音差異帶來的影響,使處理后的信號能夠更完整地反映語音的本質特征。
用深度學習進行語音識別
機器學習并不總是一個黑盒
如果你知道神經機器翻譯是如何工作的,那么你可能會猜到,我們可以簡單地將聲音送入神經網絡中,并訓練使之生成文本:
一個大問題是語速不同。一個人可能很快地說出「hello!」而另一個人可能會非常緩慢地說「heeeelllllllllllllooooo!」。這產生了一個更長的聲音文件,也產生了更多的數據。這兩個聲音文件都應該被識別為完全相同的文本「hello!」而事實證明,把各種長度的音頻文件自動對齊到一個固定長度的文本是很難的一件事情。
為了解決這個問題,我們必須使用一些特殊的技巧,并進行一些深度神經網絡以外的特殊處理。讓我們看看它是如何工作的吧!
將聲音轉換成比特(Bit)
聲音是作為波(wave) 的形式傳播的。我們如何將聲波轉換成數字呢?讓我們使用我說的「hello」這個聲音片段舉個例子:
我說「hello」的波形
聲波是一維的,它在每個時刻都有一個基于其高度的值(聲波其實是二維的,有時間,還有振幅(即這個基于高度的值))。讓我們把聲波的一小部分放大看看:
為了將這個聲波轉換成數字,我們只記錄聲波在等距點的高度:
給聲波采樣
這被稱為采樣(sampling)。我們每秒讀取數千次,并把聲波在該時間點的高度用一個數字記錄下來。這基本上就是一個未壓縮的 .wav 音頻文件。
「CD 音質」的音頻是以 44.1khz(每秒 44100 個讀數)進行采樣的。但對于語音識別,16khz(每秒 16000 個采樣)的采樣率就足以覆蓋人類語音的頻率范圍了。
讓我們把「Hello」的聲波每秒采樣 16000 次。這是前 100 個采樣:
每個數字表示聲波在一秒鐘的 16000 分之一處的振幅。
數字采樣小助手
因為聲波采樣只是間歇性的讀取,你可能認為它只是對原始聲波進行粗略的近似估計。我們的讀數之間有間距,所以我們必然會丟失數據,對吧?
數字采樣能否完美重現原始聲波?那些間距怎么辦?
但是,由于采樣定理,我們知道我們可以利用數學,從間隔的采樣中完美重建原始聲波——只要我們的采樣頻率比期望得到的最高頻率快至少兩倍就行。
我提這一點,是因為幾乎每個人都會犯這個錯誤,并誤認為使用更高的采樣率總是會獲得更好的音頻質量。其實并不是。
預處理我們的采樣聲音數據
我們現在有一個數列,其中每個數字代表 1/16000 秒的聲波振幅。
我們可以把這些數字輸入到神經網絡中,但是試圖直接分析這些采樣來進行語音識別仍然很困難。相反,我們可以通過對音頻數據進行一些預處理來使問題變得更容易。
讓我們開始吧,首先將我們的采樣音頻分成每份 20 毫秒長的音頻塊。這是我們第一個 20 毫秒的音頻(即我們的前 320 個采樣):
將這些數字繪制為簡單的折線圖,我們就得到了這 20 毫秒內原始聲波的大致形狀:
雖然這段錄音只有**** 1/50 ****秒的長度,但即使是這樣短暫的錄音,也是由不同頻率的聲音復雜地組合在一起的。其中有一些低音,一些中音,甚至有幾處高音。但總的來說,就是這些不同頻率的聲音混合在一起,才組成了人類的語音。
為了使這個數據更容易被神經網絡處理,我們將把這個復雜的聲波分解成一個個組成部分。我們將分離低音部分,再分離下一個最低音的部分,以此類推。然后將(從低到高)每個頻段(frequency band)中的能量相加,我們就為各個類別的音頻片段創建了一個指紋(fingerprint)。
想象你有一段某人在鋼琴上演奏 C 大調和弦的錄音。這個聲音是由三個音符組合而成的:C、E 和 G。它們混合在一起組成了一個復雜的聲音。我們想把這個復雜的聲音分解成單獨的音符,以此來分辨 C、E 和 G。這和語音識別是一樣的道理。
我們需要傅里葉變換**(FourierTransform)來做到這一點。它將復雜的聲波分解為簡單的聲波。一旦我們有了這些單獨的聲波,我們就將每一份頻段所包含的能量加在一起。
最終得到的結果便是從低音(即低音音符)到高音,每個頻率范圍的重要程度。以每 50hz 為一個頻段的話,我們這 20 毫秒的音頻所含有的能量從低頻到高頻就可以表示為下面的列表:
列表中的每個數字表示那份 50Hz 的頻段所含的能量
不過,把它們畫成這樣的圖表會更加清晰
你可以看到,在我們的 20 毫秒聲音片段中有很多低頻能量,然而在更高的頻率中并沒有太多的能量。這是典型「男性」的聲音。
如果我們對每 20 毫秒的音頻塊重復這個過程,我們最終會得到一個頻譜圖(每一列從左到右都是一個 20 毫秒的塊):
「hello」聲音剪輯的完整聲譜
頻譜圖很酷,因為你可以在音頻數據中實實在在地看到音符和其他音高模式。對于神經網絡來說,相比于原始聲波,從這種數據中尋找規律要容易得多。因此,這就是我們將要實際輸入到神經網絡中去的數據表示方式。
從短聲音識別字符
現在我們有了格式易于處理的音頻,我們將把它輸入到深度神經網絡中去。神經網絡的輸入將會是 20 毫秒的音頻塊。對于每個小的音頻切片(audio slice),神經網絡都將嘗試找出當前正在說的聲音所對應的字母。
我們將使用一個循環神經網絡——即一個擁有記憶,能影響未來預測的神經網絡。這是因為它預測的每個字母都應該能夠影響它對下一個字母的預測。例如,如果我們到目前為止已經說了「HEL」,那么很有可能我們接下來會說「LO」來完成「Hello」。我們不太可能會說「XYZ」之類根本讀不出來的東西。因此,具有先前預測的記憶有助于神經網絡對未來進行更準確的預測。
當通過神經網絡跑完我們的整個音頻剪輯(一次一塊)之后,我們將最終得到一份映射(mapping),其中標明了每個音頻塊和其最有可能對應的字母。這是我說那句「Hello」所對應的映射的大致圖案:
我們的神經網絡正在預測我說的那個詞很有可能是「HHHEE_LL_LLLOOO」。但它同時認為我說的也可能是「HHHUU_LL_LLLOOO」,或者甚至是「AAAUU_LL_LLLOOO」。
我們可以遵循一些步驟來整理這個輸出。首先,我們將用單個字符替換任何重復的字符:
· HHHEE_LL_LLLOOO 變為 HE_L_LO
· HHHUU_LL_LLLOOO 變為 HU_L_LO
· AAAUU_LL_LLLOOO 變為 AU_L_LO
然后,我們將刪除所有空白:
· HE_L_LO 變為 HELLO
· HU_L_LO 變為 HULLO
· AU_L_LO 變為 AULLO
這讓我們得到三種可能的轉寫——「Hello」、「Hullo」和「Aullo」。如果你大聲說出這些詞,所有這些聲音都類似于「Hello」。因為神經網絡每次只預測一個字符,所以它會得出一些純粹表示發音的轉寫。例如,如果你說「He would not go」,它可能會給出一個「He wud net go」的轉寫。
在我們可能的轉寫「Hello」、「Hullo」和「Aullo」中,顯然「Hello」將更頻繁地出現在文本數據庫中(更不用說在我們原始的基于音頻的訓練數據中了),因此它可能就是正解。所以我們會選擇「Hello」作為我們的最終結果,而不是其他的轉寫。
參考:
https://zhuanlan.zhihu.com/p/24703268
http://dataunion.org/28416.html