轉載聲明:本文為轉載文章
作者:ferb2015
原文地址:https://blog.csdn.net/eqiang8848/article/details/81543599
kaldi是一個開源的語音識別工具箱,是基於c++、perl、shell編寫的,可以在windows和unix 平台上編譯。
中文參考資料:《kaldi的全部資料_v0.7(未完成版本).pdf》。網盤鏈接 提取碼:yuq0
教程網頁:http://www.kaldi-asr.org/doc/ 里面可以查閱腳本的用途、使用,以及建立asr過程的資料。還有網上的dan的ppt。
kaldi下載:https://github.com/kaldi-asr/kaldi。
語音識別基礎知識快速入門
我的入門方式是看《語音信號處理》韓紀慶(編)的語音識別章節。
kaldi安裝
簡要說明:(運行環境centos7、ubuntu16.4、macos 10.13都能安裝成功)
- 安裝前你需要對你的 linux 進行配置,需要安裝的軟件apt-get、subversion、automake、autoconf、libtool、g++、zlib、libatal、wget,如何安裝見《kaldi的全部資料_v0.7(未完成版本).pdf》。
git clone https://github.com/kaldi-asr/kaldi.git 選擇某個路徑,下載kaldi。
在命令行cd到kaldi路徑下,cd到tool目錄下,在命令行分別輸入:
make -j nproc
extras/install_srilm.sh
install_irstlm.sh是安裝語言模型。
3. make 完后,在src目錄下:在命令行分別輸入:
./configure
make depend
make
make階段是編譯階段,將下載的包編譯為可執行文件,耗時較長,耐心等待。
ubuntu安裝遇到問題最少,centos和macos上安裝都會出現一些問題,得手動解決。
遇到過的error和解決方法:
make過程中,openfst-1.6.7.tar.gz沒有解壓完全,因此自動又解壓一遍,生成openfst-1.6.7.tar.gz.1,因此要把原openfst-1.6.7.tar.gz刪掉(rm openfst-1.6.7.tar.gz),openfst-1.6.7.tar.gz.1重命名為openfst-1.6.7.tar.gz(mv openfst-1.6.7.tar.gz.1 openfst-1.6.7.tar.gz)。再次make(不需要手動解壓)。
sudo make仍出現permission denied造成error。把文件夾的用戶改成使用者。比如我的用戶名叫work,chown -R work kaldi。
如果多次make都遇到error,建議先make clean把編譯過的全刪掉,再重新裝。
kaldi各文件解釋
- /egs:不同語料例子的執行腳本文件
- /tools:存放asr過程中用到的庫
- /src:存放實際執行的c++算法
以aishell為例的ASR過程
命令行到kaldi路徑下,輸入
cd egs/aishell/s5
首先改cmd的配置:
vim cmd.sh
改為:
export train_cmd=run.pl #"queue.pl --mem 2G"
export decode_cmd="run.pl --mem 4G" #"queue.pl --mem 4G"
export mkgraph_cmd="run.pl --mem 8G" #"queue.pl --mem 8G"
export cuda_cmd="run.pl --gpu 1"
原文件的queue是基於集群的,這里我們用本機/服務器跑,因此改為run.sh。
:wq保存后,輸入:
vim run.sh
看見data=/export/a05/xna/data改成想存放語料的路徑,返回后,新建對應的文件夾。之后輸入
./run.sh
就開始進行asr過程了。強烈建議逐行運行,運行當前行時,把其他暫時注釋調,這樣清楚看見每個階段的過程。
過程簡單說來就是:
語料數據准備 下載語料庫到本地/服務器的文件夾
數據關系,詞典、語言文件(text, wav.scp, utt2pk, spk2utt)准備,訓練集、測試集、驗證集准備
單音素(或者其他模型)訓練和解碼
構建解碼圖
解碼查看結果
run.sh詳細解釋:
這里是簡單的介紹,具體細節可以參考kaldi入門詳解 aishell2步驟解釋(二)
vim run.sh
查看run.sh腳本,這里逐行解釋:
下載並解壓aishell 178小時語料庫,(音頻和lexicon詞典):
local/download_and_untar.sh $data $data_url data_aishell || exit 1;
local/download_and_untar.sh $data $data_url resource_aishell || exit 1;
准備詞典:
local/aishell_prepare_dict.sh $data/resource_aishell || exit 1;
准備數據。分成test、dev、train集。:
local/aishell_data_prep.sh $data/data_aishell/wav $data/data_aishell/transcript || exit 1;
詞典、語言文件准備,生成對應的數據關系:
Phone Sets, questions, L compilation
utils/prepare_lang.sh --position-dependent-phones false data/local/dict \
"<SPOKEN_NOISE>" data/local/lang data/lang || exit 1;
其中,數據關系保存在/data里,文件解釋如下:
spk2gender 包含說話人的性別信息
spk2utt 包含說話人編號和說話人的語音編號的信息
text 包含語音和語音編號之間的關系
utt2spk 語音編號和說話人編號之間的關系
wav.scp 包含了原始語音的路徑信息等
提取MFCC特征:
# Now make MFCC plus pitch features.
# mfccdir should be some place with a largish disk where you
# want to store MFCC features.
mfccdir=mfcc
for x in train dev test; do
steps/make_mfcc_pitch.sh --cmd "$train_cmd" --nj 10 data/$x exp/make_mfcc/$x $mfccdir || exit 1;
steps/compute_cmvn_stats.sh data/$x exp/make_mfcc/$x $mfccdir || exit 1;
utils/fix_data_dir.sh data/$x || exit 1;
done
分為兩步,先通過steps/make_mfcc.sh提取MFCC特征,再通過steps/compute_cmvn_stats.sh計算倒譜均值和方差歸一化。
生成了兩個文件夾:mfcc 和 exp/make_mfcc,其中 mfcc 里主要保存了提取的特征,而 exp/make_mfcc 里保存了日志,即 .log 文件。
在 steps/make_mfcc.sh 里用到的最主要的命令就是 compute-mfcc-feats 和 copy-feats,其在 src 里編譯好的。
mfcc 目錄里主要是 .ark 和 .scp 文件,其中 .scp 文件里的內容是語音段和特征對應,而真正的特征保存在 .ark 文件里。用下面的命令可以看清楚
copy-feats ark:mfcc/raw_mfcc_train.1.ark ark,t:-
單音素訓練:
steps/train_mono.sh --cmd "$train_cmd" --nj 10 \
data/train data/lang exp/mono || exit 1;
之后會在 exp 文件夾下產生一個 mono 的目錄,里面以 .mdl 結尾的就保存了模型的參數。使用下面的命令可以查看模型的內容。
$ gmm-copy --binary=false exp/mono/0.mdl - | less
構建單音素解碼圖:
# Monophone decoding
utils/mkgraph.sh data/lang_test exp/mono exp/mono/graph || exit 1;
mkgraph.sh主要生成了HCLG.fst和words.txt這兩個重要的文件,后續識別主要利用了三個文件,分別是final.mdl、HCLG.fst、words.txt。
解碼:分別針對開發集和測試集解碼
steps/decode.sh --cmd "$decode_cmd" --config conf/decode.config --nj 10 \
exp/mono/graph data/dev exp/mono/decode_dev
steps/decode.sh --cmd "$decode_cmd" --config conf/decode.config --nj 10 \
exp/mono/graph data/test exp/mono/decode_test
解碼的日志會保存在 exp/mono/decode_dev/log 和 exp/mono/decode_test/log 里。
Veterbi 對齊
# Get alignments from monophone system.
steps/align_si.sh --cmd "$train_cmd" --nj 10 \
data/train data/lang exp/mono exp/mono_ali || exit 1;
之后就是和訓練單音素一樣,進行其他模型的訓練解碼,生成聲學模型和語言模型,保存在/exp中。
查看結果:
輸入下面的命令來查看結果
# getting results (see RESULTS file)
for x in exp/*/decode_test; do [ -d $x ] && grep WER $x/cer_* | utils/best_wer.sh; done 2>/dev/null
總結:aishell的/s5/run.sh文件運行了gmm+hmm hybrid模型以及dnn+hmm hybrid模型。
首先用標准的13維MFCC加上一階和二階導數訓練單音素GMM系統,采用倒譜均值歸一化(CMN)來降低通道效應。然后基於具有由LDA和MLLT變換的特征的單音系統構造三音GMM系統,最后的GMM系統用於為隨后的DNN訓練生成狀態對齊。
基於GMM系統提供的對齊來訓練DNN系統,特征是40維FBank,並且相鄰的幀由11幀窗口(每側5個窗口)連接。連接的特征被LDA轉換,其中維度降低到200。然后應用全局均值和方差歸一化以獲得DNN輸入。DNN架構由4個隱藏層組成,每個層由1200個單元組成,輸出層由3386個單元組成。 基線DNN模型用交叉熵的標准訓練。 使用隨機梯度下降(SGD)算法來執行優化。 將迷你批量大小設定為256,初始學習率設定為0.008。
被噪聲干擾的語音可以使用基於深度自動編碼器(DAE)的噪聲消除方法。DAE是自動編碼器(AE)的一種特殊實現,通過在模型訓練中對輸入特征引入隨機破壞。已經表明,該模型學習低維度特征的能力非常強大,並且可以用於恢復被噪聲破壞的信號。在實踐中,DAE被用作前端管道的特定組件。輸入是11維Fbank特征(在均值歸一化之后),輸出是對應於中心幀的噪聲消除特征。然后對輸出進行LDA變換,提取全局標准化的常規Fbank特征,然后送到DNN聲學模型(用純凈語音進行訓練)。
train_mono.sh 用來訓練單音子隱馬爾科夫模型,一共進行40次迭代,每兩次迭代進行一次對齊操作
train_deltas.sh 用來訓練與上下文相關的三音子模型
train_lda_mllt.sh 用來進行線性判別分析和最大似然線性轉換
train_sat.sh 用來訓練發音人自適應,基於特征空間最大似然線性回歸
nnet3/run_dnn.sh 用nnet3來訓練DNN,包括xent和MPE
用chain訓練DNN
結果
aishell訓練模型的詞錯誤率wer和字錯誤率cer如下:
%WER 44.23 [ 28499 / 64428, 1821 ins, 4610 del, 22068 sub ] exp/mono/decode_test/wer_13_0.0
%WER 29.67 [ 19113 / 64428, 1567 ins, 2934 del, 14612 sub ] exp/tri1/decode_test/wer_14_0.5
%WER 29.24 [ 18841 / 64428, 1557 ins, 2813 del, 14471 sub ] exp/tri2/decode_test/wer_15_0.5
%WER 27.38 [ 17640 / 64428, 1764 ins, 2267 del, 13609 sub ] exp/tri3a/decode_test/wer_16_0.0
%WER 23.44 [ 15102 / 64428, 1468 ins, 2110 del, 11524 sub ] exp/tri4a/decode_test/wer_15_0.5
%WER 21.76 [ 14017 / 64428, 1383 ins, 1954 del, 10680 sub ] exp/tri5a/decode_test/wer_16_0.5
%WER 17.43 [ 11233 / 64428, 1077 ins, 1675 del, 8481 sub ] exp/nnet3/tdnn_sp/decode_test/wer_16_0.5
%WER 15.96 [ 10281 / 64428, 919 ins, 1672 del, 7690 sub ] exp/chain/tdnn_1a_sp/decode_test/wer_12_0.5
%CER 34.13 [ 35757 / 104765, 783 ins, 3765 del, 31209 sub ] exp/mono/decode_test/cer_11_0.0
%CER 19.56 [ 20496 / 104765, 910 ins, 1436 del, 18150 sub ] exp/tri1/decode_test/cer_13_0.5
%CER 19.16 [ 20073 / 104765, 989 ins, 1211 del, 17873 sub ] exp/tri2/decode_test/cer_13_0.5
%CER 17.24 [ 18060 / 104765, 780 ins, 1024 del, 16256 sub ] exp/tri3a/decode_test/cer_13_0.5
%CER 13.58 [ 14227 / 104765, 640 ins, 716 del, 12871 sub ] exp/tri4a/decode_test/cer_14_0.5
%CER 12.22 [ 12803 / 104765, 668 ins, 565 del, 11570 sub ] exp/tri5a/decode_test/cer_14_0.5
%CER 8.44 [ 8838 / 104765, 331 ins, 510 del, 7997 sub ] exp/nnet3/tdnn_sp/decode_test/cer_14_0.5
%CER 7.37 [ 7722 / 104765, 303 ins, 581 del, 6838 sub ] exp/chain/tdnn_1a_sp/decode_test/cer_11_1.0