Kaldi運行thchs30中文語音識別教程
轉載自 https://www.jianshu.com/p/c48466d36162 這篇文章寫的比較詳細,適合新手入門觀看,特地摘錄下來以供分享和之后學習
說明
- 測試環境:Ubuntu16.04
- 建議:仔細地按照此教程來,有些人中間出錯是因為沒仔細按照教程的步驟和細節
- 文檔更新時間:20180713
- 使用thchs30訓練最后的識別准確率約:64%
運行thchs30步驟
- 安裝kaldi:https://github.com/kaldi-asr/kaldi/blob/master/tools/INSTALL,按官方教程即可
- 首先進入githab下載的源碼中egs目錄下找到這個例子,然后要看一遍它的介紹。在readme里面有語料庫的下載方式。把它下完(3個壓縮包全下)。總共8個多G比較大。
- 考到對應的文件夾下(與s5同級別即可),取名叫thchs30-openslr,將所有壓縮包解壓到這下面,文件目錄如下
thchs30-openslr ├── data_thchs30 ├── resource └── test-noise
- 1
- 2
- 3
- 4
4.打開s5目錄,編輯cmd.sh. 修改為本地運行, 如下
export train_cmd=run.pl export decode_cmd=run.pl export mkgraph_cmd=run.pl export cuda_cmd=run.pl
- 1
- 2
- 3
- 4
修改s5下面的run.sh腳本,可以改兩個地方
#n=4 #parallel jobs 修改並行任務的數量,可以根據cpu的個數來定 n=2 #parallel jobs #thchs=/nfs/public/materials/data/thchs30-openslr #修改文件路徑,改成你的文件路徑 thchs=/home/jackie/data/thchs30-openslr
- 1
- 2
- 3
- 4
5.可以直接運行bash run.sh,前面沒有配置錯誤什么的話應該不會有問題,有問題的話注意看輸出,大概跑幾小時到十幾小時(根據機器而定)。也可以選擇建議一行一行地跑這個腳本,這樣容易定位錯誤。如何一行行跑呢? 使用注釋:
:<<BLOCK ....我是注釋內容 ....我是注釋內容 BLOCK
- 1
- 2
- 3
- 4
6.按照上面的一句一句的來。它大概有幾個過程:數據准備,monophone單音素訓練, tri1三因素訓練, trib2進行lda_mllt特征變換,trib3進行sat自然語言適應,trib4做quick,后面就是dnn了
7.當運行到dnn時候會報錯,因為默認dnn都是用GPU來跑的。它會檢查一下,發現只在CPU下,就終止了。這里建議不要跑dnn了。因為我試過,改成CPU之后跑了7,8天,才迭代17,18次。太慢了。而一次訓練怎么的也得20多次。還要訓練好幾回。所以,想跑dnn的話還是找GPU吧。
8.運行結束后看thchs30/s5/exp目錄,其中tri1/decode_test_word/scoring_kaldi/best_wer 文件就是程序的錯誤率約36.15%,tri1/final.mdl即為輸出的模型,此外graph_word文件夾下面有words.txt,和HCLG.fst,一個是字典,一個是有限狀態機。有這3個文件,就可以來使用你的識別功能了。
9.識別自己的語音(使用wav文件或者麥克風)識別效果並不准,錯誤率約36%。回到源碼的kaldi/src目錄下。make ext 編譯擴展程序。(在這之前確定你的tools文件夾下的portaudio已經裝好)之后,會看到onlinebin文件夾。里面有兩個程序,online-wav-gmm-decode-faster 用來回放wav文件來識別的,online-gmm-decode-faster用來從麥克風輸入聲音來識別的。(這里開個小差:portaudio 裝好后,有可能收不到聲音,可以裝個audio recoder(用apt-get),之后用它錄音試試,測測是否有聲音,只要能錄音,portaudio就沒問題,一般裝完就好了,不行就再重啟一下。不知道為啥。)
10.我們找一個例子吧:去egs下,打開voxforge,里面有個online_demo,直接考到thchs30下。在online_demo里面建2個文件夾online-data work,在online-data下建兩個文件夾audio和models,audio下放你要回放的wav,models建個文件夾tri1,把s5下的exp下的tri1下的final.mdl和35.mdl(final.mdl是快捷方式)考過去。把s5下的exp下的tri1下的graph_word里面的words.txt,和HCLG.fst,考到models的tri1下。這里復制完后目錄結構應該是這樣的
online_demo
├── online-data
│ ├── audio
│ │ ├── 1.wav │ │ ├── 2.wav │ │ ├── 3.wav │ │ ├── 4.wav │ │ ├── 5.wav │ │ └── trans.txt │ └── models │ └── tri1 │ ├── 35.mdl │ ├── final.mdl │ ├── HCLG.fst │ └── words.txt ├── README.txt ├── run.sh └── work[這個文件夾運行run.sh成功后才會出現] ├── ali.txt ├── hyp.txt ├── input.scp ├── ref.txt └── trans.txt
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
11.打開online_demo的run.sh
- 將下面這段注釋掉:(這段是voxforge例子中下載現網的測試語料和識別模型的。我們測試語料自己准備,模型就是tri1了)
if [ ! -s ${data_file}.tar.bz2 ]; then echo "Downloading test models and data ..." wget -T 10 -t 3 $data_url; if [ ! -s ${data_file}.tar.bz2 ]; then echo "Download of $data_file has failed!" exit 1 fi fi
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 然后再找到如下這句,將其路徑改成tri1
ac_model_type=tri2b_mmi
- 1
改成:
ac_model_type=tri1
- 1
以及:
online-wav-gmm-decode-faster --verbose=1 --rt-min=0.8 --rt-max=0.85\ --max-active=4000 --beam=12.0 --acoustic-scale=0.0769 \ scp:$decode_dir/input.scp $ac_model/model
- 1
- 2
- 3
改成:(僅修改了最后的model為final.mdl)
online-wav-gmm-decode-faster --verbose=1 --rt-min=0.8 --rt-max=0.85\ --max-active=4000 --beam=12.0 --acoustic-scale=0.0769 \ scp:$decode_dir/input.scp $ac_model/final.mdl
- 1
- 2
- 3
12.直接./run.sh吧,就是開始回放識別了。里面有提示,./run.sh –test-mode live命令就是從麥克風識別。
13.升華部分在這里。我們試完tri1的模型后,一定很想試試tri2或3.但當你操作時,會遇到如下的問題:
ERROR (online-wav-gmm-decode-faster:LogLikelihoods():diag-gmm.cc:533) DiagGmm::ComponentLogLikelihood, dimension mismatch 39vs. 40
- 1
怎么解決? 仔細看看這個源文件,它是dieta的。如果要是ldp還得加matrix參數(拿tri2b舉例)。
於是修改run.sh成如下這個樣子 :(就是把12.mat(在tri2中final.mat是12.mat的快捷方式,所以拷貝final.mat)考過來,引入命令中)
ac_model=${data_file}/models/$ac_model_type trans_matrix="$ac_model/12.mat" audio=${data_file}/audio if [ -s $ac_model/matrix ]; then trans_matrix=$ac_model/12.mat fi
- 1
- 2
- 3
- 4
- 5
- 6
- 7
同時把把s5下的exp下的tri2b下的12.mat考到models的tri2b下。
14.再次修改run.sh成如下這個樣子(添加2個參數–left-context=3 –right-context=3)
online-wav-gmm-decode-faster --verbose=1 --rt-min=0.8 --rt-max=0.85 \ --max-active=4000 --beam=12.0 --acoustic-scale=0.0769 --left-context=3 --right-context=3\ scp:$decode_dir/input.scp $ac_model/final.mdl $ac_model/HCLG.fst \ $ac_model/words.txt '1:2:3:4:5' ark,t:$decode_dir/trans.txt \ ark,t:$decode_dir/ali.txt $trans_matrix;;
- 1
- 2
- 3
- 4
- 5
15.運行./run.sh,結果如下。怎么樣,有點酷不? 如果想使用tri2等模型做麥克風在線的,也同理修改就可以了。
online-wav-gmm-decode-faster --verbose=1 --rt-min=0.8 --rt-max=0.85 --max-active=4000 --beam=12.0 --acoustic-scale=0.0769 --left-context=3 --right-context=3 scp:./work/input.scp online-data/models/tri2b/final.mdl online-data/models/tri2b/HCLG.fst online-data/models/tri2b/words.txt 1:2:3:4:5 ark,t:./work/trans.txt ark,t:./work/ali.txt online-data/models/tri2b/12.mat File: D4_750 蘇北 軍禮 下跪 將 是 馬 湛 殺人 里 杜 唐 據 五 蘇 並 案 但 甜美 但 也 分析 抗戰
- 1
- 2
- 3
訓練與解碼腳本解讀
本節結合官方文檔對主要腳本進行解讀。
以下流程中的符號解釋:->表示下一步,{}表示循環,[]表示括號內每一個都要進行一次,()表示不同分支下可能進行的操作
1.train_mono.sh 用來訓練單音子隱馬爾科夫模型,一共進行40次迭代,每兩次迭代進行一次對齊操作
gmm-init-mono->compile-train-graphs->align-equal-compiled->gmm-est-> {gmm-align-compiled->gmm-acc-stats-ali->gmm-est}40->analyze_alignments.sh
- 1
- 2
2.train_deltas.sh 用來訓練與上下文相關的三音子模型
check_phones_compatible.sh->acc-tree-stats->sum-tree-stats->cluster-phones->compile-questions-> build-tree->gmm-init-model->gmm-mixup->convert-ali->compile-train-graphs-> {gmm-align-compiled->gmm-acc-stats-ali->gmm-est}35->analyze_alignments.sh
- 1
- 2
- 3
3.train_lda_mllt.sh 用來進行線性判別分析和最大似然線性轉換
check_phones_compatible.sh->split_data.sh->ali-to-post->est-lda->acc-tree-stats->sum-tree-stats-> cluster-phones->compile-questions->build-tree->gmm-init-model->convert-ali->compile-train-graphs-> {gmm-align-compiled->gmm-acc-stats-ali->gmm-est}35->analyze_alignments.sh
- 1
- 2
- 3
4.train_sat.sh 用來訓練發音人自適應,基於特征空間最大似然線性回歸
check_phones_compatible.sh->ali-to-post->acc-tree-stats->sum-tree-stats->cluster-phones->compile-questions-> build-tree->gmm-init-model->gmm-mixup->convert-ali->compile-train-graphs-> {gmm-align-compiled->(ali-to-post->)gmm-acc-stats-ali->gmm-est}35->ali-to-post-> gmm-est->analyze_alignments.sh
- 1
- 2
- 3
- 4
5.train_quick.sh 用來在現有特征上訓練模型。
對於當前模型中在樹構建之后的每個狀態,它基於樹統計中的計數的重疊判斷的相似性來選擇舊模型中最接近的狀態。
check_phones_compatible.sh->ali-to-post->est-lda->acc-tree-stats->sum-tree-stats-> cluster-phones->compile-questions->build-tree->gmm-init-model->convert-ali->compile-train-graphs-> {gmm-align-compiled->gmm-acc-stats-ali->gmm-est}20->analyze_alignments.sh
- 1
- 2
- 3
6.run_dnn.sh 用來訓練DNN,包括xent和MPE
{make_fbank.sh->compute_cmvn_stats.sh}[train,dev,test]->train.sh->{decode.sh}[phone,word]-> align.sh->make_denlats.sh->train_mpe.sh->{{decode.sh}[phone,word]}3
- 1
- 2
7.train_mpe.sh 用來訓練dnn的序列辨別MEP/sMBR
這個階段訓練神經網絡以聯合優化整個句子,這比幀級訓練更接近於一般ASR目標。
sMBR的目的是最大化從參考轉錄對齊導出的狀態標簽的期望正確率,而使用網格框架來表示競爭假設。
訓練使用每句迭代的隨機梯度下降法。
首先使用固定的低學習率1e-5(sigmoids)運行3-5輪。
在第一輪迭代后重新生成詞圖,我們觀察到快速收斂。
我們支持MMI, BMMI, MPE 和sMBR訓練。所有的技術在Switchboard 100h集上是相同的,僅僅在sMBR好一點點。
在sMBR優化中,我們在計算近似正確率的時候忽略了靜音幀。
{nnet-train-mpe-sequential}3->make_priors.sh
- 1
8.train_dae.sh 用來實驗基於dae的去噪效果
compute_cmvn_stats.sh->{add-noise-mod.py->make_fbank.sh->compute_cmvn_stats.sh}[train,dev,test]-> train.sh->nnet-concat->{{decode.sh}[phone,word]}[train,dev,test]
- 1
- 2
9.train.sh 用來訓練深度神經網絡模型,幀交叉熵訓練,該相位訓練將幀分類為三音狀態的DNN。這是通過小批量 隨機梯度下降完成的。
默認使用Sigmoid隱藏單元,Softmax輸出單元和完全連接的AffineTransform層,學習率是0.008,小批量的大小
為256。
我們沒有使用動量或正則化(注:最佳學習率和隱藏單元的類型不同,sigmoid的值為0.008,tanh為0.00001。
通過‘–feature-transform’和‘-dbn’將input——transform和預訓練的DBN傳入此腳本,只有輸出層被隨機初始化。
我們使用提前停止來防止過度擬合,為此我們測量交叉驗證集合(即保持集合)上的目標函數,
因此需要兩對特征對齊dir來執行監督訓練
feat-to-dim->nnet-initialize->compute-cmvn-stats->nnet-forward->nnet-concat->cmvn-to-nnet-> feat-to-dim->apply-cmvn->nnet-forward->nnet-initialize->train_scheduler.sh
- 1
- 2
10.train_scheduler.sh 典型的情況就是,train_scheduler.sh被train.sh調用。
一開始需要在交叉驗證集上運行,主函數需要根據$iter來控制迭代次數和學習率。
學習率會隨着目標函數相對性的提高而變化:
如果提高大於’start_halving_impr=0.01’,初始化學習率保持常數
否則學習率在每次迭代中乘以’halving_factor=0.5’來縮小
最后,如果提高小於’end_halving_impr=0.001’,訓練終止。
11.mkgraph.sh 用來建立一個完全的識別網絡
12.decode.sh 用來解碼並生成詞錯率結果
13.align_si.sh 對制定的數據進行對齊,作為新模型的輸入
14.make_fmllr_feats.sh 用來保存FMLLR特征
15.pretrain_dbn.sh 深度神經網絡預訓練腳本
16.decode_fmllr.sh 對發音人自適應的模型進行解碼操作
17.nnet-train-frmshuff.cc 最普遍使用的神經網絡訓練工具,執行一次迭代訓練。過程:
–feature-transform 即時特征擴展
NN輸入-目標對的每幀重排
小批量隨機梯度下降(SGD)訓練
支持的每幀目標函數(選項 - 對象函數):
Xent:每幀交叉熵
Mse:每幀均方誤差
18.nnet-forward.cc 通過神經網絡轉發數據,默認使用CPU。選項:
–apply-log :產生神經網絡的對數輸出(比如:得到對數后驗概率)
–no-softmax :從模型中去掉soft-max層
—class-frame-counts:從聲學得分中減去計算對數的計數
專有縮寫中文解釋
cmvn:倒譜均值和方差歸一化
fft:快速傅里葉變換
GMM:高斯混合模型
MFCC:梅爾倒譜系數
pcm:脈沖編碼調制
pdf:概率分布函數
PLP:感知線性預測系數
SGMM:子空間高斯混合模型
UBM:通用背景模型
VTLN:特征級聲道長度歸一化