kaildi講解

轉載聲明:本文爲轉載文章前端

做者:ferb2015linux

原文地址:http://www.javashuo.com/article/p-yzivtwhv-nr.htmlc++

kaldi是一個開源的語音識別工具箱,是基於c++、perl、shell編寫的,能夠在windows和unix 平臺上編譯。git

中文參考資料:《kaldi的所有資料_v0.7(未完成版本).pdf》。網盤連接 提取碼:yuq0github

教程網頁:http://www.kaldi-asr.org/doc/ 裏面能夠查閱腳本的用途、使用,以及創建asr過程的資料。還有網上的dan的ppt。算法

kaldi下載:https://github.com/kaldi-asr/kaldishell

語音識別基礎知識快速入門macos

個人入門方式是看《語音信號處理》韓紀慶(編)的語音識別章節。ubuntu

kaldi安裝

簡要說明:(運行環境centos七、ubuntu16.四、macos 10.13都能安裝成功)vim

  1. 安裝前你須要對你的 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是安裝語言模型。

  1. 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

參考資料:
1.解讀thchs30/s5/run.sh的主要步驟:https://blog.csdn.net/BBZZ2/article/details/72884979
2.kaldi的語音識別數據timit例子詳解:https://blog.csdn.net/DanyHgc/article/details/75222517 ---------------------

相關文章
相關標籤/搜索