AIBigKaldi(五)| Kaldi的單音子模型訓練(上)
本文來自公眾號“AI大道理”
提取了MFCC特徵,並進行倒譜均值方差歸一化,資料檢查無誤後就可以進行模型訓練了。
首先進行的是單音素模型訓練,然後進行三音子模型訓練。
單音子模型為後期訓練提供對齊基礎。
以kaldi中的yesno為例。
1 單音子模型訓練
3 train_mono.sh
原始碼解析:
Usage: steps/train_mono.sh [options] <data-dir> <lang-dir> <exp-dir>
過程之道:
初始化模型->生成訓練圖HCLG.fst->對標籤進行初始化對齊->統計估計模型所需的統計量->估計引數得到新模型->迭代訓練->最後的模型final.mdl。
在迭代訓練中:
使用gmm-align-compiled對齊特徵資料,得到新的對齊狀態序列;
呼叫gmm-acc-stats-ali計算更新模型引數所用到的統計量;
呼叫gmm-est更新模型引數,並且在每一輪中增加GMM的分量個數。
2初始化模型
3.1 gmm-init-mono.cc
功能:
初始化模型
是最基礎的模型。
這是不需要任何訓練資料就可以得到的模型。
(無中生有)
輸入:HMM的拓撲結構,特徵維度
輸出:模型、決策樹
原始碼解析:
過程之道:
-
初始化全域性特徵的均值和方差glob_inv_var,glob_mean均為1,大小等於特徵維度。如果有輸入特徵,另外再計算更新。
-
讀入拓撲結構HmmTopology,建立裡面所有phone到該phone的Pdf class數目的對映。
-
構建決策樹,只需要根據set.int檔案遞迴的構造樹。
-
gmm-init-mono構建GMM。每個pdf初始化只有一個gmm,也就是單高斯,均值方差來自之前的glob_inv_var,glob_mean, weight為1,均值方差也都為1,計算常數部分gconsts 即高斯分佈x為0時的概率。
-
將所有gmm模型匯入聲學模型am_gmm中。最後輸出transition和聲學模型的檔案model,決策樹tree。
初始化模型結果:
這已經是一個完整的聲學模型了,可以用它來進行語音識別,只是識別率不高。
0.mdl的內容如下:
/kaldi-trunk/src/gmmbin/gmm-copy --binary=false exp/mono0a/0.mdl -
0.mdl包含TransitionModel轉移模型和多個DiagGMM高斯模型。
其中:
拓撲結構:
三狀態HMM(非靜音)
可見共6個轉移弧。
五狀態HMM(靜音)
可見共4*4+2=18個轉移弧。
音素 hmm狀態:
1號是靜音因素有5個HMM狀態,用01234表示,其他因素只有3個狀態,用012表示 。
pdf-id就是0-10,每個狀態對應一個GMM分佈。
取對數之後的轉移概率:
轉移弧個數31=2*6+1*18+1
其中第一個0是因為transition-id是從1開始,在所有轉移弧前補充一個0。
高斯模型:
維度39維(沒有能量),pdf-id個數為11個,引數包含means_invvars均值和inv_vars方差、權重、每一分量高斯分佈裡的常量部分取log後的數值。
得到了初始化的模型0.mdl, 2個音素,11個狀態。
每個狀態對應一個只包含一個高斯分量的GMM。
可以直接用這個模型進行語音識別,但效果會很差。
後續的引數迭代中要更新每個狀態的HMM轉移概率和GMM的均值向量以及協方差矩陣,同時進行單高斯分量到混合高斯分量的分裂。
tree
檢視tree內容:
/kaldi-trunk/src/bin/copy-tree --binary=false tree -
檔案之後的內容,是遞迴儲存了一棵決策樹。
構造決策樹的過程:
CE(Constant EventMap):葉子節點,直接儲存該節點存放的transition ID;
SE(Split EventMap):非葉子節點,儲存左右子節點yes,no等等;
TE(Table EventMap):非葉子節點,儲存節點數以及各個子節點的指標。
3 預編譯訓練圖
3.2 compile-train-graphs.cc
功能:
訓練用每句話轉換成一個FST結構,輸入是音素,輸出是整個句子。
輸入:tree , transition_model ,L.fst(Lexicon),訓練檔案標註。
輸出:為圖 HCLG.fst
標註文字:
為什麼需要訓練圖?
kaldi訓練模型並不是採用理論中的Baum-Welch演算法的軟對齊,實踐中是使用Vitrerbi演算法進行硬對齊。
(可見理論和實踐的差異。)
為了獲得每一幀對應的狀態號作為訓練的標籤,需要構建一個直線形的狀態圖。
在這個圖上利用Viterbi演算法求得最優路徑,同時得到幀與狀態的對齊。
原始碼解析:
構造結果:
狀態圖是一個直線型的圖,包含了標註文字的狀態序列,同時每個狀態有指向自身的跳轉即self-loop。
在monooa目錄下執行:
/kaldi-trunk/src/bin/compile-train-graphs --read-disambig-syms=../../data/lang/phones/disambig.int tree 0.mdl ../../data/lang/L.fst 'ark:../../utils/sym2int.pl --map-oov 1 -f 2- ../../data/lang/words.txt < ../../data/train_yesno/split1/1/text|' ark,t:HCLG.fst.txt
去掉0_0_0_0_1_1_1_1和其他語音,儲存。
轉化為fst圖:
fstcompile HCLG.fst.txt HCLG.fst
視覺化:
fstdraw --isymbols=phones.txt HCLG.fst | dot -Tps > HCLG111.ps
放大:
整體來看這個狀態圖是一個直線型的圖,包含了標註文字的狀態序列,同時每個狀態有指向自身的跳轉即self-loop。
圓圈表示的就是狀態,裡面的數字是狀態的id。
弧上面,冒號前面的數字是transition-id,冒號後面的數字是輸出的音素;斜槓後面的數字是權重。
只包含標註文字的狀態序列。
(構造訓練圖是基於抄本構建的,比後面的構造解碼圖要簡單些,所採用的程式碼也不一樣。)
4 模型訓練
構造好訓練圖接下來就可以進行訓練了。
所謂訓練就是在訓練圖上進行解碼,獲得最優路徑的同時得到對齊序列,根據對齊序列進行統計資訊量。
轉移概率可以進行數數獲得,GMM引數隨著對齊的幀數變化而更新,同時GMM分量從一開始的單高斯split出更多的高斯。
如此不斷迭代訓練獲得單音子模型。
下期預告
AIBigKaldi(六)|Kaldi的單音子模型訓練(下)
往期精選
AI大語音(十四)——區分性訓練
AI大語音(十三)——DNN-HMM
AI大語音(十二)——WFST解碼器(下)
AI大語音(十一)——WFST解碼器(上)
AI大語音(十)——N-gram語言模型
AI大語音(九)——基於GMM-HMM的連續語音識別系統
AI大語音(八)——GMM-HMM聲學模型
AI大語音(七)——基於GMM的0-9語音識別系統
AI大語音(六)——混合高斯模型(GMM)
AI大語音(五)——隱馬爾科夫模型(HMM)
AI大語音(四)——MFCC特徵提取
AI大語音(三)——傅立葉變換家族
AI大語音(二)——語音預處理
AI大語音(一)——語音識別基礎
——————
淺談則止,細緻入微AI大道理
掃描下方“AI大道理”,選擇“關注”公眾號
—————————————————————
—————————————————————