kaldi特徵和模型空間轉換

kaldi特徵和模型空間轉換

博主話:這篇博客是對kaldi官網中Feature and model-space transforms in Kaldi 的翻譯,因爲不是專業翻譯人士,接觸kaldi時間也不長,所以難免有紕漏之處,希望讀者如果有更好的建議和意見,可以在下面留言,有助於更好的交流,謝謝大家



介紹

Kaldi代碼目前支持許多功能和模型空間的轉換和預測。特徵空間變換和預測以一致的方式被工具(它們在基本上只是矩陣)處理,以下部分涉及到共同點:

通常不具有說話人特徵的變換,預測和其他功能操作包括:

通常以說話人自適應方式應用的全局變換是:

接下來討論使用它們的迴歸類樹和變換:

應用全局線性或仿射特徵變換


在特徵空間變換和全局投影(不與類相關聯的情況下)(例如語音/不發音或迴歸類)的情況下,我們將它們表示爲矩陣。線性變換或投影被表示爲一個矩陣,通過將這個矩陣左乘以特徵向量,得到變換後的特徵是$ A x $。仿射變換或投影以相同的方式表示,但是我們假設1已經被附加到特徵向量上,所以變換的特徵是$ W \ left [\ begin {array} {c} x \\ 1 \ end {array} \ right] $,其中$ W = \ left [A;  b \ right] $,A和b是線性變換和常數偏移。請注意,該約定與一些文獻不同,其中1可能表現爲第一維而不是最後一個維度。全局變換和投影通常以Matrix <BaseFloat類型寫入單個文件,

transform-feats中transforms 可以用來表示features。它的語法是

 transform-feats <transform> <input-feats> <output-feats>

其中<input-feats>是一個rspecifier,<output-feats>是一個wspecifier,而<transform>可能是一個rxfilename或rspecifier(請參閱指定表格式:wspecifiers和rspecifiers以及擴展文件名:rxfilenames和wxfilenames)。該程序將根據矩陣的列數是否等於特徵維度,或者等於特徵維度加上一個值,來確定變換是線性還是仿射。該程序通常用作管道的一部分。一個典型的例子是:

 feats="ark:splice-feats scp:data/train.scp ark:- |
          transform-feats $dir/0.mat ark:- ark:-|"
 some-program some-args "$feats" some-other-args ...

這裏,文件0.mat包含單個矩陣。應用說話人特定轉換的示例是:

 feats="ark:add-deltas scp:data/train.scp ark:- |
   transform-feats --utt2spk=ark:data/train.utt2spk ark:$dir/0.trans ark:- ark:-|"
 some-program some-args "$feats" some-other-args ...

一個完整的例子將如上所述,但刪除了-utt2spk選項。在本例中,文件0.trans將包含由speaker-id索引的變換(例如CMLLR變換),文件數據/ train.utt2spk將具有“utt-id spk-id”形式的行(參見下一節更多的解釋)。transform-feats不關心如何估計轉換矩陣,它只適用於功能。在經過所有特徵之後,它打印出每幀的平均對數行列式。當比較目標函數時,這可以是有用的(這個對數行列式必須被添加到像gmm-align,gmm-acc-stats或gmm-decode-kaldi這樣的程序打印出來的每幀可能性上)。如果變換的線性部分A(即忽略偏移項)不是方陣,那麼該程序將打印出$ \ frac {1} {2} \ mathbf {logdet}(AA ^ T)$,即僞對數行列式。當變換矩陣是MLLT矩陣乘以LDA矩陣時,對檢查MLLT估計的收斂性很有用



說話人獨立與每個說話人相對於每個發音匹配









估計變換通常設置爲進行特定類型的匹配,即與說話人無關的(特定說話人或語音)。例如,LDA和MLLT / STC變換是與說話人無關的,但是fMLLR變換是​​特定說話人或特定語音的。估計特定說話人或語音轉換的程序默認情況下將按照發音模式工作,但如果提供了-spk2utt選項,則在每個說話人模式下(見下文)。

transform-feats既可以接受與說話人無關也可以接受特定說話人或語音轉換。此程序檢測第一個參數(變換)是否爲rxfilename(請參閱擴展文件名:rxfilenames和wxfilenames)或rspecifier(請參閱指定表格式:wspecifiers和rspecifiers)。如果是前者,則將其視爲與說話人無關的變換(例如,包含單個矩陣的文件)。如果後者有兩個選擇。如果沒有提供-utt2spk選項,則將轉換視爲由utterance id索引的矩陣表。如果提供了一個-utt2spk選項(utt2spk是由包含speaker id的utterance索引的字符串表),那麼這個變換被定爲由speaker id索引。


發音到說話人和說話人到發音的映射


在這一點上,我們總結一下-utt2spk和-spk2utt選項。處理轉換的程序和當你正在做每個說話人(而不是每個話語)的匹配時,都會用到它們。通常,處理已經創建的變換的程序將需要-utt2spk選項,創建轉換的程序將需要-spk2utt選項。一個典型的例子是會有一個名爲/ utt2spk的文件,如下所示:

