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模块的,怎么让她理解我的意图呢?

[houwenbin@localhost ~]$ cd ~/kaldi-master/src

[houwenbin@localhost 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 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落雪snowflake

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值