Kaldi單音素GMM學習筆記

2021-07-30 06:24:36 字數 4273 閱讀 1397

目錄

類 學習資料:

統計學習方法–李航

語音識別實踐–俞棟,鄧力

speech and language processing—daniel jurafsky, james h. martin.

ediburg-course. (

個人理解:

論講解的清晰度、條理性,李航的書更好一些。俞棟的書則更貼近語音,並且該書的公式推導簡直清晰,一點都不含糊,比如前向後向公式的推導。

em演算法之前看過幾遍,總是似懂非懂。本次看em演算法,則是在我學習過《數理統計》這門課之後,因此在看em演算法的時候能加入引數估計、期望的一些背景知識去理解em演算法。主要有兩點要搞清楚,第一點,em演算法其實就是在分布已知(概率密度函式的形式已知)、引數未知的情況下去估計未知引數。這樣一來,估計gmm引數的em演算法的輸入輸出就較好理解了。第二點:em演算法是個迭代演算法,最後是可以收斂到區域性最優的。用上一輪計算出來的引數計算當前輪的一些值(比如帶入高斯分布公式算概率),然後去得到新的引數值。

在kaldi中,單音素gmm的訓練用的是viterbi training,而不是baum-welch training。因此就不是用hmm baum-welch那幾個公式去更新引數,也就不用計算前向概率、後向概率了。kaldi中用的是em演算法用於gmm時的那三個引數更新公式,並且稍有改變。

baum-welch演算法更新引數時,因為要計算前向後向概率,很費時間,因此使用viterbi training作為baum-welch演算法的近似。在baum-welch演算法中,計算前向後向概率時,要用到所有的狀態路徑,在viterbi訓練中,用viterbi路徑代替對所有狀態路徑的累積。

在viterbi訓練中,先根據上一輪的模型引數對語音特徵資料進行對齊,得到每一幀的特徵所對應的hmm狀態(在kaldi中是transition-id),也就是forced alignment。forced alignment的結果是對應於特徵序列的狀態序列。

舉個例子:

當前的特徵序列是o1, o2, o3, o4, o5, o6, o7.(每一幀的特徵是39維mfcc)

對應的狀態序列是7, 8, 8, 8, 9, 9, 10.(每個數字代表乙個hmm state)

知道了特徵序列和其對應的狀態序列,我們就可以通過簡單的數數來更新hmm的引數——轉移概率矩陣a。根據對齊結果,統計每乙個hmm狀態總共出現了多少次(可以從transition-id得到hmm state-id),統計該狀態的每乙個轉移出現了多少次(一般只有兩個轉移,轉移到自身和轉移到下一狀態),用每乙個轉移的出現次數除以該狀態的出現次數就得到了轉移概率。hmm引數就是這樣更新的。

首先應該明白,在單音素gmm訓練中,每乙個hmm狀態有乙個對應的gmm概率密度函式(pdf),所以有多少個hmm狀態,就有多少個gmm,也就有多少組gmm引數。在知道了特徵序列和對齊序列後,找出某乙個hmm狀態對應的所有觀測(比如狀態8對應的o2, o3, o4,在kaldi中則是找到某一transition-id對應的所有觀測),也就得到了該狀態對應的gmm所對應的所有觀測。知道了該gmm對應的所有觀測、該gmm的當前引數,就可以根據gmm引數更新公式更新gmm引數了,比如知道了狀態8對應的觀測o2, o3, o4。kaldi中所用的gmm引數更新公式如下圖所示。

kaldi的github分支kaldi-5.0裡,egs/wsj/s5/steps路徑下的train_mono.sh。

usage: steps/train_mono.sh [options] e.g.: steps/train_mono.sh data/train.1k data/lang exp/mono
初始化單音素模型。呼叫gmm-init-mono,生成0.mdl、tree。

編譯訓練時的圖。呼叫compile-train-graph生成text中每句抄本對應的fst,存放在fsts.job.gz中。

第一次對齊資料。呼叫align-equal-stats-ali生成對齊狀態序列,通過管道傳遞給gmm-acc-stats-ali,得到更新引數時用到的統計量。

第一次更新模型引數。呼叫gmm-est更新模型引數。

進入訓練模型的主迴圈:在指定的對齊輪數,使用gmm-align-compiled對齊特徵資料,得到新的對齊狀態序列;每一輪都呼叫gmm-acc-stats-ali計算更新模型引數所用到的統計量,然後呼叫gmm-est更新模型引數,並且在每一輪中增加gmm的分量個數。

usage: gmm-init-mono e.g.: gmm-init-mono topo 39 mono.mdl mono.tree
計算所有特徵資料每一維特徵的全域性均值、方差

讀取topo檔案,建立共享音素列表(根據$lang/phones/sets.int),根據共享音素列表建立ctx_dep(相當於tree)

每一組共享音素的乙個狀態對應乙個pdf。對每乙個狀態,建立只有乙個分量的gmm,該gmm的均值初始化為全域性均值、方差初始化為全域性方差。(實際上,此時表示gmm的類是diaggmm,該物件根據多維高斯分布的公式和對角協方差矩陣的特殊性,為了方便計算,直接儲存的引數並不是均值、方差,而是方差的逆(實際就是方差矩陣每個元素求倒數)、均值×方差的逆,還提前計算並儲存了公式中的常數部分(.mdl檔案gmm部分的

根據ctx_dep和topo建立轉移模型。將轉移模型、gmm聲學模型寫到0.mdl

將ctx_dep寫到tree.

usage: compile-train-graphs [options] e.g.: compile-train-graphs tree 1.mdl lex.fst ark:train.tra ark:graphs.fsts
該程式的輸出是ark格式的graphs.fsts(存為exp/mono/fst.job.gz),包含train.tra中的每個utt-id的fst,fst由無轉移概率的hclg組成。

暫時不用扣wfst相關的細節,只要明白這一步對於整個訓練過程用什麼用就可以了,後面專攻wfst部分**的時候可以把每個階段與wfst相關的部分串起來。

生成與音訊特徵對齊的hmm狀態序列時要用到每句話的fst。

usage: align-equal-compiled e.g.: align-equal-compiled 1.fsts scp:train.scp ark:equal.ali
對每一句話,根據這句話的特徵和這句話的fst,生成對應的對齊狀態序列。

usage: gmm-acc-stats-ali [options] e.g.: gmm-acc-stats-ali 1.mdl scp:train.scp ark:1.ali 1.acc;
對於每一幀的特徵和其對齊(transition-id):

處理完所有資料後,將tm和am的累積量寫到乙個檔案中:x.job.acc中

gmm-acc-stats-ali生成的累計量分散在job個檔案中,該程式將分散的對應同一trans-id、pdf-id的累計量合併在一起。

usage:  gmm-est [options] e.g.: gmm-est 1.mdl 1.acc 2.mdl
主要分兩部分,一部分更新transitionmodel,一部分更新gmm。

儲存乙個gmm的引數,包括分量權值weights_、均值、方差、每一分量高斯分布裡的常量部分取log後的數值gconsts_。注意均值和方差為了方便計算,儲存的並不是原原本本的均值、方差,而是方差每一元素求倒數後的inv_vars_、均值乘以inv_vars_後的means_invvars_。

對應於diaggmm的標準形式的gmm,儲存乙個gmm原原本本的引數:分量權重weights_,均值means_,方差vars_。

儲存所有的gmm。

對應於diaggmm,儲存引數更新時所需的累積量:

num_comp_:混合分量個數m

dim_:特徵維數

occupancy_:m個元素,每乙個元素是∑n

j=1γ

^jk

mean_accumulator_:mxd維,每一行是∑n

j=1γ

^jky

j variance_accumulator_:mxd維,每一行是∑n

j=1γ

^jky

2j對應於amdiaggmm,儲存所有的accumdiaggmm。

儲存hmm拓撲,log轉移概率,transition-id、transition-state、triplets(phone, hmm-state, forward-pdf)等之間的對映。

Kaldi單音子建模

gmm hmm和gmm nn 本質上並沒有什麼區別,基於神經網路的主流語音識別系統仍基於hmm,只不過是用神經網路來代替gmm建模hmm狀態的觀察概率 1 特徵提取 特診提取指令碼會讀取資料資料夾中的音訊表單,並依次進行特徵提取,將結果寫入資料資料夾中的聲學特徵表單,要求輸入音訊的取樣大小為16位元...

kaldi中修改phones中音素個數

在工程專案中,有一天專案組說我們做語音評測的不需要這麼多音素來表示,我們的產品英語語音評測是參考libirispeech中的指令碼來修改的,預設是有360多個音素來表示的,檢視phones.txt檔案中,發現實際上音素包含有位置資訊。kaldi中修改音素個數,將指令碼中prepare lang.sh...

語音識別之HTK入門(三) 單音素單高斯模型

前面兩節介紹了語音識別的一些概念,並進行資料的預處理。現在我們有了音訊資料轉化為mfcc特徵向量的檔案,以及與每個特徵檔案相對應的音素資訊檔案。現在進入模型構建部分,包括兩個核心部分,一是如何表示音素概率分布 二是如何建模音素間的轉移關係。首先,給個總結性的描述。最初的系統是通過隱馬爾可夫模型 hm...