ASR之Kaldi

Kaldi官方github地址:https://github.com/kaldi-asr/kaldi

Kaldi目錄結構

./tools, ./src, ./egs 這三個目錄是比較重要的。

./tools目錄下面全部都是Kaldi依賴的包。其中主要有:

  1. OpenFST:Weighted Finite State Transducer library,是一個用來構造有限狀態自動機的庫。我們知道隱馬爾科夫模型就可以看成是一個有限狀態自動機的。這是最終要的一個包,Kaldi的文檔裏面說:If you ever want to understand Kaldi deeply you will need to understand OpenFst.誒,要學的好多。
  2. ATLAS:這是一個C++下的線性代數庫。做機器學習自然是需要很多矩陣運算的。
  3. IRSTLM:這是一個統計語言模型的工具包。
  4. sph2pipe:這是賓夕法尼亞大學linguistic data consortium(LDC)開發的一款處理SPHERE_formatted數字音頻文件的軟件,它可以將LDC的sph格式的文件轉換成其它格式。

./src目錄存放的是Kaldi的源代碼。

./egs存放的是Kaldi提供的一些例子。

Kaldi的編譯安裝:

按照README.md中說明進行操作即可

運行yesno實例

該實例是一個非常小的數據集,每一條記錄都是一系列yes或者no的語音,標註是由文件名來標註的。先運行一下。

切換到./egs/yesno/s5目錄下,運行sudo./run.sh命令。

經過一段時間的訓練和測試,可以看到運行結果。

這裏寫圖片描述

WER爲0.00。看來這個例子識別的還是挺準的。

 

PS:WER(WordError Rate)是字錯誤率,是一個衡量語音識別系統的準確程度的度量。其計算公式是WER=(I+D+S)/N,其中I代表被插入的單詞個數,D代表被刪除的單詞個數,S代表被替換的單詞個數。也就是說把識別出來的結果中,多認的,少認的,認錯的全都加起來,除以總單詞數。這個數字當然是越低越好。

 

下面進入./yesno/s5/waves_yesno目錄瞧一瞧。

 

全部都是.wav格式的音頻文件。可以打開一個文件聽一聽,發現是一個老男人連續不停地說yes或者no,每個文件說8次。文件名中,0代表那個位置說的是no,1代表說的是yes。這個實驗沒有單獨的標註文件,直接採用的是文件名來標註的。

 

那個waves_yesno.zip.gz數據可以在http://www.openslr.org/resources/1/waves_yesno.tar.gz上下載,解壓到s5下面。也可以不下載,run.sh裏就幫你做好了。你在實驗前可以看下里面的說明文檔。

 

運行thchs30(清華大學中文語料庫)

 

https://blog.csdn.net/snowdroptulip/article/details/78943748

 

 

HCLG

 

L.fst: The Phonetic Dictionary FST

 

 

maps monophone sequences to words.

 

The file L.fst is the Finite State Transducer form of the lexicon with phone symbols on the input and word symbols on the output.

 

L_disambig.fst:The Phonetic Dictionary with Disambiguation Symbols FST

 

 

A lexicon with disambiguation symbols

 

 

G.fst:The Language Model FST

 

FSA grammar (can be built from an n-gram grammar).

 

C.fst:The Context FST

C maps triphone sequences to monophones.

Expands the phones into context-dependent phones.

 

H.fst:The HMM FST

H maps multiple HMM states (a.k.a. transition-ids in Kaldi-speak) to context-dependent triphones.

Expands out the HMMs. On the right are the context-dependent phones and on the left are the pdf-ids. 

 

HCLG.fst: final graph

 

 

總結一下:

 

 

