基於HTK的連續語音識別系統搭建學習筆記(四)

3.創建綁定狀態的三音素HMM模型

目的是加入上下文依賴(context-dependent)三音素模型並得到穩健的訓練。包括兩步,先由單音素得到三音素並重估參數,第二步就是綁定三音素的狀態以使輸出更加穩健。

[step 9]得到三音素HMM

上下文依賴三音素模型可以用單音素作爲初始,再進行重估。由於重估時要三音素級標註文本,就先生成標註文本。

創建文件:mktri.led

創建位置:根目錄

文件內容:


生成文件:wintri.mlf(由單音素標註文本文件aligned.mlf 轉換成的等價三音素標註文本)triphones1(一個三音素的列表)

生成位置:lists labels

執行:

HLEd -n .\lists\triphones1 -l * -i .\labels\wintri.mlf mktri.led .\labels\aligned.mlf

下面利用HMM 編輯器初始化三音素模型。

執行:

perl .\scripts\maketrihed .\lists\monophones1 .\lists\triphones1

生成文件:mktri.hed

生成位置:根目錄

注:修改mktri.hed 文件,把第一行的.\lists\triphones1 改成./lists/triphones1 

執行:

HHEd -H .\hmms\hmm9\macros -H .\hmms\hmm9\hmmdefs -M .\hmms\hmm10 mktri.hed .\lists\monophones1 

運行HHEd 得到如下警告,沒有大礙的:


重估兩次:

HERest -C .\config\config1 -I .\labels\wintri.mlf -t 250.0 150.0 1000.0 -S train.scp -H .\hmms\hmm10\macros -H .\hmms\hmm10\hmmdefs -M .\hmms\hmm11 .\lists\triphones1 
HERest -C .\config\config1 -I .\labels\wintri.mlf -t 250.0 150.0 1000.0 -s stats -S train.scp -H .\hmms\hmm11\macros -H .\hmms\hmm11\hmmdefs -M .\hmms\hmm12 .\lists\triphones1 

兩次均會有如下警告,不用理會:


試着執行一下識別任務,看看如何: 

HVite -H .\hmms\hmm12\macros -H .\hmms\hmm12\hmmdefs -S test.scp -l * -i recout_step9.mlf -w wdnet -p 0.0 -s 5.0 .\dict\dict2 .\lists\triphones1 

這時會報錯:


通過分析將dict2中SUE的第二種發音註釋掉就可以了

再運行:

新錯誤:


然後分析之後把FOUR的第二種發音註釋掉

將dict2改成dict4

執行:

HVite -H .\hmms\hmm12\macros -H .\hmms\hmm12\hmmdefs -S test.scp -l * -i .\results\recout_step9.mlf -w wdnet -p 0.0 -s 5.0 .\dict\dict4 .\lists\triphones1

進行識別驗證: 

執行:
HResults -I .\labels\testwords.mlf .\lists\monophones1 .\results\recout_step9.mlf 
所得結果如下: 


可以看出,基於三音素的HMM 比基於單音素的 HMM 有較大的性能提升。 
我們進一步進行討論dict4 的由來。由於在 step 8 中對標記文本和語音數據進行了校準,對於象FOUR ,SUE 這樣有多個發音的單詞,在 Vitebi 算法的作用下,會選擇最大化似然率的單詞,而不是象step 4 那樣選擇第一種讀音。結果使 dict2 中的發音在擴展成三音素時在音素級真值文本中沒有實例,當然也就找不到該三音素的 HMM 模型。這時會報錯。根據這個原理,可以編一個Perl 腳本自動對字典中沒用到的單詞註釋掉。我把這個腳本命名爲
makedict.pl,包含在 scripts 文件夾裏。它可以代替上面的手工註釋工作,使用下面的命令可以得到dict4: 
perl .\scripts\makedict.pl .\dict\dict2 .\dict\dict4 .\lists\triphones1

[step 10]綁定三音素

在上一步估計模型時,因數據不足導致很多分佈的方差只好用截至方差vFloors。這一步就是通過綁定狀態來共享數據,使輸出分佈更加的穩健。HHEd 提供兩種聚類狀態的機制,這裏採用的是決策樹: 

執行:

perl .\scripts\mkclscript.prl TB350.0 .\lists\monophones0>tree.hed

生成tree.hed文件,內容如下:


還要往tree.hed 中插入問題集(在HTK DEMO裏面有參考qusts.hed(在HTKDEMO裏)和 trace 等信息。最終形式如下:


在tree.hed 中,tiedlist 是綁定後的不同三音素列表。fulllist 是輸入參數,代表綁定前的
所有三音素列表,所以要事先製作。HTK book的製作方法: 
HDMan -b sp -n .\lists\fulllist -g global2.ded -l flog .\dict\beep-tri .\dict\beep 
其中,文件global2.ded 是在 global.ded基礎上加入了TC命令: 


執行:

HHEd -H .\hmms\hmm12\macros -H .\hmms\hmm12\hmmdefs -M .\hmms\hmm13 tree.hed .\lists\triphones1 > log

HDMan這裏所做的工作包括 1 )按照global.ded的配置把 beep 字典中的發音擴展成(詞內)三音素形式,保存到beep-tri字典;2)提取beep-tri中出現的所有不同三音素保存到 fulllist列表中。但是你會發現,按照上述方式製作的fulllist 在執行 HHEd 時會引發錯誤:


解決辦法:

對dict2 進行修改,另存爲 dict5,其中去掉了下述兩項: 
SENT-END []  sil 
SENT-START []  sil

執行HDMan生成fulllist : 
HDMan -b sp -n .\lists\fulllist -g global3.ded -l flog .\dict\dict5-tri .\dict\dict5 
上面的global3.ded 是在 global2.ded 基礎上去掉了 AS sp一行,因爲 dict5 中的每一單詞
發音後已經存在sp 了。文件 global3.ded 的內容如下:


重新執行一遍則不會報錯。

生成文件:tiedlist log stats

重估兩次:

HERest -C .\config\config1 -I .\labels\wintri.mlf -t 250.0 150.0 1000.0 -S train.scp -H .\hmms\hmm13\macros -H .\hmms\hmm13\hmmdefs -M .\hmms\hmm14 .\lists\tiedlist

這時候會報錯:


解決辦法:

在fulllist中加入sil

在重複一遍,這次僅有一個警告:


再重估一次:

HERest -C .\config\config1 -I .\labels\wintri.mlf -t 250.0 150.0 1000.0 -S train.scp -H .\hmms\hmm14\macros -H .\hmms\hmm14\hmmdefs -M .\hmms\hmm15 .\lists\tiedlist 

這次的警告與上次相同,沒有關係的。

4.識別器評估

[step 11]驗證識別結果

用Viterbi 算法進行識別已經在前文多處涉及,執行如下命令: 
HVite -C .\config\config1 -H .\hmms\hmm15\macros -H .\hmms\hmm15\hmmdefs -S test.scp -l * -i .\results\recout_step11.mlf -w wdnet -p 0.0 -s 5.0 .\dict\dict4 .\lists\tiedlist 

HResults -I .\labels\testwords.mlf .\lists\tiedlist .\results\recout_step11.mlf 

所得結果:


以上包括之前的三篇博文就是基於HTK的連續語音識別系統搭建學習筆記!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章