如何三步搭建一套聲紋系統(tǒng)
背景介紹
聲紋檢索,顧名思義就是說(shuō)話人識(shí)別,通過(guò)聲音來(lái)驗(yàn)證或者識(shí)別說(shuō)話人的聲音。聲紋識(shí)別的關(guān)鍵步驟就是聲音向量化,將說(shuō)話人的聲音將其轉(zhuǎn)化成結(jié)構(gòu)化的向量。阿里云AnalyticDB向量版,提供了一套聲紋驗(yàn)證檢索的解決方案。用戶只需要使用簡(jiǎn)單的幾條SQL命令,三步之內(nèi)就可以搭建一套高精度的聲紋檢索驗(yàn)證服務(wù)。
聲紋識(shí)別技術(shù)
1)聲紋檢索演示
圖1展示了AnalyticDB向量數(shù)據(jù)庫(kù)的聲紋檢索系統(tǒng)的演示界面。為了方便用戶體驗(yàn),我們將380個(gè)人的聲音信息,轉(zhuǎn)化成向量存儲(chǔ)在系統(tǒng)中。當(dāng)前演示系統(tǒng)分成兩部分,第一部分是檢索部分,用戶輸入錄制好的聲音文件或者用戶現(xiàn)場(chǎng)進(jìn)行錄音上傳聲音文件,提交到聲紋庫(kù)進(jìn)行聲音的匹配檢索。第二部分是注冊(cè)部分,用戶可以注冊(cè)上傳自己的聲音到當(dāng)前的聲紋庫(kù)里面,方便后期的查詢驗(yàn)證。在接下來(lái)的章節(jié)中,我們分別介紹各個(gè)功能。
圖1. 聲紋演示系統(tǒng)
圖2上傳一段S0004的測(cè)試音頻“BAC009S0004W0486.wav”到聲紋庫(kù)里面進(jìn)行檢索,可以看到TOP1的結(jié)果S0004就會(huì)在最上面進(jìn)行展示。
圖2. 查詢聲音
圖3展示了聲紋注冊(cè)系統(tǒng),用戶可以注冊(cè)自己的聲音到后臺(tái)聲紋庫(kù)里面,方便檢索。比方說(shuō),用戶Hanchao注冊(cè)自己的聲音(只有7s長(zhǎng)度),到當(dāng)前的系統(tǒng)里面來(lái)。當(dāng)前系統(tǒng)支持無(wú)文本注冊(cè),用戶可以說(shuō)任何話來(lái)進(jìn)行注冊(cè)。
圖3. 注冊(cè)聲音
圖4演示用戶現(xiàn)場(chǎng)錄制聲音,上傳到系統(tǒng)中,進(jìn)行檢索。比方說(shuō),“Hanchao”錄制了一段5秒的語(yǔ)音到聲紋系統(tǒng)中進(jìn)行檢索。之前注冊(cè)過(guò)“Hanchao”的聲音,當(dāng)前系統(tǒng)可以看到排名第一的聲音就是“Hanchao”的聲音。
圖4. 錄制并檢索聲音
當(dāng)前對(duì)于聲紋演示,我們采用的是1:N的演示結(jié)果,可以用在會(huì)議室中的識(shí)別,通過(guò)聲音可以找到相關(guān)的會(huì)議說(shuō)話人。當(dāng)前,對(duì)于身份驗(yàn)證,這種1:1的演示,我們只用限制距離小于550,就可以方便的進(jìn)行身份驗(yàn)證。
2)應(yīng)用結(jié)構(gòu)總體設(shè)計(jì)
阿里云聲紋庫(kù)檢索的系統(tǒng)框架的總體架構(gòu)如圖5所示,AnalyticDB(聲紋庫(kù))負(fù)責(zé)整個(gè)聲紋檢索應(yīng)用的全部結(jié)構(gòu)化信息(用戶注冊(cè)標(biāo)識(shí),用戶姓名,以及其他的用戶信息)和非結(jié)構(gòu)化信息(聲音產(chǎn)生的向量)的存儲(chǔ)和查詢。在查詢的過(guò)程中,用戶通過(guò)聲紋抽取模型,將聲音轉(zhuǎn)成向量,在AnalyticDB中進(jìn)行查詢。系統(tǒng)返還回來(lái)相關(guān)的用戶信息,以及l(fā)2向量距離[5]。其中聲音抽取模型的訓(xùn)練和測(cè)試,我們?cè)谙乱徽逻M(jìn)行講解。
圖5. 聲紋檢索庫(kù)
3)系統(tǒng)精度
當(dāng)前演示聲紋系統(tǒng),采用的是GMM-UMB模型抽取的i-vector作為檢索向量[3]。另外,我們還訓(xùn)練了精度更高的深度學(xué)習(xí)聲紋識(shí)別模型(x-vector[4])。并且,可以針對(duì)特定的場(chǎng)景,比方說(shuō)電話通話場(chǎng)景,手機(jī)APP場(chǎng)景,嘈雜噪聲場(chǎng)景等相關(guān)的場(chǎng)景進(jìn)行聲紋模型訓(xùn)練,詳細(xì)信息可以加我們的群進(jìn)行了解。
聲紋識(shí)別在學(xué)術(shù)界常用的數(shù)據(jù)集(Aishall.v1 [1]數(shù)據(jù)集和TIMIT [2]數(shù)據(jù)集)上面的(1:N)的準(zhǔn)確率(>99.5%,見表1)。
表1. Top 1 精度測(cè)試結(jié)果
三步搭建一個(gè)聲紋系統(tǒng)
第一步,初始化。
當(dāng)前系統(tǒng)實(shí)現(xiàn)了聲音轉(zhuǎn)向量的函數(shù),用戶將前端得到的聲音通過(guò)POST請(qǐng)求,發(fā)給阿里云服務(wù)系統(tǒng),選擇對(duì)應(yīng)的聲紋模型,就可以將聲音轉(zhuǎn)成對(duì)應(yīng)的向量。
import requestsimport jsonimport numpy as np# sound: 聲音二進(jìn)制文件。# model_id:模型id。def get_vector(sound, model_id='i-vector'): url = 'http://47.111.21.183:18089/demo/vdb/v1/retrieve' d = {'resource': sound, 'model_id': model_id} r = requests.post(url, data=d) js = json.loads(r.text) return np.array(js['emb'])# 讀取用戶文件。file = 'xxx.wav'data = f.read()print(get_vector(data))f.close()
在初始化的過(guò)程中,用戶創(chuàng)建相關(guān)的用戶聲紋表。同時(shí),給表的向量列加入向量索引,來(lái)加速查詢過(guò)程。當(dāng)前聲紋模型輸出的都是400維的向量,所以索引參數(shù)dim設(shè)置為400。
--創(chuàng)建用戶聲紋表CREATE TABLE person_voiceprint_detection_table( id serial primary key, name varchar, voiceprint_feature float4[]);--創(chuàng)建向量索引CREATE INDEX person_voiceprint_detection_table_idx ON person_voiceprint_detection_table USING ann(voiceprint_feature) WITH(distancemeasure=L2,dim=400,pq_segments=40);
第二步,注冊(cè)用戶聲音。
在注冊(cè)的過(guò)程中,注冊(cè)一個(gè)用戶,插入一條記錄到當(dāng)前系統(tǒng)中。
--注冊(cè)用戶'張三'到當(dāng)前的系統(tǒng)中。--通過(guò)HTTP服務(wù),將聲紋轉(zhuǎn)化成相關(guān)的向量。INSERT INTO person_voiceprint_detection_table(name, voiceprint_feature)SELECT '張三', array[-0.017,-0.032,...]::float4[])
第三步,檢索或驗(yàn)證用戶聲音。
聲紋門鎖驗(yàn)證(1:1 驗(yàn)證):在驗(yàn)證系統(tǒng)中,系統(tǒng)會(huì)得到用戶的標(biāo)識(shí)信息(user_id),在聲紋庫(kù)中計(jì)算輸入的聲音向量和庫(kù)里該用戶的聲音向量的距離。一般系統(tǒng)會(huì)設(shè)置一個(gè)距離閾值(threshold=550),如果向量之間的距離大于這個(gè)閾值,說(shuō)明驗(yàn)證失敗。如果小于閾值,說(shuō)明聲紋驗(yàn)證成功。
-- 聲紋門鎖檢測(cè)(1:1)驗(yàn)證SELECT id, -- 用戶id信息 name, -- 用戶姓名 l2_distance(voiceprint_feature, ARRAY[-0.017,-0.032,...]::float4[]) AS distance -- 向量距離 FROM person_voiceprint_detection_table -- 用戶聲音表WHERE distance < threshold -- 通常情況下,threshold為550 AND id = 'user_id' -- 用戶要驗(yàn)證的id;
會(huì)議聲紋檢索(1:N 檢測(cè)):系統(tǒng)通過(guò)識(shí)別當(dāng)前講話人的聲音,會(huì)返回最相關(guān)的注冊(cè)用戶信息。如果沒有返回結(jié)果,說(shuō)明當(dāng)前會(huì)議說(shuō)話人不在聲紋庫(kù)里面。
-- 聲紋會(huì)議人員識(shí)別(1:N)驗(yàn)證SELECT id, -- 用戶id信息 name, -- 用戶姓名 l2_distance(voiceprint_feature, ARRAY[-0.017,-0.032,...]::float4[]) AS distance -- 向量距離 FROM person_voiceprint_detection_table -- 用戶聲音表WHERE distance < threshold -- 通常情況下,threshold為550 ORDER BY voiceprint_feature <-> ARRAY[-0.017,-0.032,...]::float4[] -- 利用向量進(jìn)行排序LIMIT 1; -- 返回最相似的結(jié)果