1. 程式人生 > >Kaldi-dnn 學習01

Kaldi-dnn 學習01

1. Kaldi 中實現的 dnn 共 4 種:

    a. nnet1 - 基於 Karel's 的實現,特點:簡單,僅支援單 GPU, 由 Karel 維護

    b. nnet2 - 基於 Daniel Povey p-norm 的實現,特點:靈活,支援多 GPU、CPU,由 Daniel 維護

    c. nnet3 - nnet2 的改進,由 Daniel 維護

    d. (nnet3 + chain) - Daniel Povey 改進的 nnet3, 特點:可以實現實時解碼,解碼速率為 nnet3 的 3~5 倍

    目前來看:minibatch  Stochastic Gradient Descent 用於 DNN 梯度下降的效果最好

                      從一個小樣本含 (τ個樣本) 估計出一個 avarage gradient , 這個小樣本就叫做 minibatch

2. 先從 nnet2 說起

    a. nnet2 最頂層的訓練指令碼:steps/nnet2/train_pnorm_fast.sh

通過多計算節點,完成並行化訓練

    b. 輸入神經網路的特徵

         輸入神經網路的特徵是可配置的,通常為MFCC+LDA+MLLT+fMLLR, 40-維的特徵,從網路上看到的是由7幀(從中間幀到左右幀都是3幀)組成的一個幀窗。由於神經網路很難從相關輸入的資料中學習,因此,以 40*7 維特徵作為一個不相關的固定變換形式,通過 step/nnet2/get_lda.sh 完成該工作,實際中並非使用準確的 LDA,而是用 non-dimension-reducing 形式的 LDA,然後減少輸出特徵方差的維度。

    

     c. dumping 訓練樣本到磁碟

            

          第一步,呼叫 step/nnet2/get_egs.sh:拷貝大量資料至 /exp/nnet5d/egs/;便於隨機梯度下降訓練。對輸入做“幀-級別”的隨機初始化(僅做一次)。也就是說:能始終以相同的序列化 access 資料,對於 disk 和 network, disk access 序列化是很好的。

          /exp/nnet5d/egs/中包含很多 class 例項(稱為NnetTrainingExample) (如egs.1.1.ark,egs.1.2.ark...),這些 class 包含每幀的 label 資訊,和該幀用於神經網路計算的一個充足的特徵(40維特徵)的輸入時間窗。(從表面上看來)並非為神經網路做 frame-splicing,神經網路有“時間觀念”,並知道“需要多長時間的上下文”(即看函式 RightContext() 和 LeftContext())。egs.1.1.ark 中的第 1 個數字 1 代表 job-index,第 2 個數字 1 代表 iteration index。

          有檔案中包含 job-index 和 the iteration index,如共有16個 CPU/GPU 可用,則 job-index 取值範圍 [1, 16],而 the iteration index 的範圍則根據資料量、及有多少個 job 來定。每個 archive 大約需要 200,000 個 samples。需要訓練很多個 epochs, 每個 epoch 做很多次迭代。設定引數為 iters_per_epoch, num_jobs_nnet 和 sample_per_iter。

          具體 iters_per_epoch, num_jobs_nnet  和 sample_per_iter 設定值,見 exp/nnet5d/egs/ 對應名字檔案。

          

       d. 神經網路初始化

           第一步,初始含一個隱藏層的神經網路,隨後在訓練中逐漸增加 (2~5 ) 隱藏層。配置隱藏層的檔案類似 /exp/nnet4d/nnet.config。即通過 nnet-am-init 建立初始化模型。類似如下的配置檔案
 


