PaddleSpeech提供了MDTC模型(paper: The NPU System for the 2020 Personalized Voice Trigger Challenge)在Hey Snips數(shù)據(jù)集上的語音喚醒(KWS)的實現(xiàn)。這篇論文是用空洞時間卷積網(wǎng)絡(luò)(dilated temporal convolution network, DTCN)的方法來做的,曾獲the 2020 personalized voice trigger challenge (PVTC2020)的第二名,可見這個方案是比較優(yōu)秀的。想看看到底是怎么做的,于是我對其做了一番初探。
1,模型理解
論文是用空洞時間卷積網(wǎng)絡(luò)(DTCN)的方法來實現(xiàn)的。為了減少參數(shù)量,用了depthwise & pointwise 一維卷積。一維卷積以及BatchNormal、relu等組成1個DTCNBlock, 4個DTCNBlock組成一個DTCNStack。實現(xiàn)的模型跟論文里的有一些差異。論文里的模型具體見論文,實現(xiàn)的模型框圖見下圖:

模型有PreProcess、DTCNStack(3個, DTCN:空洞時間卷積網(wǎng)絡(luò))、FCN(全連接網(wǎng)絡(luò))、sigmoid這些模塊。PreProcess是做前處理,主要是由3個一維卷積(1個depthwise和兩個pointwise)組成。每個DTCNStack由4個DTCNBlock組成,DTCNBlock跟preprocess模塊相似,唯一的區(qū)別是多了殘差模塊(圖中畫紅線的)。
這個模型的參數(shù)個數(shù)不到37K,見下圖:

參數(shù)個數(shù)是比較少的,相對論文里的也少了不少。剛開始我不太相信,后來我對網(wǎng)絡(luò)中的模型每層都算了參數(shù)個數(shù),的確是這么多。想了一下,對比paper里的模型,參數(shù)變少主要有兩點:一是少了一些模塊,二是FCN由linear替代(linear替代FCN會少不少參數(shù))。
模型用的特征是80維的mel-filter bank,即每幀的特征是一個80維的數(shù)據(jù)。把一個utterance的這些幀的特征作為模型的輸入,輸出是每一幀的后驗概率,如果有一幀的后驗概率大于threshold,就認(rèn)為這一utterance是關(guān)鍵詞,從而喚醒設(shè)備。舉例來說,一個utterance有158幀,模型的輸入就是158*80的矩陣(158是幀數(shù),80是特征的維度),輸出是158*1的矩陣,即158個后驗概率。假設(shè)threshold設(shè)為0.8,這158個后驗概率中只要有一個達(dá)到0.8,這個utterance就認(rèn)為是關(guān)鍵詞。
2,環(huán)境搭建
PaddleSpeech相關(guān)的文檔里講了如何搭建環(huán)境(Ubuntu下的),這里簡述一下:
1)創(chuàng)建conda環(huán)境以及激活這個conda環(huán)境等:
conda create --name paddletry python=3.7
conda activate paddletry
2)安裝 paddelpaddle (paddlespeech 是基于paddelpaddle的)
pip install paddlepaddle
3)clone 以及編譯paddlespeech 代碼
git clone https://github.com/PaddlePaddle/PaddleSpeech.git
pip install .
3,數(shù)據(jù)集準(zhǔn)備
數(shù)據(jù)集用的是sonos公司的”hey snips”。我?guī)滋靸?nèi)用三個不同的郵箱去注冊申請,均沒給下載鏈接,難道是跟目前在科技領(lǐng)域緊張的中美關(guān)系有關(guān)?后來聯(lián)系到了這篇paper的作者, 他愿意分享數(shù)據(jù)集。在此謝謝他,真是個熱心人!他用百度網(wǎng)盤分享了兩次數(shù)據(jù)集,下載后均是tar包解壓出錯,估計是傳輸過程中出了問題。在走投無路的情況下嘗試去修復(fù)壞的tar包。找到了tar包修復(fù)工具gzrt,運氣不錯,能修復(fù)大部分,關(guān)鍵是定義train/dev/test集的json文件能修復(fù)出來。如果自己寫json文件太耗時耗力了。Json中一個wav文件數(shù)據(jù)格式大致如下:
{
"duration": 4.86,
"worker_id": "0007cc59899fa13a8e0af4ed4b8046c6",
"audio_file_path": "audio_files/41dac4fb-3e69-4fd0-a8fc-9590d30e84b4.wav",
"id": "41dac4fb-3e69-4fd0-a8fc-9590d30e84b4",
"is_hotword": 0
},
數(shù)據(jù)集中原有wav文件96396個,修復(fù)了81401個。寫python把在json中出現(xiàn)的但是audio_files目錄中沒有的去掉,形成新的json文件。原始的以及新的數(shù)據(jù)集中train/dev/test wav數(shù)如下:

從上表可以看出新的數(shù)據(jù)集在train/dev/test上基本都是原先的84%左右。
4,訓(xùn)練和評估
在PaddleSpeech/examples/hey_snips/kws0下做訓(xùn)練。訓(xùn)練前要把這個目錄下conf/mdtc.yaml里的數(shù)據(jù)集的路徑改成自己放數(shù)據(jù)集的地方。由于我用CPU訓(xùn)練,相應(yīng)的命令就是./run.sh conf/mdtc.yaml 。 訓(xùn)練50個epoch(默認(rèn)配置)后,在驗證集下的準(zhǔn)確率為99.79%(見下圖),還是不錯的,就沒再訓(xùn)練下去。

評估出的DET圖如下:

Paddlespeech也提供了KWS推理命令: paddlespeech kws。需要研究一下這個命令是怎么用的,看相關(guān)代碼。--input 后面既可以是一個具體的wav文件(這時只能評估一個文件),也可以是一個txt文件,把要評估的文件名都寫在里面,具體格式如下圖:

--ckpt_path是模型的路徑,--config是設(shè)置配置文件,也就是mdtc.yaml。因為要對整個測試集做評估,所以--input要寫成txt的形式。Hey Snips數(shù)據(jù)集wav文件都在audio_files目錄下,需要寫腳本把測試集的wav文件取出來放在一個目錄下(我的是heytest), 還要寫腳本把這次測試文件的文件名以及路徑寫到上圖所示的txt文件里。同時還要在paddlespeech 里加些代碼看推理出的值是否跟期望值一致,做些統(tǒng)計。把這些都弄好后就開始做運行了,具體命令如下圖:

最終測試集下的結(jié)果,見下圖:文章來源:http://www.zghlxwxcb.cn/news/detail-450493.html

共19442個文件,跟期望一致的(圖中correct的)是19410個,準(zhǔn)確率為99.84%。與驗證集下的大體相當(dāng)。文章來源地址http://www.zghlxwxcb.cn/news/detail-450493.html
到了這里,關(guān)于飛槳paddlespeech 語音喚醒初探的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!