Kaldi thchs30手札(二)L.fst與G.fst
歡迎大家關注我的博客 http://pelhans.com/ ,所有文章都會第一時間發布在那裡哦~
本部分是對Kaldi thchs30 中run.sh的代碼的line 38-60行研究和知識總結,重點是word-graph的建立。
概覽
先把代碼放在這裡:
prepare language stuff
build a large lexicon that invovles words in both the training and decoding.
(
echo "make word graph ..."
cd $H; mkdir -p data/{dict,lang,graph} &&
cp $thchs/resource/dict/{extra_questions.txt,nonsilence_phones.txt,optional_silence.txt, silence_phones.txt} data/dict &&
cat $thchs/resource/dict/lexicon.txt $thchs/data_thchs30/lm_word/lexicon.txt |
grep -v | grep -v | sort -u > data/dict/lexicon.txt || exit 1;
utils/prepare_lang.sh --position_dependent_phones false data/dict "" data/local/ lang data/lang || exit 1;
gzip -c $thchs/data_thchs30/lm_word/word.3gram.lm > data/graph/word.3gram.lm.gz || exit 1;
utils/format_lm.sh data/lang data/graph/word.3gram.lm.gz $thchs/data_thchs30/lm_word/lexicon.txt data/graph/lang || exit 1;
)
其中$H是指的是thchs30/s5這個路徑,$thchs30指的是前面設置的語音語料庫路徑。
頭五行為提示開始製作,進入主目錄並建立dict,lang,graph三個文件夾,然後講語音資料庫中dict下的文件考到data/dict目錄下。用cat命令顯示字典文件並用grep查找不包含 和 字元的行並輸入到lexicon.txt文件中。
utils/prepare_lang.sh 構建字典L.fst文件,該文件不包含消岐符。
gzip -c這行是解壓語言模型。
utils/format_lm.sh 該行是為了生成G.fst文件和並檢查它是否包含空環。
可以看出重點就是兩個utils/*的腳本,下面我們詳細介紹它倆。
prepare_lang.sh
該程序的參數在文件開頭有詳細的說明,這裡挑選使用到的參數翻譯一下:
1) --position_dependent_phones false: 是否將phone拆成更詳細的部分,若選擇true,則將在phone後面根據音素所處的位置加上
2) data/dict: 詞典源文件夾 。
3) :詞典裏未包含的事例, .
4) data/local/lang : 臨時文件夾
5) data/lang: 目標文件夾。
6) share_silence_phones:在構造出的roots.txt文件中,其中的所有sil共享同一個高斯pdf。需要注意的是若選擇共享也只是共享pdf,轉移概率還是不一樣的。
這裡對roots.txt文件詳細解釋一下,在同一行出現的所有音素對應的HMM會共享它們的pdf-class根節點,如果不共享的話就放在不同行。
roots.txt每行開頭都包含(not)shared和(not)split的修飾,share代表對於每個HMM(例如有三個狀態),是否所有的狀態共享一個根節點(如三個狀態共享一個根節點),not-shared就是每個狀態都有不同的根節點。(not)split則表示對於上述的每個根節點,是否有機會根據問題進行決策樹分裂,如果為split,則允許進行分裂,分裂後同一行中的不同音素對應的HMM狀態可能會有不同的pdf-class。如果是not-split,則不允許分裂,同一行中的所有音素對應的HMM將固定共享它們的pdf-class而不發生分裂。在thchs30中該選項是false同時不進行共享。
到這裡用到的選項我們就解釋完了,下面從頭到尾把用到的部分代碼解釋一下。
line 85-129是各種輸入文件的檢查和整理。其中:
1. lexicon.txt文件是字典文件,格式為 .2. lexiconp.txt是帶概率的字典文件,概率值為每個詞出現的概率,格式為: .
3. silence_phones.txt/nonsilence_phones.txt為靜音/非靜音音素,每一行代表一組相同的base phone,但可能有不同的中銀或者聲調的音素,如: 。
4. optional_silence.txt:包含一個單獨的音素用來作為詞典中默認的靜音音素。
5. extra_questions.txt:用來構建決策樹的問題集,可以是空的,包含多組相同的音素,每一組音素包含相同的重音或者聲調;也有可能是一致表示非語音的靜音/噪音音素。這可以用於增加自動生成問題的數量。
line 131-203:當你選擇position_dependent_phones是true時,根據lexiconp.txt文件在每個詞的音素後面添加位置標記.
line 209-230: 執行上面建立roots.txt文件的過程。若share_silence_phones為true則共享sil,若為false則直接將shared 和split加到roots.txt文件頭並且將需要共享的音素放到一行即可。
line 232-237: 使用utils/apply_map.pl將源文件夾下的音素映射到phones/下的對應文件。(map程序說自己applies a map to things in a file...這個things..等我有時間好好看看這貨幹嘛的,不過我對比了下,倆文件除了多個空格沒有其他區別。。。)
line 243-253: 根據音素的位置來添加extra questions.
line 255-284: 字典中的詞可能會出現同個發音的情況,這裡在同音詞的發音標註後面加入消岐符(disambig sysmbols,長這樣#1)來進行區分,字典中有多少同音詞就會有多少個消岐符。
line 286-296: 為每個音素創建描述詞邊界信息的文件。
line 298-345: 創建辭彙-符號表。這個表中的內容就是所有辭彙和符號與數字的對應;如
這樣。
line 347-362: 創建align_lexicon.{txt,int}文件,大體操作為從lexiconp.txt中移除概率部分。
line 364-386: 創建不包含消岐符的的L.fst文件用於訓練使用。使用的是utils/make_lexicon_fst.pl,它將詞典中的單詞和音素轉換成fst輸入格式的文件。內部存儲格式為:
line 389-412: 主要是格式轉換,將各個文本轉換成前面映射得到的數字表示。
line 415-433: 創建完整的L.fst文件。
format_lm.sh
該程序的主要目標就是根據語言模型生成G.fst文件。方便與之前的L.fst結合,發揮fst的優勢。腳本最後會檢測G.fst中是否存沒有單詞的空環,如果存在就會報錯,這回這會導致後續HLG的determinization出現錯誤。其程序核心就是arpa2fst
L.fst 與 G.fst
可以看出,上面兩個程序的主要目標就是創建L.fst和G.fst,那麼這兩個文件是什麼呢?它們的作用又是什麼呢?
fst文件根據它的顯示圖我猜測應該是有限狀態轉換機(Finite State Transducer)的縮寫,FST允許聲學信息(HMM集合)、單詞發音、語言模型和識別語法的單獨的統一的表示。由於該統一表示,導致在遍歷搜索網路期間,可以執行計算花費不大的計算,而其他計算花費大的優化能夠被卸下到預編譯階段進行。
知道它是個有限狀態轉換機,剩餘的就好辦的多了,以L.fst來說,它在轉換之前是一個帶有概率和消岐符的字典文件,長的是下面這個樣子: