蒙面唱將是小猿最近在看的一檔音樂節目,歌手帶著面具唱歌,讓大家更關注他們的聲音而忘記他們的面容,撇開節目創意不談,小猿更注意的是機器人小V。它每次出現的意義是利用內置的聲紋匹配功能,向幾位評委提供可能的歌手名單,雖然那英出現的次數太多,但是當它說出“馴鹿”有可能是周慧時,從巫啟賢的反應依然能看出小V的能力還是不容小覷的。作為程序猿,小猿當然對這種聲紋匹配功能更加感興趣了,于是就簡單的研究了一下這種相當成熟的人工智能技術。
首先聲紋(Voiceprint),是用電聲學儀器顯示的攜帶言語信息的聲波頻譜。人類語言的產生是人體語言中樞與發音器官之間一個復雜的生理物理過程,人在講話時使用的發聲器官--舌、牙齒、喉頭、肺、鼻腔在尺寸和形態方面每個人的差異很大,所以任何兩個人的聲紋圖譜都有差異。每個人的語音聲學特征既有相對穩定性,又有變異性,不是絕對的、一成不變的。這種變異可來自生理、病理、心理、模擬、偽裝,也與環境干擾有關。盡管如此,由于每個人的發音器官都不盡相同,因此在一般情況下,人們仍能區別不同的人的聲音或判斷是否是同一人的聲音。
而所謂聲紋識別(Voiceprint Recognition, VPR),屬于生物識別技術的一種,也稱為說話人識別,其有兩類,即說話人辨認和說話人確認。不同的任務和應用會使用不同的聲紋識別技術,如縮小歌手范圍時可能需要辨認技術,而銀行交易時則需要確認技術。前者用以判斷某段語音是若干人中的哪一個所說的,是“多選一”問題;而后者用以確認某段語音是否是指定的某個人所說的,是“一對一判別”問題。不管是辨認還是確認,都需要先對說話人的聲紋進行建模,這就是所謂的“訓練”或“學習”過程。
在說話人辨認方面,根據待識別的說話人是否在注冊的說話人集合內,說話人辨認可以分為開集(open-set)辨認和閉集(close-set)辨認。前者假定待識別說話人可以在集合外,而后者假定待識別說話人在集合內。顯然,開集辨認需要有一個對集外說話人的“拒識問題”,而且閉集辨認的結果要好于開集辨認結果。比如小V在蒙面唱將中使用的方法就是說話人辨認,它內置了很多的唱片集合,通過辨認歌手的聲紋是否在唱片集合中來判斷歌手的身份。
聲紋識別可以說有兩個關鍵問題,一是特征提取,二是模式匹配(模式識別)。
聲紋識別的特征必須是“個性化”特征,而說話人識別的特征對說話人來講必須是“共性特征”。雖然目前大部分聲紋識別系統用的都是聲學層面的特征,但是表征一個人特點的特征應該是多層面的,包括:(1)與人類的發音機制的解剖學結構有關的聲學特征(如頻譜、倒頻譜、共振峰、基音、反射系數等等)、鼻音、帶深呼吸音、沙啞音、笑聲等;(2)受社會經濟狀況、受教育水平、出生地等影響的語義、修辭、發音、言語習慣等;(3)個人特點或受父母影響的韻律、節奏、速度、語調、音量等特征。從利用數學方法可以建模的角度出發,聲紋自動識別模型目前可以使用的特征包括:(1)聲學特征(倒頻譜);(2)詞法特征(說話人相關的詞n-gram,音素n-gram);(3)韻律特征(利用n-gram描述的基音和能量“姿勢”);(4)語種、方言和口音信息;(5)通道信息(使用何種通道);等等。
對于模式識別,有以下幾大類方法:
(1)模板匹配方法:利用動態時間彎折(DTW)以對準訓練和測試特征序列,主要用于固定詞組的應用(通常為文本相關任務);
(2)最近鄰方法:訓練時保留所有特征矢量,識別時對每個矢量都找到訓練矢量中最近的K個,據此進行識別,通常模型存儲和相似計算的量都很大;
(3)神經網絡方法:有很多種形式,如多層感知、徑向基函數(RBF)等,可以顯式訓練以區分說話人和其背景說話人,其訓練量很大,且模型的可推廣性不好;
(4)隱式馬爾可夫模型(HMM)方法:通常使用單狀態的HMM,或高斯混合模型(GMM),是比較流行的方法,效果比較好;
(5)VQ聚類方法(如LBG):效果比較好,算法復雜度也不高,和HMM方法配合起來更可以收到更好的效果;
(6)多項式分類器方法:有較高的精度,但模型存儲和計算量都比較大;
聲紋識別的應用有一些缺點,比如同一個人的聲音具有易變性,易受身體狀況、年齡、情緒等的影響;比如不同的麥克風和信道對識別性能有影響;比如環境噪音對識別有干擾;又比如混合說話人的情形下人的聲紋特征不易提取等等。盡管如此,與其他生物特征相比,聲紋識別的應用有一些特殊的優勢,使得聲紋識別的應用越來越收到系統開發者和用戶親睞,聲紋識別的世界市場占有率15.8%,僅次于手指和手的生物特征識別,并有不斷上升的趨勢。而一向以發燒自稱的小米也在自己的小米5s首次使用了超聲波聲紋識別。
聲紋識別的原理大概了解到這,作為程序猿我們還是習慣來點代碼,下面就介紹1個在聲紋識別方面比較優秀的開源框架:VoicePrint 是一款基于高斯混合模型的文本無關的聲紋識別算法驗證程序,源碼地址如下:https://github.com/dake/openVP