spk1utt1 spk1
spk1utt2 spk1
spk2utt1 spk2
spk2utt2 spk2
...

這些字符串只是示例,它們代表通用的說話者和話語標識符; 並且會有一個名爲/ spk2utt的文件,如下所示:

spk1 spk1utt1 spk1utt2
spk2 spk2utt1 spk2utt2
...

並且您將提供看起來像-utt2spk = ark: / utt2spk或-spk2utt = ark:/ spk2utt的選項。'ark:'前綴是必需的,因爲這些文件由Table 代碼作爲rspecifier給出,並被解釋爲包含字符串(或者在spk2utt情況下的字符串向量)的歸檔。請注意,utt2spk通常以隨機訪問方式訪問,因此,如果正在處理數據子集,則可以安全地提供整個文件,spk2utt通常以順序的方式訪問,因此,如果使用數據子集你將要拆分spk2utt。

接受spk2utt選項的程序通常會遍歷spk2utt文件中的speaker-id,並且對於每個speaker-id,它們將遍歷每個演講者的話語(utterances),累加每個話語的統計信息。然後訪問特徵文件將處於隨機訪問模式,而不是正常的順序訪問。這需要設置一些注意事項,因爲特徵文件相當大,並且fully-processed 的特徵通常要從存檔讀取(如果不仔細設置,則不允許最高效的內存隨機訪問)。爲了避免在這種情況下訪問功能文件時出現內存膨脹,建議確保所有歸檔按照utterance-id進行排序,提供給-spk2utt選項的文件中的說話按排序順序顯示,並且在指定向這些程序輸入的特徵的rspecifier中給出了適當的選項(例如“ark,s,cs: - ”,如果它是標準輸入)。請參閱Avoiding memory bloat when reading archives in random-access mode ,以便進一步討論此問題。


組合變換


另一個接受泛型變換的程序是compose-transforms。一般語法是“compose-transforms a b c”,它執行乘法c = ab(如果a是仿射,則比矩陣乘法多一點運算量)。從腳本修改的示例如下:

 feats="ark:splice-feats scp:data/train.scp ark:- |
         transform-feats
           \"ark:compose-transforms ark:1.trans 0.mat ark:- |\"
           ark:- ark:- |"
 some-program some-args "$feats" ...

該示例還說明了使用從程序調用的兩個級別的命令。這裏,0.mat是一個全局矩陣(例如LDA),而1.trans是一組由utterance id索引的fMLLR / CMLLR矩陣。compose-transforms將轉換組合在一起。相同的特徵可以更簡單地計算,但是效率較低,如下所示:

 feats="ark:splice-feats scp:data/train.scp ark:- |
         transform-feats 0.mat ark:- ark:- |
         transform-feats ark:1.trans ark:- ark:- |"
 ...

通常,作爲組合變換的輸入的變換a和b可以是與說話人無關的變換或特定說話人或語音的變換。如果a是特定語音的,b是特定說話人的,那麼你必須提供-utt2spk選項。然而,不支持如果a是特定語音的,b是特定說話人的組合(當然這也沒有太大意義)。如果a或b是tables,組合轉換的輸出將是一個table。三個參數a,b和c可以代表table或正常文件(即{r,w}specifiers或{r,w} xfilenames),但須符合一致性要求。

如果a是仿射變換,爲了正確地執行組合,組合變換需要知道b是仿射還是線性(它不知道,因爲它不能訪問由b轉換的特徵的維度)。這由選項-b-is-affine(bool,default false)控制。如果b是仿射的,但是您忘記設置此選項,並且a是仿射,則組合轉換將b看做是實際輸入特徵維度加1的線性變換,並將輸出實際輸入特徵維度加2的變換。當轉換功能應用於特徵時,沒有辦法用“transform-feats”來解釋這一點,所以在這一點上,錯誤應該變得明顯。


估計變換時的靜音權重


估計說話人自適應變換(如CMLLR)時,消除靜音幀是非常有用的。當使用迴歸樹的多類方法(參見構建迴歸樹進行適應)時,這似乎也是正確的。我們實現這一點的方式是通過降低與靜音音素相關的後驗概率,這相當於對狀態水平後驗概率的改善。下面提供了一個bash shell腳本的一部分(此腳本在Global CMLLR / fMLLR轉換中有更詳細的討論):

ali-to-post ark:$srcdir/test.ali ark:- | \
  weight-silence-post 0.0 $silphones $model ark:- ark:- | \
  gmm-est-fmllr --fmllr-min-count=$mincount \
    --spk2utt=ark:data/test.spk2utt $model "$sifeats" \
   ark,o:- ark:$dir/test.fmllr 2>$dir/fmllr.log

這裏,shell變量“silphones”將被設置爲無聲電話的整數id的冒號分隔列表。


線性判別分析(LDA)轉換


Kaldi通過LdaEstimate類支持LDA估計。該類不直接與任何特定類型的模型交互; 它需要使用類的數量進行初始化,累加函數被聲明爲:

class LdaEstimate {
  ...
  void Accumulate(const VectorBase<BaseFloat> &data, int32 class_id,
                  BaseFloat weight=1.0);
};

程序acc-lda將聲學狀態(即pdf-id)作爲類來累計LDA統計量。它需要轉換模型,以便將對齊(以transition-id表示)與pdf-id進行映射。然而,它不限於特定類型的聲學模型。

est-lda是LDA估計(它讀入acc-lda的統計數據)。從變換中獲得的特徵將具有單位方差,但不一定爲零。程序est-lda輸出LDA變換矩陣,並且使用選項-write-full-matrix可以寫出沒有降維的完整矩陣(其第一行將等效於LDA投影矩陣)。當使用LDA作爲HLDA的初始化時,這可能很有用。


框架拼接


通常在LDA之前對原始MFCC特徵進行幀拼接(例如,將九個連續的幀拼接在一起)。程序splice-feats這樣做。使用此腳本的典型行如下:

feats="ark:splice-feats scp:data/train.scp ark:- |
        transform-feats $dir/0.mat ark:- ark:-|"

並且“feats”變量稍後將被某些需要讀取功能的程序用作rspecifier(參見 指定表格式:wspecifiers和rspecifiers)。在這個例子中,因爲我們使用默認值(-left上下文= 4,右上下文= 4,總共9個幀),我們沒有指定拼接在一起的幀數。


Delta特徵計算


delta功能的計算由程序add-deltas完成,它使用ComputeDeltas函數。delta特徵計算具有與HTK相同的默認設置,即,通過值[-2,-1,0,1,2]的滑動窗口來計算乘以特徵的第一個增量特徵,然後通過除以(2 ^ 2 + 1 ^ 2 + 0 ^ 2 + 1 ^ 2 + 2 ^ 2 = 10)。通過對第一個增量特徵應用相同的方法來計算第二個增量特徵。每一邊上下文的幀數由-delta-window(默認值:2)控制,並且要添加的增量特徵數由-delta-order(默認值:2)控制。使用這種方式的典型腳本行是:

feats =“ark:add-deltas --print-args = false scp:data / train.scp ark: -  |”


異方差線性判別分析(HLDA)