SpliceComponent input-dim=40 left-context=4 right-context=4 const-component-dim=0
FixedAffineComponent matrix=exp/nnet4d/lda.mat
AffineComponentPreconditionedOnline input-dim=360 output-dim=1000 alpha=4.0 num-samples-history=2000 update-period=4 rank-in=20 rank-out=80 max-change-per-sample=0.075 learning-rate=0.02 param-stddev=0.0316227766016838 bias-stddev=0.5
PnormComponent input-dim=1000 output-dim=200 p=2
NormalizeComponent dim=200
AffineComponentPreconditionedOnline input-dim=200 output-dim=1475 alpha=4.0 num-samples-history=2000 update-period=4 rank-in=20 rank-out=80 max-change-per-sample=0.075 learning-rate=0.02 param-stddev=0 bias-stddev=0
SoftmaxComponent dim=1475

 SpliceComponent: 定義了完成 feature-frame-splicing 的視窗尺寸


    FixedAffineComponent:類 LDA-like 的非相關轉換,由標準的 weight matrix plus bias 組成,通過標準的 stochastic gradient descent 訓練而來,使用 global learning rate

    AffineComponentPreconditionedOnline:為 FixedAffineComponent 的一種提煉,訓練過程中不僅使用global learning rate,還使用 matrix-valued learning rate 來預處理梯度下降。參見 dnn2_preconditioning。

    PnormComponent:為非線性,傳統的神經網路模型中使用 TanhComponent
    NormalizeComponent:用於穩定訓練 p-norm 網路,它是固定的,非可訓練,非線性的。它不是在個別 individual activations 上起作用,而是對單幀的整個 vetor 起作用,重新使它們單位標準化。

    SoftmaxComponent:為最終的非線性特徵,便於輸出標準概率

    同時,上述指令碼也會產生 hidden.config, 用於新的隱藏層,在最開始的兩次迭代中不會使用,如


AffineComponentPreconditionedOnline input-dim=200 output-dim=1000 alpha=4.0 num-samples-history=2000 update-period=4 rank-in=20 rank-out=80 max-change-per-sample=0.075 learning-rate=0.02 param-stddev=0.0316227766016838 bias-stddev=0.5
PnormComponent input-dim=1000 output-dim=200 p=2
NormalizeComponent dim=200

 第二步,做 nnet-train-transitions ,完成轉移概率的計算,該步驟計算的概率在 decoding 時 HMMs 中使用(神經網路中是不需要該概率的)。並計算 “targets(幾千個 context-dependent 狀態)” 的先驗概率。接下來進行解碼,分割這些通過網路計算得到的先驗概率,得到pseudo-likelihoods。
     

     d. 神經網路訓練

             本階段進行關鍵步驟:神經網路訓練。實際上就是 0 - num_iters-1 次的迴圈,迭代次數 num_iters 就是 每個 epoch 的迭代次數。訓練 epochs 的次數 = num_pochs(eg 15) + num_epochs_extra(eg 5)。每個 epoch 的迭代次數儲存在 egs/nnet5d/egs/iters_per_epoch 中,具體大小依賴於併發的 job 個數和訓練的資料量。一般的策略是:learning rate 從初始的 0.04,decrease rete 為 0.004,迭代15個epoch,最後5個 epoch 使用固定的 final_learning_rate 0.004。

           在每個迭代中,首要任務是計算一些 diagnostics:即 訓練與驗證資料的目標函式(如,iteration 10, 可以檢視對應的 egs/nnet5d/log/compute_prob_valid.10.log 和 egs/nnet5d/log/compute_prob_train.10.log)。在檔案(eg: egs/nnet5d/log/progress.10.log)即可看到 iteration 10 對應的 diagnostics [表示每層有多少個 parameters 變化,以及有多少訓練資料目標函式的變化對每一層的變化有作用]。

            基本的並行方法:對數百個 samples 使用隨機梯度下降來訓練,在不同 job 中使用不同的資料,然後 average models。在引數中,目標函式不是凸函式。實踐證明對於並行方法, "preconditioned update" 是非常重要的,而 average model 是沒有作用的。

         

   g. Final model combination

      

             檢視 exp/nnet4d/log/combine.log 檔案可看到,final.mdl 是如何合成的。基本方法:減少方差估計的平均迭代次數。實際中,combine.log 不僅僅只利用引數的平均值,而使用 training-data examples 的 subset 來優化 weight set(不限制必需為正)。對於 subset 的目標函式為常用函式(eg: log-probability),優化方法為 L-BFGS 和 特殊的預處理方法。each component and each iteration 含各自的 weilght。實踐證明:使用 隨機訓練資料的 subset 效果會更好。