構圖過程 G -> L -> C -> H

 

          G: 作爲 acceptor (輸入 symbol 與輸出相同),用於對grammar 或者 language model 進行編碼

          L:  Lexicon, 其輸出 symbol 是 words, 輸入 symbol 是 phones

          C:  context-dependency 其輸出 symbol 是 phones, 其輸入 symbol 爲表示context-dependency phones

 

              如: vector<int32> ctx_window = { 12, 15, 21 };

                      含義:id = 15 的 phone 爲 中心 phone, left phone id = 12, right phone id = 21

 

          H: 包括HMM definitions,其輸出 symbol 爲context-dependency phones, 其輸入 symbol 爲transitions-ids(即 對 pdf-id 和 其它信息編碼後的 id) 

 

         asl=="add-self-loops” 

          rds=="remove-disambiguation-symbols”, 

          and H' is H without the self-loops:

 

         HCLG = asl(min(rds(det(H' o min(det(C o min(det(L o G))))))))

 

 

ark文件與txt文件互相轉換

      這個很簡單,也只需要用到copy-feats命令

                     copy-feats ark:train.ark   ark,t:/train.txt           ark轉化爲txt

                     copy-feats ark,t:train.txt  ark:train.ark              txt轉化爲ark

 

總結:主要的文件轉化是通過copy-feats這個命令,它的主要功能是將文件變成數據流,這樣方便對數據進行處理。

     比如你想查看kaldi中提取的mfcc特徵到底是什麼樣子,同樣可以用copy-feats,如:

          copy-feats ark:train.ark   ark,t:-  | less

     通過一個管道用less來查看ark裏面的內容。

https://blog.csdn.net/by21010/article/details/51776447

 

命令行級 I/O 機制

命令行 I/O 是指在 shell 上調用編譯好的 Kaldi 工具的方法。比如,如果想查看音頻文件的時長,就可以使用這樣的命令 
wav-to-duration scp:wav.scp ark,t:- 
其中,wav-to-duration 是 Kaldi 中的查看時長的工具,後面兩個是參數。下面具體介紹命令行級 Kaldi 的 I/O。

非表格型I/O

非表格型的 I/O 一般比較簡單,一般是輸入輸出只包含一個或兩個對象的文件或流(比如,聲學模型文件,變換矩陣)。使用方式就是 shell 命令的使用方式。其中值得注意的有: 
- Kaldi 採用一種擴展的文件名進行輸入輸出。讀取文件的文件名稱爲 rxfilename , 寫入的文件名稱爲 wxfilename。 
- 在 rxfilename/wxfilename 處採用 “-” 來表示標準輸入輸出。 
- rxfilename/wxfilename 處可以使用管道命令,比如先用gunzip將壓縮文件解壓,再輸入到 Kaldi 程序中,即可在文件輸入路徑處填入 “gunzip -c foo.gz|”。 
- rxfilename/wxfilename 後可以通過 “:” 來描述偏移量,如 “foo:1045” 表示從 foo 文件偏移 1045 個字節開始讀取。 
- 使用 –binary=true/false 來控制是否使用二進制輸出。默認是true。 
- 有一組 copy* 命令,可以用來查看文件。如,copy-matrix –binary=false foo.mat -。 
- Log 信息和輸出會混在一起顯示,但是 Log 信息是 stderr 上,所以不會傳到管道中。可以通過添加 2>/dev/null 命令,將log信息重定向到 /dev/null。

下面列舉一些例子: 
echo ‘[ 0 1 ]’ | copy-matrix –binary=false - - 
將矩陣 [ 0 1 ] 輸入到 copy-matrix 中,再顯示出來。亦可以將其表示爲 
copy-matrix –binary=false ‘echo [ 0 1 ]|’ -

表格型I/O

對於一系列數據的集合,比如對應於每一句話的特徵矩陣,或者每一條音頻文件對應的路徑,Kaldi 採用表格形式的數據表示。表格中,以沒有空格的字符串爲索引。Kaldi 中,稱從表格文件中讀取的一個字符串爲 rspecifier, 寫入表格文件的一個字符串爲wspecifier。有兩種表格文件格式:archive 和 script 。其讀取方式和非表格型數據類似,也是使用 rxfilename/wxfilename的格式,其格式爲[options]:path:[offset]。需要在 options 中註明是archive文件還是script文件。例如 
wav-to-duration scp:wav.scp ark,t:-

rspecifiers 和 wspecifier

rspecifiers 和 wspecifier 是 Kaldi 中定義的兩種術語,是存在於表格文件中的文件名,格式類似於 rxfilename/wxfilename, 亦可以採用管道命令呢,對於ark文件,可以添加選項,如ark,s,cs:-等。

兩種存儲格式:script-file 和 archive-file

script-file 是一種文件指針,裏面包含的是具體文件所在路徑,其格式爲 
key rspecifier|wspecifier 
key 是字段名字,rspecifier/wspecifier則是文件路徑,rspecifier/wspecifier 可以有空格。例如 “utt1 gunzip -c /foo/bar/utt1.mat.gz”。 
archive-file 裏面裝的是實際的數據。其文件格式是 
key1 object1 key2 object2 key3 object3 … 
ark文件可以連接在一起,依然是一個有效的ark文件。但是如果需要的文件時有序的話,連接的時候應該要注意。 
ark文件和scp文件有可能同時寫,這時可以這麼寫:ark,scp:foo.ark,foo.scp。

特徵提取

對data下的train、dev和test數據分別調用下面兩個腳本

steps/make_mfcc.sh

特徵存在feats.scp中,存儲的特徵是每一幀13維,當用到mfcc特徵的時候才計算deltas和deltas-deltas,轉爲39維。
腳本主要爲下面幾行

  $cmd JOB=1:$nj $logdir/make_mfcc_${name}.JOB.log \
    compute-mfcc-feats  $vtln_opts --verbose=2 --config=$mfcc_config \
     scp,p:$logdir/wav_${name}.JOB.scp ark:- \| \
      copy-feats --compress=$compress ark:- \
      ark,scp:$mfccdir/raw_mfcc_$name.JOB.ark,$mfccdir/raw_mfcc_$name.JOB.scp \
      || exit 1;

其中$cmd爲run.pl

以data/train爲例

  • 檢查。檢查一些文件是否存在等
  • 根據變量$nj的大小,將data/train/wav.scp平分爲$nj份
  • 調用run.pl,提取特徵。一個JOB處理一份wav.scp,共$nj個JOB。用到程序compute-mfcc-featscopy-feats,生成mfcc/raw_mfcc_train.JOB.ark和對應的mfcc/raw_mfcc_train.JOB.scp文件,JOB爲1到$nj的數字。
  • 將$nj個mfcc/raw_mfcc_train.JOB.scp文件合成一個data/train/feats.scp文件
  • 檢查。檢查是否正確提取所有文件

steps/compute_cmvn_stats.sh

  • 對每個說話人計算cmvn(cepstral mean and variance normalization)。
  • 對每個說話人,對每一維(共13維)分別計算count/sum/sum-squared三組statistics,分別爲1維、13維、13維。count代表該說話人所有音頻文件的總幀數,sum代表所有幀裏每一維的和,sum-square代表所有幀裏每一維的平方的和。然後根據這三組statistics,計算均值和方差。
  • 可用copy-matrixs程序查看cmvn.scp或cmvn.ark文件,對每一個說話人,有一個28維的矩陣,前十三維是sum,然後是count,接着十三維是sum-squared,最後一個0。
  • 該腳本有三個選項:--fake--two-channel--fake-dims
    調用compute-cmvn-stats生成mfcc/cmvn_train.arkmfcc/cmvn_train.scp,然後將後者複製到data/train/cmvn.scp

https://blog.csdn.net/Xwei1226/article/details/80491538

https://blog.csdn.net/u010731824/article/details/69668765

ASR指標:

正確率:只要和原來的標籤相同就算正確。

準確率:除了要正確,還需要加上因爲插入其它詞造成的錯誤。

Correct(cor) = ( N − D − S )× 100% / N =  H× 100% / N
Accurac(acc) = ( N− D− S− I  )× 100% / N =  (H - I)× 100% / N
N- total number of labels (總標籤數)
D- deletion errors (刪除錯誤)
S-  substitution errors (替換錯誤)
I-  insertion errors (插入錯誤)

ASR指標統計工具:HTK HResults

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