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.7603450.124764 -0.142875 -1.026510.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.1658850.152729 0.380491 0.2123790.178501 -0.0663124 0.1836460.111049 0.223023 0.517410.34404 0.437391 0.6665070.710299 0.737166 1.04550.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 。原因如下:

Since the parallelization method is based on averaging the neural nets from parallel SGD runs, we view the "effective learning rate"
per sample of the entire learning process as equal to the learning rate divided by the number of jobs. So when doubling the number of jobs,
if we double the learning rate we keep the "effective learning rate" the same.

但是,如果 learning rate  太大会导致不稳定。

     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”,就是说用一个小子集训练数据来优化一组尺度不同层的参数。

Kaldi-dnn 学习相关推荐

  1. 语音识别之Kaldi:学习GMM-HMM

    语音识别之Kaldi kaldi语音识别理论与实践课程学习. 前面的博客介绍了语音识别的基础知识及原理.现在开始学习实战.以Kaldi框架为基础. Kaldi是一个有全套的语音识别代码的工具,由Dan ...

  2. dnn学习:数据访问(1)

    最近粗略的研究了dnn的数据访问机制,记录一下学习结果.    dnn的页面.模块可按照组进行授权,本来想先研究dnn是如何设计权限控制模块的,把权限相关的表结构及关系搞清楚后开始看代码,这一看就钻到 ...

  3. Kaldi 实战学习(1)说话人识别小例子(egs/aishell/v1)

    代码 进入:~/kaldi/egs/aishell/v1 # 地址变量(引号可省略,但是=之间不可有空格!) data=/export/a05/xna/data data_url=www.opensl ...

  4. DNN学习笔记 最简单的皮肤制作

    说明: 在学习DNN时,使用的版本为 DNN8.参考资料:http://www.dnnsoftware.com/docs/designers/creating-themes/index.html 制作 ...

  5. 深度学习的算法实践和演进

    1. 前言 如果说高德纳的著作奠定了第一代计算机算法,那么传统机器学习则扩展出第二代,而近十年崛起的深度学习则是传统机器学习上进一步发展的第三代算法.深度学习算法的魅力在于它核心逻辑的简单且通用. 在 ...

  6. Nature发文:深度学习系统为什么这么好骗?

    选自Nature 作者:Douglas Heave 机器之心编译 机器之心编辑部 几张贴纸就能「改变」交通标志识别结果,转个方向就看不出图中的动物种类,今天的人工智能系统经常会出现莫名其妙的 bug. ...

  7. 一文梳理深度学习算法演进

    来源:https://zhuanlan.zhihu.com/p/464515049 作者:Peter潘欣 编辑:蘑菇先生 学习记涉及语音.图像.nlp.强化学习.隐私保护.艺术创作.目标检测.医疗.压 ...

  8. 深度学习在推荐系统上的应用

    作者:陈仲铭,知乎 ID:ZOMI 深度学习最近大红大紫,深度学习的爆发使得人工智能进一步发展,阿里.腾讯.百度先后建立了自己的AI Labs,就连传统的厂商OPPO.VIVO都在今年开始筹备建立自己 ...

  9. 推荐系统中基于深度学习的混合协同过滤模型

    近些年,深度学习在语音识别.图像处理.自然语言处理等领域都取得了很大的突破与成就.相对来说,深度学习在推荐系统领域的研究与应用还处于早期阶段. 携程在深度学习与推荐系统结合的领域也进行了相关的研究与应 ...

  10. 基于OpenCL的深度学习工具:AMD MLP及其使用详解

    from:http://www.csdn.net/article/2015-08-05/2825390 [编者按]深度学习是近年来迅速发展和突破的机器学习领域,具有非常广泛的应用前景.将服务器GPU应 ...

最新文章

  1. java short long_谈谈Java中整数类型(short int long)的存储方式
  2. 面试:说说 HTTPS 的工作原理?
  3. java λ表达式_Java λ表达式
  4. Notepad++ 删除空白行的方法(转)
  5. 小论接口(interface)和抽象类(abstract class)的区别
  6. 一道Python面试题
  7. Android数据库Realm实践
  8. C语言 最大公约数和最小公倍数计算
  9. cmake字符串转数组_JS 数组中你或许不知道的操作
  10. 高教杯历年真题_喜报 | 2019“高教社”杯全国大学生数学建模竞赛获奖名单!...
  11. LoginActivity实现
  12. java mvc接收json_java相关:SpringMVC中controller接收json数据的方法
  13. 2013Esri全球用户大会QA之ArcGIS未来发展
  14. python pyhook监听扫码_Python2.7:使用Pyhook模块监听鼠标键盘事件-获取坐标实例
  15. [3DMax]物体在场景内居中和物体内坐标居中
  16. clickHouse 使用常见问题踩坑
  17. 如何解决oracle中文乱码问题,oracle中解决中文乱码问题
  18. AltiumDesigner19(AD19)使用设置技巧
  19. 稀疏表征:稀疏字典构建
  20. 纳豆的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告

热门文章

  1. 工作六年的主管对网投的建议
  2. 浏览器的UserAgent大全
  3. 第8章第22节:制作企业宣传册的案例分析幻灯片 [PowerPoint精美幻灯片实战教程]
  4. Qt插件机制及加载流程
  5. VMware发布开源项目Lightwave和Photon 提高云应用扩展性
  6. 哈希---闭散列和开散列
  7. Linux 文件管理-文件系统-XFS文件存储系统详解
  8. PDF→Excel格式转换工具集锦!
  9. win10系统在电源选项中限制cpu最大频率(更新后丢失“处理器电源管理“项)
  10. excel数据平均分配给多人_excel表格数据分配-用Excel怎么才能将组数据平均分配给几个人...