#> cat exp/nnet4d/log/combine.log
<snip>
    Scale parameters are  [
  -0.109349 -0.365521 -0.760345
  0.124764 -0.142875 -1.02651
  0.117608 0.334453 -0.762045
  -0.186654 -0.286753 -0.522608
  -0.697463 0.0842729 -0.274787
  -0.0995975 -0.102453 -0.154562
  -0.141524 -0.445594 -0.134846
  -0.429088 -1.86144 -0.165885
  0.152729 0.380491 0.212379
  0.178501 -0.0663124 0.183646
  0.111049 0.223023 0.51741
  0.34404 0.437391 0.666507
  0.710299 0.737166 1.0455
  0.859282 1.9126 1.97164 ]
 
LOG <snip> Combining nnets, objf per frame changed from -1.05681 to -0.989872
LOG <snip> Finished combining neural nets, wrote model to exp/nnet4a2/final.mdl

如上所求,combination weights 被列印為矩陣格式,行:代表 iteration,列:代表相關 layer。combination weights  剛開始 negative,隨後 postive,可以解釋為趨於一次嘗試模型進一步的方向。使用 training data 而不是 validation data,因為這樣效果更好。


   f. Mixing-up

          可以使用如下工具列印 final.mdl 來分析
 


#> nnet-am-info exp/nnet4d/final.mdl
num-components 11
num-updatable-components 3
left-context 4
right-context 4
input-dim 40
output-dim 1483
parameter-dim 1366000
component 0 : SpliceComponent, input-dim=40, output-dim=360, context=4/4
component 1 : FixedAffineComponent, input-dim=360, output-dim=360, linear-params-stddev=0.0386901, bias-params-stddev=0.0315842
component 2 : AffineComponentPreconditioned, input-dim=360, output-dim=1000, linear-params-stddev=0.988958, bias-params-stddev=2.98569, learning-rate=0.004, alpha=4, max-change=10
component 3 : PnormComponent, input-dim = 1000, output-dim = 200, p = 2
component 4 : NormalizeComponent, input-dim=200, output-dim=200
component 5 : AffineComponentPreconditioned, input-dim=200, output-dim=1000, linear-params-stddev=0.998705, bias-params-stddev=1.23249, learning-rate=0.004, alpha=4, max-change=10
component 6 : PnormComponent, input-dim = 1000, output-dim = 200, p = 2
component 7 : NormalizeComponent, input-dim=200, output-dim=200
component 8 : AffineComponentPreconditioned, input-dim=200, output-dim=4000, linear-params-stddev=0.719869, bias-params-stddev=1.69202, learning-rate=0.004, alpha=4, max-change=10
component 9 : SoftmaxComponent, input-dim=4000, output-dim=4000
component 10 : SumGroupComponent, input-dim=4000, output-dim=1483
prior dimension: 1483, prior sum: 1, prior min: 7.96841e-05
LOG (nnet-am-info:main():nnet-am-info.cc:60) Printed info about baseline/exp/nnet4d/final.mdl

 可以看到,在 outlayer 層之前有一層網路層(神經元節點數為4000),而它的實際大小為 1483,因為決策樹含有1483個葉子。

          通過 SumGroupComponent,softmax層維度由4000減少到1483,可以使用如下命令檢視


#> nnet-am-copy --binary=false baseline/exp/nnet4d/final.mdl - | grep SumGroup
nnet-am-copy --binary=false baseline/exp/nnet4d/final.mdl -
<SumGroupComponent> <Sizes> [ 6 3 3 3 2 3 3 3 2 3 2 2 3 3 3 3 2 3 3 3 3 \
3 3 4 2 1 2 3 3 3 2 2 2 3 2 2 3 3 3 3 2 4 2 3 2 3 3 3 4 2 2 3 3 2 4 3 3 \
<snip>
4 3 3 2 3 3 2 2 2 3 3 3 3 3 1 2 3 1 3 2 ]

 g. Tuning the number of jobs

              通常,最有效的 minibatch size = threads 的倍數。learning rate 與相關 jobs 的數量有關係,一般地,如果增加 jobs 的數量,同時應該增加相同倍數的 learning rate 。原因如下:
