基于80251的嵌入式語音識別
語音識別技術(shù),廣泛來說是指語意識別和聲紋識別;從狹義上來說指語音語義的理解識別,也稱為自動語音識別(ASR)。其關(guān)鍵技術(shù)包括選擇識別單元、語音端點(diǎn)檢測、特征參數(shù)提取、聲學(xué)模型及語音模型的建立。語音識別技術(shù)目前在桌面系統(tǒng)、智能手機(jī)、導(dǎo)航設(shè)備等嵌入式領(lǐng)域均有一定程度的應(yīng)用。其主要技術(shù)難題是識別系統(tǒng)的適應(yīng)性較差、受背景噪聲影響較大,未來的發(fā)展方向應(yīng)是無限詞匯量連續(xù)語音非特定人語音識別系統(tǒng)。
(1)信號處理及特征提取模塊
該模塊的主要任務(wù)是從輸入信號中提取特征,供聲學(xué)模型處理。同時,它一般也包括了一些信號處理技術(shù),以盡可能降低環(huán)境噪聲、信道、說話人等因素對特征造成的影響。
(2)統(tǒng)計(jì)聲學(xué)模型
典型系統(tǒng)多采用基于一階隱馬爾科夫模型進(jìn)行建模。
(3)發(fā)音詞典
發(fā)音詞典包含系統(tǒng)所能處理的詞匯集及其發(fā)音。發(fā)音詞典實(shí)際提供了聲學(xué)模型建模單元與語言模型建模單元間的映射。
(4)語言模型
語言模型對系統(tǒng)所針對的語言進(jìn)行建模。理論上,包括正則語言,上下文無關(guān)文法在內(nèi)的各種語言模型都可以作為語言模型,但目前各種系統(tǒng)普遍采用的還是基于統(tǒng)計(jì)的N元文法及其變體。
(5)解碼器
解碼器是語音識別系統(tǒng)的核心之一,其任務(wù)是對輸入的信號,根據(jù)聲學(xué)、語言模型及詞典,尋找能夠以最大概率輸出該信號的詞串,從數(shù)學(xué)角度可以更加清楚的了解上述模塊之間的關(guān)系。
當(dāng)今語音識別技術(shù)的主流算法,主要有基于動態(tài)時間規(guī)整(DTW)算法、基于非參數(shù)模型的矢量量化(VQ)方法、基于參數(shù)模型的隱馬爾可夫模型(HMM)的方法、基于人工神經(jīng)網(wǎng)絡(luò)(ANN)和支持向量機(jī)等語音識別方法。
對于語音識別技術(shù)實(shí)現(xiàn)的描述是相當(dāng)完整的,而且其可以作為語音識別技術(shù)在資源緊缺型嵌入式平臺實(shí)現(xiàn)的一個較好的參考。
語音識別技術(shù)介紹
1.應(yīng)用分類
(1)特定人與非特定人識別,特定人識別相對簡單,訓(xùn)練者的識別率高,但非訓(xùn)練者的識別率很低。而非特定人不受此影響,但實(shí)現(xiàn)復(fù)雜,識別率也相對低一些。
(2)語音識別與身份識別,前者提取各個命令者發(fā)出的語音的共性特征,而后者提取差異性特征。基于語音的身份識別主要應(yīng)用于門禁等安全領(lǐng)域。語音識別廣泛應(yīng)用于詞語識別,工業(yè)控制等領(lǐng)域。
(3)連續(xù)與非連續(xù)(孤立詞)語音識別,很明顯,連續(xù)語音識別難度較大。嵌入式產(chǎn)品集中在孤立詞語音識別方面。
(4)小詞匯量和大詞匯量語音識別。兩者選擇的方法是不一樣的,會在識別率和識別速度上折中考慮。
(5)關(guān)鍵詞識別,如在一段語音中抽取帶有某個關(guān)鍵詞的句子,或者根據(jù)哼的曲子旋律去搜索對應(yīng)的歌曲等等。
本系統(tǒng)受限80251的計(jì)算和存儲性能,主要實(shí)現(xiàn)基于特定人的孤立詞語音識別。
2. 實(shí)現(xiàn)原理
語音識別主要包括:預(yù)處理、特征提取、訓(xùn)練和識別四個部分。
預(yù)處理主要包括去噪、預(yù)加重(去除口鼻輻射)、端點(diǎn)檢測(檢測有效語音段)等過程。
特征提取是對經(jīng)過預(yù)處理后的語音信號進(jìn)行特征參數(shù)分析。該過程就是從原始語音信號中抽取出能夠反映語音本質(zhì)的特征參數(shù),形成特征矢量序列。主要的特征參數(shù)包括:線性預(yù)測編碼參數(shù)(LPC)、線性預(yù)測倒譜參數(shù)(LPCC)、MEL倒譜參數(shù)(MFCC)等。
語音模式庫:即聲學(xué)參數(shù)模板,它是用聚類分析等方法,從一個講話者或多個講話者多次重復(fù)的語音參數(shù)中經(jīng)過長時間訓(xùn)練得到的。
語音模式匹配:將輸入語音的特征參數(shù)同訓(xùn)練得到的語音模式庫進(jìn)行比較分析,從而得到識別結(jié)果。常用的方法包括:動態(tài)時間規(guī)整(DTW)、神經(jīng)網(wǎng)絡(luò)(ANN)、隱馬爾科夫(HMM)等。DTW比較簡單實(shí)用,適用于孤立詞語音識別。HMM比較復(fù)雜,適用于大詞匯量連續(xù)語音識別。
三、嵌入式語音識別難點(diǎn)
語音識別的關(guān)鍵是識別率的高低。PC語音識別的識別率主要受限于系統(tǒng)選擇的方法,如端點(diǎn)檢測的精確度、特征參數(shù)的有效性、模式匹配方法的有效性等。而嵌入式的語音識別不僅受選擇方法的影響,而且受算法運(yùn)算精度的影響。PC機(jī)主要采用浮點(diǎn)數(shù),而嵌入式主要是采用定點(diǎn)算法,因此運(yùn)算精度、誤差控制非常重要。語音識別算法包括多個模塊,多個算法運(yùn)算過程,累積誤差對結(jié)果的影響是致命的。所以在算法設(shè)計(jì)過程中必須要仔細(xì)考慮定點(diǎn)數(shù)值的精度,既要盡量提高精度,又要防止運(yùn)算結(jié)果溢出。
嵌入式語音識別還需要考慮識別速度。PC機(jī)運(yùn)行速度比較快,中等詞匯量語音識別的用戶體驗(yàn)還是蠻好的。但在嵌入式語音識別中,詞匯量的大小對用戶體驗(yàn)的影響是相當(dāng)嚴(yán)重的。即使識別率高,但識別速度很慢,那這個產(chǎn)品很難推廣。所以嵌入式語音識別需要在識別率和識別速度上折中考慮。識別速度不僅受限于選取算法的運(yùn)算復(fù)雜度,還受嵌入式硬件的影響,如數(shù)據(jù)空間大小。如果數(shù)據(jù)RAM空間不夠大,那就需要以其他介質(zhì)(如FLASH/CARD)作為緩存。后續(xù)處理頻繁范圍該介質(zhì)將會嚴(yán)重影響識別速度。所以識別速度也受限于硬件條件。
四、80251平臺語音識別的硬件條件及其考慮
1. 80251平臺語音識別的硬件條件
這里我們假定SOC集成了251內(nèi)核,而其能實(shí)現(xiàn)錄音的功能,這是語音識別的最基本要求。語音識別的硬件條件就是系統(tǒng)分配給錄音應(yīng)用的所有資源。
錄音應(yīng)用的資源一般包括:
1) audio buffer(512字節(jié)),其主要是作為audio錄音時采樣處理后的數(shù)據(jù)緩存,即采樣后audio會把512字節(jié)錄音數(shù)據(jù)放到該BUFFER,應(yīng)用再調(diào)用文件系統(tǒng)寫接口把該BUFFER數(shù)據(jù)寫到FLASH。
2) EDATA變量數(shù)據(jù)空間(1024字節(jié)),其主要是錄音應(yīng)用和中間件模塊的變量數(shù)據(jù)空間。錄音應(yīng)用和中間件已經(jīng)用掉622字節(jié),剩下402字節(jié)。
3) PCMRAM(12K字節(jié)), 其主要是用于錄音時的數(shù)據(jù)采樣處理。
4) 代碼空間(9K字節(jié)),錄音應(yīng)用和中間件代碼運(yùn)行空間。
2. 80251平臺語音識別可用資源
在80251平臺上實(shí)現(xiàn)語音識別就需要在錄音應(yīng)用基礎(chǔ)上增加語音識別功能,因此語音識別需要與錄音應(yīng)用共享以上資源。語音識別分預(yù)處理、特征提取、訓(xùn)練和匹配識別四個子過程,四個子過程在運(yùn)行的時間上是不重復(fù)的。以下根據(jù)各個子過程的運(yùn)行時間考慮以上資源的復(fù)用性??紤]到80251采用硬件BANK機(jī)制,所以語音識別的代碼空間不受影響。因此著重考慮數(shù)據(jù)空間的復(fù)用性。另外,語音識別一般是對PCM數(shù)據(jù)進(jìn)行處理,80251的PCM數(shù)據(jù)的量化比特?cái)?shù)為16BIT,即2個字節(jié)。人的有效語音頻率在4KHZ以下,所以采用率選擇8KHZ,滿足奈奎斯特采樣定理。
預(yù)處理的預(yù)加重比較簡單,是一個低通濾波器,不需占用額外的數(shù)據(jù)空間。對于去噪,本系統(tǒng)暫時不予考慮。預(yù)處理主要的部分在于語音端點(diǎn)檢測,即去除靜音段,保留有效語音段。類似于錄音中的聲控錄音,但語音識別的語音端點(diǎn)檢測比聲控錄音更加復(fù)雜,也要求更加精確。本系統(tǒng)采用實(shí)時在線的端點(diǎn)檢測算法,因此在端點(diǎn)檢測過程(即在偵聽命令的錄音過程)需要實(shí)時地對audio buffer的數(shù)據(jù)進(jìn)行處理,檢測是否為有效語音。在這個過程,audio buffer和PCMRAM都是不可使用的。能夠使用的就是402字節(jié)的EDATA空間。由于語音識別各個過程都要進(jìn)行分幀處理(后續(xù)再講),本系統(tǒng)設(shè)定每幀128點(diǎn),因此需要申請一個256字節(jié)的幀處理BUFFER。剩下402-256 = 146字節(jié)作為語音識別的變量數(shù)據(jù)空間。
在端點(diǎn)檢測過程中,根據(jù)當(dāng)前幀的短時能量或者過零率確認(rèn)語音開始時,對該幀數(shù)據(jù)的處理有兩種,一是將當(dāng)前512字節(jié)數(shù)據(jù)(一個扇區(qū))COPY到一段語音BUFFER,另一種是調(diào)用文件系統(tǒng)寫接口寫到FLASH中。對于前者,其速度肯定優(yōu)于后者,因?yàn)槠洳恍枰谔幚淼倪^程中調(diào)用文件系統(tǒng)接口。還有,突然的脈沖噪聲也會讓系統(tǒng)誤認(rèn)為語音的開始,所以在確認(rèn)噪聲后又需重新開始檢查。如果有一塊大的語音BUFFER,語音識別的性能將會大幅提高。一般認(rèn)為一個人說出的孤立詞語音持續(xù)時間在2秒以內(nèi),即2×8000×2 ≈ 32K字節(jié)。但80251平臺明顯沒有這個資源。所以選擇了將當(dāng)前扇區(qū)數(shù)據(jù)寫入文件,即用FLASH作為語音BUFFER使用。另外,80251文件有個缺陷,寫操作不能調(diào)用FSEEK。這樣會帶來端點(diǎn)檢測速度的下降。如前所講,脈沖噪聲會滿足語音開始的條件,因此脈沖噪聲起始點(diǎn)之后的一段聲音數(shù)據(jù)都會寫入到FLASH文件中,檢測算法后來發(fā)現(xiàn)前面是脈沖噪聲會將之前的數(shù)據(jù)沖掉,沖頭再寫。如果能調(diào)用FSEEK,那一條語句就完成。但因?yàn)樵撊毕?,因此需要調(diào)用FSCLOSE關(guān)閉文件,再調(diào)用FS_REMOVE刪除文件,接著調(diào)用FS_CREATE重新創(chuàng)建一個文件。
語音識別后面的3個子過程運(yùn)行在非錄音時態(tài),因此可以利用audio buffer和PCMRAM。由于后續(xù)的處理過程都需要從FLASH的文件中讀取數(shù)據(jù)來處理,每次一個扇區(qū),所以用audio buffer作為緩沖。因此語音識別的后續(xù)過程可采用的數(shù)據(jù)空間即是12K字節(jié)的PCMRAM。
語音識別的特征提取過程主要需要一個緩沖特征參數(shù)的BUFFER。其他需要申請的BUFFER都可以放到FAR DATA空間(即代碼空間當(dāng)數(shù)據(jù)用,但只允許當(dāng)前BANK代碼能夠使用)。如果在對語音分幀進(jìn)行特征提取并立刻寫數(shù)據(jù)到FLASH特征文件,那也不需要緩沖特征參數(shù)的BUFFER,但目前80251平臺的文件系統(tǒng)暫不支持一邊讀一邊寫,所以必須給特征參數(shù)分配緩存BUFFER,等每個語音命令處理后再一起寫進(jìn)FLASH特征文件。以一個命令語音最長2秒計(jì),幀移為64點(diǎn),則共有2×8000/64 = 250幀,而每幀數(shù)據(jù)的LPC特征參數(shù)個數(shù)選16(即算法選16階LPC,每個參數(shù)2個字節(jié)),因此共需250×16×2 = 8000字節(jié)??紤]到在做模式匹配識別時需要緩沖模塊庫的一個參考詞條的特征參數(shù)和待識別詞條的特征參數(shù),2個8000字節(jié)將超過12K的PCMRAM。所以特征參數(shù)的緩沖BUFFER最多只能分配6K。有兩個選擇,一是特征參數(shù)個數(shù)選16,那最大的有效語音持續(xù)時間為:6×1024/(2×16×(8000/64) = 1.536秒。正常一個人說一個命令的時間約束是可以滿足在1.5秒以內(nèi)的。另一個辦法是縮小每幀數(shù)據(jù)的LPC參數(shù)個數(shù),一般語音識別選12階,本程序?yàn)榱颂幚砀欤x的是16階。如果選8階那會更快,但精度下降。
語音識別的模式匹配過程主要是需要以上講述的兩個緩沖特征參數(shù)的BUFFER。由于采用DTW算法,因此算法涉及的中間緩存都分配在FAR DATA空間。
綜上所述,80251平臺能夠在速度受限的情況下實(shí)現(xiàn)語音識別功能。
五、語音識別算法設(shè)計(jì)
六、PC端語音識別算法設(shè)計(jì)
任何一個移植到嵌入式平臺的算法都應(yīng)該在PC環(huán)境上調(diào)試驗(yàn)證通過后再進(jìn)行移植,而為了移植的高效,PC環(huán)境的算法設(shè)計(jì)應(yīng)該建立在熟悉目標(biāo)平臺的硬件結(jié)構(gòu)和編譯集成環(huán)境的基礎(chǔ)上。盡可能深刻地熟悉兩者,將為后面的移植帶來極大的好處,否則事倍功半。
1.模擬80251錄音過程進(jìn)行端點(diǎn)檢測
PC機(jī)用讀文件的形式模擬80251錄音的過程,詳細(xì)的端點(diǎn)檢測過程如下圖:
為了數(shù)據(jù)的一致性,PC機(jī)調(diào)試的文件都是80251錄出來的錄音文件(8K,PCM,16BIT,單聲道)。另外,因?yàn)?0251是分BANK處理語音識別的四個子過程,為了讓各個模塊去耦合,在WAV文件頭的一些保留區(qū)寫入語音端點(diǎn)檢測的有效幀數(shù)。這樣參數(shù)提取過程就可以從文件中直接讀出該參數(shù)并進(jìn)行處理。
80251錄音結(jié)束時會自動準(zhǔn)備好文件頭所屬的一個扇區(qū)數(shù)據(jù),而這個文件頭是包括直接的靜音段,所以最后寫入文件頭時需要對文件頭的一些參數(shù)(如文件長度)進(jìn)行修改再寫入。
其實(shí),語音數(shù)據(jù)完全可以作為一個單獨(dú)的二進(jìn)制文件存在,并不需要文件頭信息。但為了調(diào)試的有效性,仍然寫入正確的文件頭,這樣語音端點(diǎn)檢測結(jié)果仍然是一個WAV文件,通過聽這個WAV文件就知道算法是否有效。
算法的結(jié)果如果能夠圖形化那會比較直觀,所以借助了MATLAB工具進(jìn)行畫圖,以輔助調(diào)試,加快調(diào)試進(jìn)度。
2.數(shù)據(jù)處理精度
80251平臺的PCM數(shù)據(jù)為16比特量化,但事實(shí)上語音處理時采用8比特量化就足夠了。因此對錄音數(shù)據(jù)的處理都是取高8位。這樣減少了一半的運(yùn)算量,也防止計(jì)算溢出。
雖然采用高8位數(shù)據(jù)進(jìn)行處理,但為了程序的整體運(yùn)算平滑過渡,仍然用一個16位有符號短整型去表述每一個采樣點(diǎn)。VC為short int,80251為signed int。其獲取的特征參數(shù)也選用16位有符號短整型去表述。而在運(yùn)算過程有時會采用32位有符號整型以提高運(yùn)算精度。
3.類型移植
如上節(jié)所講,為了方便移植,必須讓VC中程序的變量和KEIL代碼的變量的類型一致。因此在VC中需要重定義一份KEIL環(huán)境的typeext.h文件。如:
#define int16signed short int
#define int32signed int
等等。
這樣VC的主要算法可以不做任何改動就可以放入KEIL環(huán)境進(jìn)行編譯調(diào)試。
4.浮點(diǎn)算法定點(diǎn)化
這是語音識別的最關(guān)鍵部分。如果在浮點(diǎn)算法定點(diǎn)化的過程中控制好累積誤差,是本系統(tǒng)最關(guān)鍵的問題。第四部分所闡述的算法都是浮點(diǎn)算法。PC上語音識別的識別率很高很大程度一部分原因是因?yàn)槠溥x擇復(fù)雜的算法,另一部分原因是因?yàn)樗褂酶↑c(diǎn)數(shù),較好地控制了累積誤差。其所有的參數(shù)均通過歸一化使得運(yùn)算都在-1到1之間進(jìn)行。
浮點(diǎn)庫對于嵌入式平臺是一個極大的負(fù)擔(dān),而且運(yùn)算速度很慢。所以嵌入式產(chǎn)品的關(guān)鍵也在于浮點(diǎn)算法定點(diǎn)化過程中如何更好地控制誤差。控制誤差的一個很有效的方法就是提高數(shù)據(jù)運(yùn)算精度,但是一味地提高運(yùn)算精度會導(dǎo)致運(yùn)算溢出,所以必須在兩者之間折中考慮,以獲得一個平衡。
調(diào)試此部分功能時曾遇到一個很大的困難就是求取LPC參數(shù)時的對E的處理,因?yàn)槠湓谘h(huán)過程中曾被作為除數(shù)進(jìn)行處理,如果在循環(huán)的過程中沒做好誤差控制,那其就會在某次運(yùn)算過程中為0,所以造成結(jié)果溢出。調(diào)試過程還算比較艱辛,曾經(jīng)讓自己想起要不用浮點(diǎn)庫試試。但最后還是堅(jiān)持下來用定點(diǎn)算法繼續(xù)調(diào)試。
針對本系統(tǒng)的算法,浮點(diǎn)算法定點(diǎn)化過程主要做了以下幾個方面的考慮。
1. 如5.2節(jié)所講,錄音數(shù)據(jù)采用高8位進(jìn)行處理。
2. LPC算法的自相關(guān)系統(tǒng)進(jìn)行歸一化處理,取12比特有效數(shù)據(jù),即R(0) = 4096。而且在運(yùn)算過程中若發(fā)現(xiàn)累積和大于0x7fff時就進(jìn)行相應(yīng)移位,保證累積和在0x7fff以內(nèi)。因?yàn)樗凶韵嚓P(guān)系統(tǒng)同時除以一個值,對后面的結(jié)果沒有影響。
3. LPC算法的E取32位有符號數(shù),算法運(yùn)算的中間變量也取32位。
4. LPC算的a,k等參數(shù)取12位有效數(shù)值,即在4096以內(nèi)。
5. LPC算法中的除法精度到0.5以內(nèi),即考慮余數(shù)與除數(shù)的關(guān)系。
6. DTW算法運(yùn)算使用32位運(yùn)算精度。
浮點(diǎn)算法定點(diǎn)化調(diào)試的一個好的經(jīng)驗(yàn)時在VC中用兩個工程分別實(shí)現(xiàn)浮點(diǎn)算法和定點(diǎn)算法,然后跟蹤每一步的運(yùn)算結(jié)果。發(fā)現(xiàn)誤差過大就及時修改調(diào)整。
5.速度優(yōu)化
算法設(shè)計(jì)時考慮到80251的乘除運(yùn)算能力有限,所以盡肯能地采用移位,查表操作,以提高運(yùn)算速度。舉例如下:
1. 預(yù)加重等過程需要乘以0.9375,就先乘120,再右移7位,即除以128。
2. 窗化處理時如果按公式調(diào)用cos等數(shù)學(xué)函數(shù),那代碼量的增長和運(yùn)算速度的影響都是致命的。在這里使用查表的方式進(jìn)行處理。即在MATLAB中用hamming(128)得到127點(diǎn)信號點(diǎn),由于該信號點(diǎn)是-1到1的小數(shù),所以再將其放大1024倍,將這些數(shù)值保存到一張表中(使用FAR DATA空間),代碼運(yùn)算時先分別相乘,再右移10位就可以了。所以這里巧妙地避免了除法操作。
七、 80251平臺語音識別實(shí)現(xiàn)
1.算法移植
由于PC端的算法已經(jīng)盡可能地考慮了80251的錄音過程和KEIL C環(huán)境約束,所以算法移植還算比較順利,尤其是語音端點(diǎn)檢測部分。幾乎不做任何算法改動就實(shí)現(xiàn)了該部分功能。當(dāng)然錄音應(yīng)用是需要進(jìn)行調(diào)整的。主要的改動主要是UI控制和顯示,以及中間件錄音流程的修改。即在之前的寫入操作前加入調(diào)用wav_vad函數(shù)進(jìn)行端點(diǎn)檢測,確定語音開始才寫進(jìn)FLASH錄音文件。
對于特征提取、訓(xùn)練識別部分的調(diào)整,主要是分配好代碼運(yùn)行空間和FAR DATA空間。DTW算法運(yùn)算過程中的中間變量近1k字節(jié),但由于只有該部分使用,所以都分配在FAR DATA空間。
2. VC和KEIL C的比較
調(diào)試過程中還是發(fā)現(xiàn)了VC和KEIL C編譯器有不一致的地方。但由于比較隱藏,所以發(fā)現(xiàn)這部分特性也花費(fèi)了不少時間。列舉幾點(diǎn):
1. int32 m = (int32)(int16 val1* int16 val2);VC會自動把32位的相乘結(jié)果賦給m,而KEIL C是將32位相乘結(jié)果的高16位清零再付給m。這個好像挺奇怪的,但事實(shí)就是這樣。只有把前面的強(qiáng)制類型轉(zhuǎn)換去掉才正確。所以有時強(qiáng)制類型轉(zhuǎn)換也未必是好事。
2. VC中用到的一部分BUFFER會自動初始化為0,而KEIL C中不會。所以LPC算法運(yùn)算結(jié)果出現(xiàn)偏差。因?yàn)樾C(jī)和PC的識別率差別很大,所以只好用同一個文件在小機(jī)上和PC機(jī)上同時調(diào)試,以跟蹤每一步結(jié)果,最終才發(fā)現(xiàn)這個問題。其實(shí)是編程習(xí)慣不夠好,一般在使用某段BUFFER前都應(yīng)該先清零才行。
3. VC中的short int左移會向32位擴(kuò)展,而KEIL C左移時其數(shù)值范圍并沒有加大,即丟棄超過16位的數(shù)值,沒能真正實(shí)現(xiàn)左移相乘的目的。
八、 80251平臺語音識別結(jié)果及其分析
80251平臺語音識別的識別率可以控制在93%以上(詞匯量在50以下,憑經(jīng)驗(yàn)),50以上還沒測試過。