一.前提條件
在kaldi目錄下的子目錄kaldi/egs/目錄下保存着資源管理示例腳本。查看該目錄中的README.txt文件,尤其是查看資源管理部分,它提到 與語料庫相對應的LDC目錄號。這可以從LDC獲取數據。
進入rm目錄,瀏覽README.txt文件查看整體結構,進入s5子目錄,在s5目錄中,列出並瀏覽RESULTS文件,以便對其中的內容有所了解。其中最重要的文件是run.sh。注意,run.sh不能直接執行,必須手動執行文件中的一系列命令。
二.資料准備
首先,需要配置作業,如果沒有安裝GridEngine【分布式資源管理工具】,或者是使用較小的數據集進行實驗,可以在shell上執行以下命令:
如果安裝了GridEngine,則應將queue.pl文件與指定GridEngine駐留位置的參數一起使用。在這種情況下,執行以下命令【參數-q是示例,在實際應用中替換為GridEngine詳細信息】:
train_cmd=" queue.pl -q all.q@a*.clsp.jhu.edu"
encode_cmd="queue.pl -q all.q@[ah]*.clsp.jhu.edu"
下一步是從rm語料庫中創建測試和訓練集。為此,執行以下命令【假設要測試的數據在./export/LDC/LDC2019S20/rm_comp/下,此數據可以去KALDI下載,需要付費】
命令:./local/rm_data_prep.sh /export/LDC/LDC2019S20/rm_comp/
執行成功后,會在當前目錄下創建data的新目錄。這個新目錄包含三種主要的文件夾類型:
·local:包含當前數據的字典。
·train:從語料庫中分割出來的用於訓練的數據。
·test_*:從語料庫中分割出來的數據,用於測試。
在數據目錄下執行下面的命令:
cd local/dict
head lexicon.txt
head nonsilence_phones.txt
head silence_phones.txt
使用這些命令可以大致了解通用數據准備過程的輸出。應該意識到,並非所有的這些文件都是本地Kaldi格式,即,並非所有文件都可以被Kaldi的C++程序讀取,部分還需要使用Kaldi之前使用OpenFST工具進行處理。
lexicon.txt:詞典
*silence*.txt:這些文件包含有關電話靜音已經保持靜音的信息。
在train目錄下,執行以下命令:
head text
head spk2gender
head spk2utt
head utt2spk
head wav.scp
·text:該文件包含發聲和發聲ID之間的映射,這些映射將由Kaldi使用。該文件將轉換為整數格式,但仍然是文本文件,單詞將被替換為整數。
·spk2gender:該文件包含說話人及其性別之間的映射。這將充當參與培訓的唯一用戶列表。
.spk2utt:這是說話者標識符與說話者相關的所有話語標識符之間的映射。
.utt2spk:這是發話ID與相應說話者標識符之間的一對一映射。
·wav.scp-Kaldi程序在進行特征提取時實際上直接讀取該文件。再次查看該文件,它被解析成一組鍵值對,其中鍵是每一行的第一個字符串。該值是一種“擴展文件名”。請注意,盡管我們使用擴展名.scp,但從HTK的角度來看,它不是腳本文件。
train文件夾和test_*文件夾的結構相同。但是,train數據的大小明顯大於test_*數據。可以通過返回數據目錄並執行以下命令來驗證這一點,該命令將給出訓練集和測試集的字數:wc train/text test_feb89/text
下一步是創建Kaldi使用的原始語言文件。在大多數情況下,這些文件將是整數格式的文本文件。確保返回到s5目錄,並執行以下命令:
utils/prepare_lang.sh data/local/dict '!SIL' data/local/lang data/lang
這將在本地文件夾中創建一個名為lang的新文件夾,其中將包含描述所用語言的FST。看一下腳本。它將以data/創建的某些文件轉化為Kaldi讀取的規范形式。該腳本在data/lang/目錄中創建其輸出。該腳本創建的前兩個文件稱為words.txt和phones.txt【都在data/lang/下】。這些是OpenFst格式的符號表,表示從字符串到整數再到整數的映射。查看這些文件,它們很重要並且會經常使用。
查看后綴為.csl的文件【在data/lang/phones中】,這些分別是冒號分隔的非靜音和靜音電話的整數ID列表。有時需要它們作為程序命令行上的選項,以及其它目的。
查看phone.txt【在data/lang/中】,該文件是電話符號表,還處理標准FST中使用的"消歧符號"。這些符號通常稱為#1,#2等。其中符號#0用來替換語言模型中的epsilon轉換。
文件L.fst是FST格式的編譯詞典。要查看其中包含哪種信息,可以執行以下操作:
fstprint --isymbols=data/lang/phones.txt --osymbols=data/lang/words.txt data/lang/L.fst | head
如果bash找不到命令fstprint,則需要將OpenFST的安裝路徑添加到PATH環境變量中。只需要運行腳本path.sh即可:
../path.sh
下一步是使用在上一步中創建的文件來創建描述該語言語法的FST。為此,返回目錄s5並執行以下命令:
./local/rm_prepare_gtammar.sh
如果成功,則應該返回消息"成功為RM准備語法"。將在/data/lang中創建一個名為G.fst的新文件。
三.特征提取
1.提取訓練功能
export featdir=/my/disk/rm_mfccdir # make sure featdir exists and is somewhere you can write. # can be local if you want. mkdir $featdir for x in test_mar87 test_oct87 test_feb89 test_oct89 test_feb91 test_sep92 train; do \ steps/make_mfcc.sh --nj 8 --cmd "run.pl" data/$x exp/make_mfcc/$x $featdir; \ steps/compute_cmvn_stats.sh data/$x exp/make_mfcc/$x $featdir; \ done
運行這些作業,它們並行使用多個CPU,可以根據計算機的CPU數量更改-nj選項【指定要運行的作業數量】。查看文件exp /make_mfcc/train/make_mfcc.1.log以查看創建MFCC程序的日志輸出。
2.核心概念
表的概念是基礎腳本和歸檔文件。表格基本上是一組有序的項目,由唯一的字符串索引。Table並不是真正的C++對象,因為有單獨的C++對象來訪問數據,具體取決於我們是編寫、迭代還是進行隨機訪問。類型的示例數據如下:
BaseFloatMatrixWriter
RandomAccessBaseFloatMatrixReader
SequentialBaseFloatMatrixReader
這些類型都是實際為模板類的typedef。腳本【.scp】文件或存檔【.ark】文件都被視為數據表。格式如下:
·腳本格式是純文本格式,其中包含帶有鍵的行,然后是擴展文件名,該文件名告訴Kaldi在哪里可以找到數據。
·存檔格式可以是文本或二進制。格式為鍵+空格+對象數據。
有關腳本和檔案的一些一般要點:
·指定如何讀取表的字符串稱為rspecifier。例如:ark:gunzip -c my/dir/foo.ark.gz|
·指定如何編寫表的字符串稱為wspecifier。例如:ark,t:foo.ark
·歸檔可以串聯在一起,仍然是有效的歸檔。
·該代碼可以順序或通過隨機訪問讀取腳本和存檔。用戶級代碼僅知道它是在迭代還是在進行查找。它不知道它是在訪問腳本還是存檔。
·Kaldi不會嘗試在歸檔文件中表示對象類型。必須提前知道對象類型。
·歸檔文件和腳本文件不能包含類型的混合。
·由於代碼可能必須將對象緩存在內存中,因此通過隨機訪問讀取檔案可能會導致內存效率低下。
·為了有效地隨機訪問檔案,可以使用ark,scp寫入機制來寫入相應的腳步文件。然后通過scp文件訪問它。
·避免對文檔進行隨機訪問時內存中緩存了大量數據。
·對代碼文檔進行排序並且按照順序進行調用。
·讀寫檔案的類型以Holder類型為模板,該類型知道如何讀取和寫入相關對象。