由於並行化方法是基於平行SGD執行的神經網路的平均,我們認為“有效學習率”
整個學習過程的每個樣本等於學習率除以工作數。 所以當工作量增加一倍時,
如果我們將學習率提高一倍,我們就會保持“有效學習率”不變

    h. Tuning the neural network training

     h.1 Number of parameters(hidden layers and layer size)

         對於 p-norm 網路,一般要求 -pnorm-input-dim 是 -pnorm-output-dim 的整數倍

     h.2 Learning rates

         

     h.3 Minibatch size

         minibatch size 一般取 2 的次冪,eg: 128,256,512。

     h.4 Max-change

             用於限制,在每個 minibatch 允許多少個 parameters 能變化,-max-change 會使訓練減慢


     h.5 Number of epochs,etc

             epochs 由 -num-epochs (default: 15) 和 -num-epochs-extra(default:5) 組成,-num-epochs 用於 learning rate 從 -initial-learning-rate 梯度下降到 -final-learning-rate 階段,-num-epochs-extra 用於固定的 -final-learning-rate 階段,

                    -num-iters-final 引數很重要,它決定了 final model combination 階段的迭代次數。


        h.6 Feature splicing width

             用於控制將多少幀的特徵組合成輸入特徵,該操作會影響到神經網路層的初始化,以及 examples 的產生。一般預設值為 4,表示的含義:以中間 frame 為軸,左右各四個 frame,共9幀為單位組合後做為輸入(通常由 MFCC+splice+LDA+MLLT+fMLLR 組成的 40 維特徵,splicing width = 4 是最優的,注意:LDA+MLLT特徵基於 splice frame 左右兩側各4幀,也就是說從神經網路上看 splice frame 兩側的 7 、8 幀均影響 acoustic context )

                   40 維的由來: 

                                       MFCC/幀:13維

                                       9幀:13*9維

                                       再LDA:40 維


        h.7 Configuration values relating to the LDA transform

             正如上面所說,此 LDA 並非標準的 LDA。傳統的 LDA 中,資料需要經過 normalize,使得 within-class variance 為單位矩陣,經過變換後,總 variance (within plus between-class) 第 i 個的對角值為 1.0+b(i),b(i) 具有資料依賴特性,根據 i 減少,between-class variance 為對角矩陣,而現在的 LDA 矩陣中每行乘以,其中,預設的 within-class-factor 為 0.0001,即 0.0001+b(i),而非原來的 1.0+b(i)。

         
        h.8 Other miscellaneous configuration values

             對於 train_tanh.sh,有一個優化選項 -shrink-interval(預設為 5),含義為:多久做一次 model “shrinking”,就是說用一個小子集訓練資料來優化一組尺度不同層的引數。

         



原文:https://blog.csdn.net/dearwind153/article/details/62044689 
 

Kaldi中如何使用已經訓練好的模型進行語音識別ASR呢?

Kaldi中有兩個版本的online、online2分別是第一代、第二代,現在已經不維護online,轉到online2了,但作為我們入門的,我建議還是選擇online,由簡入深嘛!!!

預設kaldi是不會編譯online模組的,怎麼讓她理解我的意圖呢?

[[email protected] ~]$ cd ~/kaldi-master/src

[[email protected] src]$ make ext -j 6

順利編譯出來~~~~
語音識別就看egs/voxforge檢視下面的run.sh

指令碼自動去下載預訓練模型:http://sourceforge.net/projects/kaldi/files/online-data.tar.bz2 

我們輸入:./run.sh --test-mode simulated就可以直接識別wav音訊檔案了!!!

深度學習專案:https://blog.csdn.net/chinatelecom08/article/details/83654602

 

原文:https://blog.csdn.net/houwenbin1986/article/details/78658102