HLDA是使用最大似然估計的降維線性特徵投影,其中使用全局平均值和方差對“被拒絕”維度進行建模,並且“接受的”維度用特徵模型建模,其均值和方差是通過最大似然估計的。目前與工具集成的HLDA的形式在HldaAccsDiagGmm中實現。使用相對緊湊的統計形式來估計GMM的HLDA,這些類對應於模型中的高斯。由於它不使用標準估計方法,我們將在此解釋這個想法。首先,由於內存限制,我們不想存儲HLDA統計量(每個類的平均值和全協方差統計最大形式。我們觀察到,如果在HLDA更新階段,我們將方差保持固定,則HLDA估計的問題將降低到MLLT(或全局STC)估計問題。參見“用於隱馬爾可夫模型的半綁合協方差矩陣”,由Mark Gales,IEEE Transactions on Speech and Audio Processing,vol。7,1999,第272-281頁,例如等式(22)和(23)。$ \ mathbf {G} ^ {(ri)} $統計量也在這裏使用,但是在HLDA案例中,需要對被接受和拒絕的維度進行稍微不同的定義。假設原始特徵維度爲D,縮小的特徵維數爲K。我們先忽略迭代上標r,並將下標j用於表示狀態,m表示高斯混合數。對於可接受的維度($ 0 \ leq i <K $),統計量爲:

\ [\ mathbf {G} ^ {(i)} = \ sum_ {t,j,m} \ gamma_ {jm}(t)\ frac {1} {\ sigma ^ 2_ {jm}(i) mu_ {jm}  -  \ mathbf {x}(t))(\ mu_ {jm}  -  \ mathbf {x}(t))^ T \]

其中$ \ mu_ {jm} \ in \ Re ^ {K} $原始D維空間中的高斯均值,並且$ \ mathbf {X}(t)的$是原始K維空間中的特徵,但是$ \西格瑪^ 2_8 {} JM(我)$K維模型內的方差的第i維。

對於被拒絕的維度($ K \ leq d <D $),我們使用單位方差高斯,統計量如下:

\ [\ mathbf {G} ^ {(i)} = \ sum_ {t,j,m} \ gamma_ {jm}(t)(\ mu  -  \ mathbf {x}(t))(\ mu  -  \ mathbf {x}(t))^ T,\]

其中$ \ $萬畝表示在K維空間中的全局特徵均值。一旦我們得到這些統計量,HLDA估計與維D中的MLLT / STC估計相同。注意,所有拒絕維度的$ \ mathbf {G} $統計量是相同的,因此在代碼中,我們僅存儲K + 1維而不是D維的統計量

此外,對於積累統計量的程序來說,只用訪問K維模型很方便,所以在HLDA累加過程中,我們積累了足夠的統計量來估計K維平均值$ \ {mu_ JM} $,而不是G我們積累的統計數據如下:

對於接受維度($ 0 \ leq i <K $),

\ [\ mathbf {S} ^ {(i)} = \ sum_ {t,j,m} \ gamma_ {jm}(t)\ frac {1} {\ sigma ^ 2_ {jm}(i)} \ mathbf {x}(t)\ mathbf {x}(t)^ T \]

對於拒絕維度 $ K \ leq i <D $

\ [\ mathbf {S} ^ {(i)} = \ sum_ {t,j,m} \ gamma_ {jm}(t)\ mathbf {x}(t)\ mathbf {x}(t) \]

當然,我們只需要存儲其中的一個(例如,對於i = K),因爲它們都是一樣的。然後在更新時間,我們可以計算維度爲$ 0 \ leq i <K $的G統計量:

\ [\ mathbf {G} ^ {(i)} = \ mathbf {S} ^ {(i)}  -  \ sum_ {j,m} \ gamma_ {jm} \ mu_ {jm} \ mu_ {jm} ^ T ,\]

對於$ K \ leq i <D $

\ [\ mathbf {G} ^ {(i)} = \ mathbf {S} ^ {(i)}  -  \ beta \ mu \ mu ^ T,\]

其中$ \ beta = \ sum_ {j,m} \ gamma_ {jm} $是總數,$ \ mu = \ frac {1} {\ beta} \ sum_ {j,m} \ mu_ {j,m} $是全局特徵的均值。在使用與MLLT相同的計算方法從G統計量計算變換後,我們輸出變換,並且還使用變換的第一個K行將均值投影到維K中,並寫出變換後的模型。

這裏描述的計算過程相當緩慢; 每個框架上的複雜度是$ O(K ^ 3)$,K也非常大(例如117)。這是我們爲緊湊統計所付出的代價; 如果我們存儲完整的均值和方差統計量,則每幀計算複雜度將是$ O(K ^ 2)$。爲了加快速度,我們有一個可選參數(代碼中的“speedup”),它可以選擇一個隨機的幀子集來計算HLDA統計量。例如,如果speedup = 0.1,我們只會在1/10的幀上累加HLDA統計量。如果此選項被激活,我們需要存儲關於均值統計量的兩個不同版本。一個版本的均值統計量,是在子集統計的,只能用於HLDA運算,其值對應着公式中的$ \ {gamma_ JM} $$ \ {mu_ JM} $。另一個版本的均值統計量是由全部訓練數據統計的,可以寫出轉換模型。

整體HLDA估計過程如下(見rm_recipe_2 / scripts / train_tri2j.sh):

  • 首先用LDA初始化它(我們存儲縮減維矩陣和全矩陣)。
  • 開始模型建立和訓練過程。在我們決定進行HLDA更新的某些(非連續)迭代中,執行以下操作:
    • 累加HLDA統計量(S,加上全維度均值統計量)。積累這些(gmm-acc-hlda)的程序需要模型,未轉換的特徵和當前的變換(它需要轉換特徵才能計算高斯驗概率)
    • 更新HLDA變換。這樣做的程序(gmm-est-hlda)需要模型; 統計量; 和先前的全(平方)轉換矩陣,它需要開始優化並正確地報告輔助功能變化。它輸出新的變換(全部和縮小的維度),以及新的估計和轉換均值的模型。

全局半綁定協方差(STC)/最大似然線性變換(MLLT)估計


全局STC / MLLT是一個特徵變換方陣。有關更多細節,請參見"Semi-tied Covariance Matrices for Hidden Markov Models", by Mark Gales, IEEE Transactions on Speech and Audio Processing, vol. 7, 1999, pages 272-281.將其視爲特徵空間變換,目標函數是給定模型的變換特徵的平均每幀對數似然,加上變換的對數行列式。模型的均值也在更新階段通過變換旋轉。足夠的統計量如下,對於$ 0 \ leq我<D $,其中D是特徵維度:

\ [\ mathbf {G} ^ {(i)} = \ sum_ {t,j,m} \ gamma_ {jm}(t)\ frac {1} {\ sigma ^ 2_ {jm}(i) mu_ {jm}  -  \ mathbf {x}(t))(\ mu_ {jm}  -  \ mathbf {x}(t))^ T \]

有關更新方程,請參考等式(22)和(23)。這些基本上是對角線逐行約束MLLR / fMLLR更新方程的簡化形式,其中二次方程的一階項消失。請注意,我們的實現與參考的不同之處在於使用矩陣的逆矩陣而不是代數餘子式,因爲乘以行列式不會對結果產生影響,並且可能會導致浮點下溢或溢出的問題。

我們描述一下在LDA特徵之上進行MLLT全過程,但它也適用於傳統的差分特徵。請參閱腳本rm_recipe_2 / steps / train_tri2f作爲示例。過程如下:

  • 估計LDA轉換矩陣(我們只需要它的第一行,而不是整個矩陣)。調用這個矩陣$ \ mathbf {M} $
  • 啓動正態模型構建過程,始終使用轉換的特徵$ \ mathbf {M} $。在某些選定的迭代過程(我們將更新MLLT矩陣)中,我們執行以下操作:
    • 在當前完全轉換的空間(即,與之相關的特徵之上$ \ mathbf {M} $)累計MLLT統計量。爲了提高效率,我們使用訓練數據的一部分來實現。
    • 做MLLT更新; 讓它產生一個方陣$ \ mathbf {T】$
    • 通過設置$ \ mu_ {jm} \ leftarrow \ mathbf {T} \ mu_ {jm} $來轉換模型。
    • 通過設置$ \ mathbf {M} \ leftarrow \ mathbf {T} \ mathbf {M} $更新當前的變換 

涉及MLLT估計的程序是gmm-acc-mllt和est-mllt。我們還需要程序gmm-transform-means(使用$ \ mathbf {T】$轉換高斯函數均值),compose-transforms(做乘法$ \ mathbf {M} \ leftarrow \ mathbf {T} \ mathbf {M} $)。


全局CMLLR / fMLLR轉換


約束最大似然線性迴歸(CMLLR),也稱爲特徵空間MLLR(fMLLR),是$ \ mathbf {x} \ rightarrow \ mathbf {A} \ mathbf {x} + \ mathbf {b} $的仿射特徵變換,也可以$ \ mathbf {x} \ rightarrow \ mathbf {W} \ mathbf {x} ^ + $表示,其中$ \ mathbf {x} ^ + = \ left [\ begin {array} {c} \ mathbf {x} \\ 1 \ end {array} \ right] $。請注意,這不同於文獻中的1在最前面。

關於CMLLR和我們使用的估計技術的綜述文章,參見"Maximum likelihood linear transformations for HMM-based speech recognition" by Mark Gales, Computer Speech and Language Vol. 12, pages 75-98.

我們存儲的足夠統計量是:

\ [\ mathbf {K} = \ sum_ {t,j,m} \ gamma_ {j,m}(t)\ Sigma_ {jm} ^ { -  1} \ mu_ {jm} \ mathbf {x}(t) ^ + \]

其中$ \ {Sigma_ JM} ^ { -  1} $是逆協方差矩陣,而對於$ 0 \ leq我<D $其中D是特徵維度,

\ [\ mathbf {G} ^ {(i)} = \ sum_ {t,j,m} \ gamma_ {j,m}(t)\ frac {1} {\ sigma ^ 2_ {j,m} )} \ mathbf {x}(t)^ + \ left。\ mathbf {x}(t)^ + \ right。^ T \]

我們的估計方案是標準的,參見參考文獻的附錄B(特別是B.1節“Direct method over rows”)。我們不同的是使用逆矩陣的一列而不是代數餘子式的行,即忽略行列式的因素,因爲它不影響結果並引起數字下溢或溢出的危險。

全局約束MLLR(CMLLR)轉換的估計由類FmllrDiagGmmAccs和程序gmm-est-fmllr完成(另見gmm-est-fmllr-gpost)。gmm-est-fmllr的語法是:

gmm-est-fmllr [options] <model-in> <feature-rspecifier> \
   <post-rspecifier> <transform-wspecifier>

“<post-rspecifier>”項目對應於transition-id 級別的後驗概率(參見 State-level posteriors)。該程序寫出一個默認utterance索引的CMLLR變換表,或者如果給出了-spk2utt選項,則由說話者索引。

以下是腳本的簡化摘錄(rm_recipe_2 / steps / decode_tri_fmllr.sh),它基於來自先前的unadapted的解碼的對齊來估計和使用CMLLR變換。假設以前的解碼是使用相同的模型(否則我們必須使用程序“convert-ali”來轉換對齊方式)。

...
silphones=48 # colon-separated list with one phone-id in it.
mincount=500 # min-count to estimate an fMLLR transform
sifeats="ark:add-deltas --print-args=false scp:data/test.scp ark:- |"

# The next comand computes the fMLLR transforms.
ali-to-post ark:$srcdir/test.ali ark:- | \
  weight-silence-post 0.0 $silphones $model ark:- ark:- | \
  gmm-est-fmllr --fmllr-min-count=$mincount \
    --spk2utt=ark:data/test.spk2utt $model "$sifeats" \
   ark,o:- ark:$dir/test.fmllr 2>$dir/fmllr.log

feats="ark:add-deltas --print-args=false scp:data/test.scp ark:- |
  transform-feats --utt2spk=ark:data/test.utt2spk ark:$dir/test.fmllr
       ark:- ark:- |"

# The next command decodes the data.
gmm-decode-faster --beam=30.0 --acoustic-scale=0.08333 \
  --word-symbol-table=data/words.txt $model $graphdir/HCLG.fst \
 "$feats" ark,t:$dir/test.tra ark,t:$dir/test.ali 2>$dir/decode.log


線性VTLN(LVTLN)


近年來,已經有許多論文描述了聲道長度歸一化(VTLN)的實現,該方法計算出對應於每個VTLN彎折因子的線性特徵變換。參見``Using VTLN for broadcast news transcription'', by D. Y. Kim, S. Umesh, M. J. F. Gales, T. Hain and P. C. Woodland, ICSLP 2004.

我們使用LinearVtln類實現了這個一般類中的一個方法,以及諸如gmm-init-lvtln,gmm-train-lvtln-special和gmm-est-lvtln-trans之類的程序。所述LinearVtln對象本質上存儲一組線性特徵變換,每個對應着一個彎折因子。讓這些線性特徵變換矩陣爲

\ [\ mathbf {A} ^ {(i)},0 \ leq i <N,\]

其中例如我們可能$ N $= 31,對應於31個不同的彎折因子。我們將在下面描述我們如何獲得以下這些矩陣。估計說話人特定變換的方式如下。首先,我們需要某種模型和相應的對齊方式。在示例腳本中,我們使用小型單音素模型,或使用完整的三音素模型。從這個模型和對齊方式,並使用原始的,未彎折的特徵,我們計算用於估計CMLLR的常規統計量。要計算LVTLN變換,需得到每個矩陣$ \ mathbf {A} ^ {(I)} $,並計算使變換$ \ mathbf {W} = \ left [\ mathbf {A} ^ {(i)} \,;  \,\ mathbf {b} \ right] $的CMLLR輔助函數最大化的偏移向量$ \ mathbf {B} $。給出最大輔助函數值(即 最大化i)的$ \ mathbf {白} $值成爲該說話人的變換(譯者注:不太確定,附上原文 This value of $\mathbf{W}$ that gave the best auxiliary function value (i.e. maximizing over i) becomes the transform for that speaker)。由於我們在這裏估計一個均值偏移量,所以我們基本上將一種基於模型的倒譜平均歸一化(或者是僅偏移的CMLLR形式)與作爲線性變換實現的VTLN曲折率(warping )相結合。這避免了只有均值規範化這一個步驟。

我們接下來描述我們如何估計矩陣$ \ mathbf {A} ^ {(I)} $。我們不按照參考文獻中所述的相同方式, 我們的方法更簡單(更容易證明)。這裏我們只說一個特定的彎折因子的計算; 在目前的腳本中,我們有不同的彎折因子,從0.85,0.86,...,1.15。我們採用特徵數據的一個子集(例如數十個話語),對於這個子集,我們計算原始和變換的特徵,其中使用常規的VLTN計算來計算變換後的特徵(參見特徵級聲道長度歸一化(VTLN ))。調用原始和轉換的特徵分別是$ \ mathbf {X}(t)的$$ \ mathbf {Y}(t)的$,其中$ T $的取值範圍是所選語音的幀。我們計算最小二乘法意義上的從$ \ mathbf {X} $映射到$ \ mathbf {Y} $的仿射變換,即如果$ \ mathbf {y}'= ​​\ mathbf {A} \ mathbf {x} + \ mathbf {b} $我們計算使$ \ sum_t(\ mathbf {y}'(t) -  \ mathbf {y}(t))^ T(\ mathbf {y}'(t) -  \ mathbf {y}(t))$最小的$ \ mathbf {A} $$ \ mathbf {B} $。然後,我們歸一化對角方差如下:我們計算的原始特徵方差$ \ mathbf {\西格瑪} ^ {(X)} $和線性變換特徵方差$ \ mathbf {\西格瑪} ^ {(Y')} $,並且對於每個d,都將$ \ mathbf {A} $的第d行乘以$ \ sqrt {\ frac {\ mathbf {\ Sigma} ^ {(x)} _ {d,d}} {\ mathbf {\ Sigma} ^ {(y')} _ {d,d}}} $,得到的矩陣就是$ \ mathbf {A} ^ {(I)} $

命令行工具支持在評估要使用的變換矩陣時忽略對數行列式的選項(例如,可以設置-logdet-scale = 0.0)。在某些情況下,這似乎會改善結果; 忽略對數決定因素,它總是使得彎折因子的分佈更加雙峯,因爲對數行列式不是正的,只是在彎折因子爲1.0時爲0,因此對數行列式相當於懲罰項爲了使彎折因子不遠離1。然而,對於某些類型的特徵(特別是從LDA導出的特徵),忽略對數行列式使得結果變得更糟,並導致非常奇怪的彎折因子分佈,因此我們的示例腳本始終使用對數行列式。無論如何,這是正確的事情。

內部C ++代碼支持對變換矩陣$ \ mathbf {A} ^ {(I)} $的最大似然重估計的累積統計。我們的期望這樣會改善結果。然而,它導致性能下降,所以我們不包括這樣做的示例腳本。


指數變換(ET)


指數變換(ET)是計算VTLN類變換的另一種方法,但與線性VTLN不同,我們完全切斷與頻率彎折的連接,並以數據驅動的方式學習。對於正常的訓練數據,我們發現它的學習與傳統的VTLN非常相似。

ET是一種轉換形式:

\ [\ mathbf {W} _s = \ mathbf {D} _s \ exp(t_s \ mathbf {A})\ mathbf {B},\]

其中exp是通過$ \ mathbf {A} $的泰勒級數定義的矩陣指數函數,與標量指數函數一樣。具有下標“s”的值是說話人特定的; 其他數量(即$ \ mathbf {A} $$ \ mathbf {B} $)是全局的,並在所有說話人之間共享。

這個方程中最重要的因子是中間的指數函數。因子$ \ mathbf {D} _s $整合基於模型的均值和可選的方差歸一化(即僅偏移或僅對角話的CMLLR),因子$ \ mathbf {B} $允許變換到MLLT(也稱爲全局STC),也是在每次重新估計的迭代中重新歸一化$t_s$的副產物。這些因子的維度如下,其中D是特徵的維度:

\ \ \ mathbf {D} _s \ in \ Re ^ {D \ times(D + 1)},\ t_s \ in \ Re,\ \ mathbf {A} \ in \ Re ^ {(D + 1)\ times (D + 1)},\ \ mathbf {B} \ in \ Re ^ {(D + 1)\ times(D + 1)}。 \]

請注意,如果$ \ mathbf {D} _s $是一個完全無約束的CMLLR矩陣,那麼這個方法就沒有意義,因爲方程式中的其他因子不會增加自由度。這些工具支持對$ \ mathbf {D} _s $的三種約束:它可以是$ [{\ mathbf I} \,\; \,{\ mathbf 0}] $(無適應),或$ [{\ mathbf I} \,\; \,{\ mathbf m}] $(僅偏移)或$ {{\ mathrm {diag}}({\ mathbf d})\,\; \,{\ mathbf m}] $(對角CMLLR); 這由命令行工具的-normalize-type選項控制。$ \ mathbf {A} $的最後行和$ \ mathbf {B} $被固定在特定的值(這些行參與與值1.0,它被附加到特徵,以表達一個仿射變換作爲基質中傳播的最後一個載體元件)。最後一行$ \ mathbf {A} $固定爲零,$ \ mathbf {B} $的最後一行固定爲$ [0 \ 0 \ 0 \ \ ldots \ 0 \ 1] $

說話人特定量$ T_S $可以被解釋爲說話人特定的彎折因子的對數。使用指數函數是因爲,如果先被因子f彎折然後被因子g彎折,彎折度應該與組合因子fg的相同。令l = log(f),m = log(g)。然後我們通過定義證明這個性質

\ [\ exp(l \ mathbf {A})\ exp(m \ mathbf {A})= \ exp((l + m)\ mathbf {A})。 \]

特定說話人的ET計算如下:這假設給定$ \ mathbf {A} $$ \ mathbf {B} $。並累計每個說話人的足夠的常規CMLLR統計量。在更新階段,我們迭代優化$ T_S $$ \ mathbf {D} _s $使輔助函數( auxiliary function最大化。用基於牛頓法的迭代過程來更新$ T_S $; 用基於傳統的CMLLR方法來更新$ \ mathbf {D} _s $,特別的關於對角線或僅偏移的情況,我們通過對$ \ mathbf {D} _s $的約束來實現。

整體訓練計算如下:

  • 首先,初始化$ \ mathbf {B} $爲id,$ \ mathbf {A} $爲最後一行爲零的隨機矩陣。

然後,從一些已知的模型開始,開始迭代 EM過程。在每次迭代中,我們首先估算特定說話人的參數$ T_S $$ \ mathbf {D} _s $,並計算變換$ \ mathbf {白} _s $,然後我們選擇更新$ \ mathbf {A} $$ \ mathbf {B} $和模型三者中的一個。

  • 如果更新$ \ mathbf {A} $,則固定給定$ T_S $$ \ mathbf {D} _s $。這個更新不能保證收斂,但在實踐中迅速收斂; 它基於二次“弱感輔助功能(weak-sense auxiliary function)”,其中使用矩陣指數函數的泰勒級數展開的一階截斷來獲得二次項。更新$ \ mathbf {A} $後,我們將修改$ \ mathbf {B} $ 使$ T_S $重新歸一化到0,使$ \ exp(t \ mathbf {A})$左乘$ \ mathbf {B} $,其中t是$ T_S $的平均值。
  • 如果更新$ \ mathbf {B} $,也是固定給定$ T_S $$ \ mathbf {D} _s $,並且更新類似於MLLT(也稱爲全局STC)。爲了累計和更新,想象估計MLLT矩陣是矩陣$ \ mathbf {A} $的左邊,如$ \ mathbf {C} \ in \ Re ^ {D \ times D} $,定義$ \ mathbf {C} ^ + = \ left [\ begin {array} {cc} \ mathbf {C}&0 \\ 0&1 \ end {array} \ right] $,變換變成$ \ mathbf {W} _s = \ mathbf {D} _s \ mathbf {C} ^ + \ exp(t_s \ mathbf {A})\ mathbf {B} $。在概念上,在估計$ \ mathbf {C} $時,我們把$ \ mathbf {D} _s $當做創建說話者特定的模型空間變換,這是唯一可能的$ \ mathbf {D} _s $對角線結構; 並且將$ \ exp(t_s \ mathbf {A})\ mathbf {B} $視爲特徵空間變換(即作爲特徵的一部分)。估計$ \ mathbf {C} $後,我們將使用定義

    \ [\ mathbf {C} ^ + \ exp(t_s \ mathbf {A})= \ exp(t_s \ mathbf {C} ^ + \ mathbf {A} \ left。\ mathbf {C} ^ + \ right。 {-1})\ mathbf {C} ^ + \]

    所以更新成爲:

    \ [\ mathbf {A} \ leftarrow \ mathbf {C} ^ + \ mathbf {A} \ left。\ mathbf {C} ^ + \ right。^ { -  1},\ \ \ mathbf {B} \ leftarrow \ mathbf {C} ^ + \ mathbf {B}。 \]

    在這一點上,我們需要用矩陣來轉換模型$ \ mathbf {C} $。讀者可能會對估計$ \ mathbf {C} $時那些因子如何相互作用的有疑惑,我們將數量$ \ mathbf {D} _s $視爲模型空間變換。如果$ \ mathbf {D} _s $只包含一個均值偏移,我們仍然可以證明輔助函數會增加,除非我們必須適當地改變偏移量(這樣做不好,因爲我們將在下一次迭代中重新估計它們)。然而,如果$ \ mathbf {D} _s $有非單元對角線(即有對角但沒有CMLLR偏移),則不能保證這種重估計過程能夠提高似然性; 在這種情況下,工具將會打印一個警告。爲了避免遇到這種情況,我們的腳本以一種$ \ mathbf {D} _s $僅偏移轉換的模式進行訓練;但是在測試中我們允許$ \ mathbf {D} _s $爲對角CMLLR變換時,結果比只偏移的要好一丟丟。
  • 更新模型很簡單; 它只涉及適應了的特徵的訓練。

與使用指數變換相關的重要程序如下:

  • gmm-init-et 初始化指數變換對象(包含A和B)並將其寫入磁盤; A的初始化是隨機的。
  • gmm-est-et 估計一組說話人的指數變換; 它讀取指數變換對象,模型,特徵和高斯層的後驗概率,並寫出變換$ \ mathbf {白} _s $和可選的“扭曲因子” $ T_S $
  • gmm-et-acc-a 累積更新的統計數據$ \ mathbf {A} $,gmm-et-est-a進行相應的更新。
  • gmm-et-acc-b 積累更新的統計數據$ \ mathbf {B} $,gmm-et-est-b進行相應的更新。

倒譜平均值和方差歸一化


倒譜平均值和方差歸一化包括對原始cepstra的平均值和方差進行歸一化,通常以發音(utterance)或每個說話人爲基礎,給出零均值,單位方差cepstra。我們提供代碼來支持這一點,還有一些示例腳本,但我們並不特別推薦使用它。一般來說,我們更喜歡基於模型的方法來表示均值和方差歸一化; 例如,線性VTLN(LVTLN)學習平均偏移量和指數變換(ET)執行對角CMLLR變換,其具有與倒譜平均值和方差歸一化相同的功率(通常應用於完全擴展的特徵) 。對於非常快速的操作,可以在基於發音的非常小的語言模型使用這個方法,我們的一些示例腳本演示了這一點。特徵提取代碼中也可以在每個語音(utterance)的基礎上減去平均值(計算-mfcc-feats和compute-plp-feats的-subtract-mean選項)。

爲了支持每個語音和每個說話人的均值和方差歸一化,我們提供程序compute-cmvn-stats和apply-cmvn。默認情況下,程序compute-cmvn-stats將計算均值和方差歸一化的足夠統計量,作爲一個矩陣(格式不是很重要;詳見代碼),並將寫出用utterance-id索引的統計量。如果給出-spk2utt選項,它將以每個演講者的方式寫出統計量(警告:在使用此選項之前,請閱讀在隨機訪問模式下讀取歸檔時避免內存膨脹,因爲此選項會導致輸入功能以隨機訪問模式讀取)。程序“apply-cmvn”讀入特徵和倒譜均值和方差統計; 如果應用了-utt2spk選項,則默認情況下,每個話語的統計量都將被索引(或者每個說話人進行索引)。它在均值和方差歸一化之後寫出特徵。儘管有這些名稱,這些程序並不在意,這些功能是由cepstra還是其他任何東西組成; 它只是將它們視爲矩陣。當然,給定的ecompute-cmvn-stats和apply-cmvn函數必須具有相同的維度。

我們注意到,它可能與特徵變換代碼的整體設計更一致,提供一個版本的compute-cmvn-stats,它將平均和方差歸一化變換以通用仿射變換(與CMLLR轉換格式一樣)的形式寫出,以便它們可以被程序transform-feats調用,並根據需要和compose-transforms的變換進行組合。如果需要,我們可能會提供這樣一個程序,但是由於我們不把平均值和方差歸一化作爲任何方法的重要組成部分,我們還沒有這樣做。


建立適應的迴歸樹


Kaldi支持迴歸樹MLLR和CMLLR(也稱爲fMLLR)。有關回歸樹的概述,請參見 "The generation and use of regression class trees for MLLR adaptation" by M. J. F. Gales, CUED technical report, 1996。

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