為什么80%的碼農都做不了架構師?>>> ??
基于 HTK 的語音撥號系統
Veket
? NWPU
2011-6-22
目標:
該系統能夠識別連續說出的數字串和若干組姓名。建模是針對子詞( sub-word,eg.. 音素),具有一定的可擴充性。當加入一個新名字時,只需修改發音詞典和任務語法即可。模型為連續混合高斯輸出,運用語音決策樹聚類形成的綁定狀態式三音素。
內容:
1. 數據準備
(1) ????? 任務語法定義
(2) ????? 字典定義
(4) ????? 標注數據,得到真值文件
(5) ????? 數據特征的提取
2. 創建單音素 HMM 模型
(6) ????? 一致初始化法創建單音素模型
(7) ????? 修補啞音素模型
(8) ????? 重新校正數據
3. 創建綁定狀態的三音素 HMM 模型
(9) ????? 得到三音素 HMM
(10) ? 綁定三音素
4. 識別器評估
( 11 )驗證測試結果
步驟:
1. 數據準備
需要錄制訓練數據和測試數據。為了進行校準,還需要數據的標注文本。這里用任務語法( task grammar )產生真值文本( ground truth ) . 為了處理訓練數據,需要定義一個語音集合和一個字典用以涵蓋訓練和測試數據中涉及的單詞。
(1) ????? 任務語法定義
任務語法以包含變量的正則表達式形式定義,存儲在文件 gram (手工制作,在 Notepad++ 或 UltraEdit 環境下進行 , 最后要空一行)里:
?
上面的語法是高層表示,必須通過 HParse 轉換成 HTK 的底層表示。
運行指令: HParse gram wdnet
?
底層表示存于文件 wdnet ( HParse 工具生成 )中。
?
(2) ????? 字典定義
利用 BEEP 語音詞典(現成的),除去其中的重音符。
在每個發音后加入 sp(short pause). 如果有啞音標志,就用 MP 命令把 sil 和 sp 合并成 sil ,這些處理命令放在 global.ded (手工制作)的腳本中。
?
文件 wlist (此系統由于涉及的單詞較少,于是手工制作即可)是出現在任務語法中的所有單詞的有序列表。
?
?????? 文件 names 是專有人名的發音(手工制作,包括 SEND-START,SENT-END )。
?
?????? 執行 HDMan:
HDMan -m -w lists/wlist - g global.ded ? -n lists/monophones 0 -l dlog dict/dict1 ? dict/beep dict/names
?
生成的文件 monophones 0 是用到的音素列表(包括 sp ) , 生成的 dlog 是參數文件,其中包含生成的字典 dict1 的相關統計信息,還會提示是否丟失單詞。生成的與任務相關的發音詞典 dict1, 需要手工修改,為 SENT-END 和 SENT-START 加上無輸出標志。
?
為了避免在 dlog 里出現 warnning, 可在 names 和 beep 同一目錄下分別建立同名的編輯腳本,內容為空即可。
?
(3) ????? 錄制語音數據
HSGen 工具可以生成符合 task grammar 的句子,用來指導錄音:
HSGen -l -n 10 wdnet dict/dict1>labels/trainprompts
HSGen -l -n 1 0 wdnet dict/dict1>labels/testprompts
?????? 根據上述生成的指令文件,錄制相應的 10 個訓練用語音數據 文件和 10 個測試用語音數據 文件。一個錄制例子如下:
HSLab ./data/Train/speech/S0001
?
(4) ????? 標注數據,得到真值文件
perl 腳本 prompts2mlf( 現成的 ) 可以把錄音文本截成單詞級真值文件 trainwords _2 .mlf , testwords _2 .mlf :
perl scripts/prompts2mlf labels/trainwords _2 .mlf labels/trainprompts
perl scripts/prompts2mlf labels/testwords _2 .mlf labels/testprompts
注 :將生成的文件 trainwords _2 .mlf ( testwords _2 .mlf ) 按 trainwords _1 .mlf ( testwords _1 .mlf ) 的格式 "*/S0*.lab" 添加到其文件末尾,并保存為 trainwords.mlf ( testwords.mlf )
標注編輯器 HLEd 可把單詞級真值文本( word level MLF )轉成音素級真值文本( phone level MLF ) phones0.mlf :
HLEd -l * -d dict/dict1 -i labels/phones0.mlf mkphones0.led labels/trainwords.mlf
編輯腳本 mkphones0.led 的內容如下:
?
其中 EX 命令表示按照字典 dict1 進行展開, IS 表示在每個話語的前后插入標志, DE 一行表示 phones0.mlf 中單詞間不用 sp 隔開。
?
(5) ? 數據的特征提取
這里所用特征為 MFCC 。工具 HCopy 可以實現提取特征的工作 。
HCopy -T 1 -C config/config 1 -S codetr.scp
其中,配置文件 config1 要設置轉換參數(紅色標出), config 內容如下:
# Coding parameters
??? TARGETKIND = MFCC_0_D_A?????????? // 目標文件參數類型
??? TARGETRATE = 100000.0?????????????? // 目標速率, 100 幀 / 秒
?? ? SOURCEFORMAT = WAV ?????????????? // 源文件格式
??? SAVECOMPRESSED = T??????????????? // 以壓縮的方式存儲
??? SAVEWITHCRC = T??????????????????? // 附加校驗和到輸出參數中
??? ZMEANSOURCE=TRUE
??? SOURCERATE=208??????????????????? // 源文件的速率
??? WINDOWSIZE = 250000.0? ???????????? // 以 25ms 為一幀進行分幀處理
??? USEHAMMING = T??????????????????? // 采用漢明窗,進行加窗處理
??? PREEMCOEF = 0.97?????????????????? // 預加重系數
??? NUMCHANS = 26???????????????????? //26 組濾波器
??? CEPLIFTER = 22????????????????????? // 倒譜濾波系數
??? NUMCEPS = 12?????????????? ???????? // 參數個數
??? ENORMALISE = F??????????????????? // 對 log 能量不進行 歸一 化
?
實現該命令所需的腳本文件 codetr.scp 可采用如下方式生成: 在 DOS 環境下進入到 wav 文件所在路徑,用 dir/b/s > wav.scp 指令將所有的 wav 文件名寫入到 wav.scp 文件中(注意刪除多出的一行),然后在 Notepad++ 中構造 下圖 所示的文件, 存 為 coder.scp 。 ( 注:生成的wav.scp 中的文件路徑是絕對路徑,可以手動改成相對路徑)
?
codetr.scp 指定訓練及輸入和輸出文件列表。執行結果, HCopy 對 codetr.scp 文件左側的語音數據 按 config 1 的配置提取特征并存入 codetr.scp 文件右側特征文件中。
對于測試數據如法炮制。
HCopy -T 1 -C config/config 1 -S codet e .scp
?
2. 創建單音素 HMM 模型
( 6 )一致初始化法創建單音素模型
?????? 定義一個原始模型 proto:
?
?
訓練文件 train.scp 的生成也是在 DOS 環境下進入到 MFCC 特征的文件路徑下,執行 dir/b/s> train.scp 。需要注意的是要在 Nodepad++ 或 UltraEdit 下把多余的一行刪除掉。
?
用全局均值和方差來初始化 HMM 模型的高斯參數:
HCompV -T 1 -C config/config1 -f 0.01 -m -S train.scp -M hmm s/hmm0 ? proto
?????? 在目錄 hmm0 下生成了更新后的 proto 和一個截至宏 vFloors 。基于 ./hmms/hmm0/ 下的兩個文件,手工制作主宏文件 hmmdefs 和與 vFloors 相關的宏 macro, 具體制作過程參見 HTKbook 。
?
?
由于暫時不使用 sp 模型,刪除 monophones 0 中的 sp, 構成 monophones 1 文件,重估參數:
HERest ? -C config/config1 - I ? labels/phone s 0.mlf ? - t 250.0 150.0 1000.0 - S train.scp -H hmms/hmm0/macros -H hmms/hmm0/hmmdefs ? -M hmms/hmm1 ? lists/monophones 1
同上,重復估計兩次:
HERes t ? -C ./config/config1 -I ./labels/phones0.mlf -t 250.0 150.0 1000.0 -S train.scp -H ./hmms/hmm1/macros -H ./hmms//hmm1/hmmdefs -M ./hmms/hmm2 ./lists/monophones 1
?
HERest ? -C ./config/config1 -I ./labels/phones0.mlf -t 250.0 150.0 1000.0 -S train.scp -H ./hmms/hmm2/macros -H ./hmms/hmm2/hmmdefs -M ./hmms/hmm3 ./lists/monophones1
?
(6) ????? 修補啞音素模型
將 hmm3 中的 macros 復制到 hmm4 中, hmmdefs 中的 sil 復制到文件末尾并將 sil 改為 sp 及狀態改為 3 放到 hmm4 。
?
(1) 利用 HHEd 加入回溯轉移概率:
HHEd -T 1 -H hmms/hmm4/macros - H hmms/hmm4/hmmdefs -M hmms/hmm5 sil.hed ? lists/monophone s0
修改 mkphones0.led, 去掉最后一行,存為 mkphones1.led ,利用 HLEd 工具得到包含 sp
的音素級真值文本:
HLEd -l * -d ./dict/dict1 -i ./labels/phones1.mlf mkphones1.led ./labels/trainwords.mlf
?
(2) 重估兩次:
HERest -C config/config1 -I labels/phone s0 .mlf -t 250.0 150.0 1000.0 - S train.scp -H hmms/hmm5/macros -H hmms/hmm5/hmmdefs -M hmms/hmm6 ? lists/monophones 0
?
HERest -C config/config1 -I labels/phone s0 .mlf -t 250.0 150.0 1000.0 - S train.scp -H hmms/hmm 6 /macros -H hmms/hmm 6 /hmmdefs -M hmms/hmm 7 ? lists/monophones 0
?
( 8 )重校準訓練數據
確認 trainwords.mlf 中的路徑為 ”*/S0 * .lab” 并且加上前面的 140 句話 ,修改 dict 1 加入 silence sil 一項,另存為 dict 2 ,執行 HVite 進行 Viterbi 校準:
HVite -l * -o SWT - b silence -C config/config1 -a -H hmms/hmm7/macros ? -H hmms/hmm7/hmmdefs -i labels/aligned.mlf -m -t 350.0 -y lab -I labels/trainwords.mlf -S train.scp ? dict/dict 2 ? lists/monophones 0
?
利用 HERest 重估兩次 ,最后保存到 hmm9
HERest _3.4 -C config/config1 -I labels/aligned.mlf -t 250.0 150.0 1000.0 - S train.scp -H hmms/hmm 7 /macros -H hmms/hmm 7 /hmmdefs -M hmms/hmm 8 ? lists/monophones 0
?
HERest _3.4 -C config/config1 -I labels/aligned.mlf ? -t 250.0 150.0 1000.0 - S train.scp -H hmms/hmm 8 /macros -H hmms/hmm 8 /hmmdefs -M hmms/hmm 9 ? lists/monophones 0
來看看這時的識別率怎么樣 :
HVite -H ./hmms/hmm 9 /macros -H ./hmms/hmm 9 /hmmdefs -S test.scp -l * -i ./results/recout_step 9 .mlf -w wdnet -p 0.0 -s 5.0 ./dict/dict 2 ./lists/monophones 0
HResults -I ./labels/testwords.mlf ./lists/monophones 0 results/recout_step 9 .mlf