Nnet3配置中的上下文和块大小

简介

本页讨论了nnet3配置中关于解码和训练的块大小以及左右上下文的某些术语。这将有助于理解一些脚本。目前,从脚本角度来看,没有任何关于nnet3的"概述"文档,所以这是nnet3唯一的文档。

 
 

基础

 
 

如果您已阅读了"nnet3"配置的以前的文档,您会发现"nnet3"不仅支持简单的前馈DNN,还可以实现在网络内层进行时间拼接(帧拼接)的时延神经网络(TDNN)以及带有recurrent(循环)拓扑的RNN、LSTM、BLSTM等。所以nnet3有时间轴的概念。下面我们确定一些术语。

 
 

左右上下文

只有TDNN才需要左右上下文,LSTM/RNN不需要左右上下文

只有TDNN才需要右下文,LSTM/RNN不需要右下文;TDNN、LSTM、RNN均需要左上文

 
 

、右上下文为3。上下文的实际计算有点复杂,因为它必须考虑到特殊情况,例如"t"值为奇数或偶数时。

 
 

循环拓扑,除了上述"所需"左右上下文外,在训练或解码时,它还需要"额外的"上下文。RNN会利用到超出"所需"上下文的上下文。在脚本中,通常会看到名为extra-left-context和extra-right-context的变量,这意味着"除了需要的内容之外,我们将提供的上下文的数量"。

 
 

在某些情况下,左上下文和右上下文意味着添加到chunk中的总的左上下文和总的右上下文,即

 
 

左上下文=模型左上下文+额外左上下文

右上下文=模型右上下文+额外右上下文

 
 

因此,在某些情况下,您需要搞清楚一个变量指的是模型的左右上下文还是数据块的左右上下文。

 
 

个左右)来填充语句的开始或结束。这没有意义而且很奇怪。在版本5.1和更高版本中,您可以指定extra-left-context-initial和extra-right-context-final,允许话语的开始/结束具有不同的上下文量。如果您指定这些值,通常将它们都指定为0(即没有额外的上下文)。但是,为了与旧版本兼容,它们通常默认为-1(意思是复制默认的左上方和右上方)。

 
 

Chunk大小

 
 

Chunk的大小是我们在训练或解码中每个数据块所含(输出)帧的数量。在get_egs.sh和train_dnn.py脚本中,chunk-size的也被称为frames-per-eg(在某些上下文中,这与块大小不同;见下文)。在解码中,我们把它称为frame-per-chunk。

 
 

对于非RNN、非chain模型、非TDNN

 
 

example, /eg-/, 样例,样本,可用其IPA音标"eg"来作为其缩写;在传统的语音识别中,一个example,即一帧以及标签的二元组(frame, label)。

egs,多个eg,多个样本。

对于不使用上下文帧以及任何时间信息的DNN,如以Sigmoid、Tanh、ReLu为神经元的DNN。chunk与egs等同。

 
 

 
 

对于非RNN、非chain模型、TDNN

 
 

帧的上文和下文,并写入到磁盘中,就必须知道某一帧的左右上下文具体是哪些帧,并记录。

倍:

帧,总共需要160帧的左右上下文

[-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

[-9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11]

[-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ,12]

[-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]

[-6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]

[-4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]

[-3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]

 
 

为了解决这个问题,将

  • 对应的标签
  • 左上下文
  • 右上下文

组合为一个块,即chunk,使得这些帧能共享左右上下文帧:

帧,总共需要20帧的左右上下文

chunk与egs的区别:

chunk:[-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]

eg:[0, 1, 2, 3, 4, 5, 6, 7]

即:chunk是显式包含左右上下文帧的eg

时,存储的数据大小为原来的1/8;若chunk-width为20时,存储的数据大小为原来的1/20

当训练模型时,将以chunk为单位。

 
 

若以帧为单位进行LSTM的训练,一整句话的所有帧能不断地在神经网络中进行前向传播;

 
 

的frame_per_egs能减少硬盘空间消耗但不影响训练结果

 
 

作用:

  • 提供所需的左右上下文帧;
  • 减少磁盘空间消耗;

 
 

TDNN解码时,输入第一帧时,需要10帧左上文和10帧右下文。而第一帧是没有左上文的,因此,在输入层处对第一帧拷贝10次,作为其左上文;而10帧的右下文还没到来,因此无法输出第一帧的输出,需要等到第11帧到来时,才能输出第1帧,等到第12帧到来时,输出第2帧。

 
 

因此,时延为11*0.01=0.11秒,且只与右下文有关

 
 

次,作为其右下文

 
 

不需要chunk,直接对整个语句进行解码输出。

 
 

left-context-max = max(left-contexti)

right-context-max = max(right-contexti)s

 
 

 
 

RNN的chunk-size

 
 

到150帧的范围内),即chunk大小。当解码时,通常在相当大的chunk(frames-per-chunk=30、50或100)上评估神经网络。对于RNN,尽可能确保在训练时的chunk-size或frames-per-chunk、extra-left-context、extra-right-context与解码时的大致相同,以得到最优结果(尽管有时时解码中的上下文值稍大一些较好)。人们可能会认为在解码时更长的上下文能得到更好的结果,但是并不总是这样(然而,请参见下面的looped decoding,其中提到一个更好的方法)。

 
 

在RNN训练中,若不使用chunk,则以语句为单位进行训练,但是,过长的语句会导致训练过慢,且梯度沿时间传播容易衰减甚至消失。因此,RNN的chunk用于解决训练过慢和梯度衰减的问题。将语句分为若干个chunk,每个chunk根据left-context恢复对上一个chunk的记忆;每个chunk共享一段历史信息。

作用:

  • 加速训练;
  • 防止梯度衰减;

 
 

 
 

 
 

块大小与frame-subsampling-factor的关系

 
 

,frame-subsampling-factor为3,那么对大小为90帧的chunk估计30个的输出(例如t = 0,t = 3 ... t = 87)。

 
 

可变的chunk大小

在Kaldi 5.1或更高版本中,有时候在训练中使用可变chunk大小。因为当块相当大时,会出现由于一个语句的帧数不是块的整数倍而导致帧的丢失。这时,可以将块大小指定为以逗号分隔的列表(例如150,120,90,75),并且生成训练示例的命令可以创建任何这些大小的块。指定的第一个块大小称为主块大小,并且对于任何给定的话语都是"特殊的",最多允许指定两个非主块大小;剩余的块必须是主块大小。这种限制更容易得到给定长度的文件的最佳分割,并使得生成偏向于具有特定长度的块。

 
 

Minibatch大小

nnet3-merge-egs将各个训练样本合并到包含许多不同样本的minibatch中(每个原始样本获得不同的'n'索引)。 minibatch-size是minibatch的大小,指的是:将多个样本的帧以及label组合为一个样本,即eg的数量;

 
 

或对于RNN或TDNN,sequences,即chunk;进行组合的数量(例如,minibatch-size = 128)。

minibatch是以chunk为单位,一个chunk即一个样本。

minibatch是以帧为单位,如64。

假设chunk-width=20,那么一个minibatch将横跨3.2个chunk。短句的时长一般为3秒~4秒,设为3秒,设帧移为10ms,则1秒包含1000/10=100帧,一个短句包含300帧,如果minibatch=64,那么一句话被切分为4个minibatch=64*4=256帧,尾部的44帧被丢弃。

因此,minibatch常常也可变。

这种情况下,若minibatch=64,32

个minibatch:64+64+64+64+32=288,尾部只有12帧被丢弃。

 
 

当块大小可变时(如果我们设置了extra-left-context-initial和extra-right-context-final,考虑到话语开头/结尾的上下文可能不同),需要确保minibatch中只包含"类似"的样本;即某个样本的上下文可用另一个样本表示,以减小开销。

 
 

在Kaldi版本5.1及更高版本中,nnet3-merge-egs仅将相同结构的chunk(即相同的块大小和相同的左右上下文)合并在一起。它持续从输入中读取chunk,直到样本数达到minibatch-size。在5.1之前的Kaldi版本中,通常丢弃那些无法凑足一个minibatch的样本,现在,多种不同的chunk大小就不会丢弃太多数据)。

 
 

--egs.chunk-width

egs(examples)中每个chunk包含的帧数。注意:如果将值翻一番,则应将"--trainer.samples-per-iter"值折半。

--trainer.samples-per-iter

每个ark(archive,档案)中包含的egs(examples,样本)数。每个eg(example,样本)包含'chunk_width'个帧。

chunk_width=20、samples_per_iter=20000时;相当于训练普通DNN时每次迭代使用20*20000=400000帧。

 
 

可变的Minibatch大小

 
 

从Kaldi 5.1及更高版本开始,--minibatch-size的参数可以是一个更通用的字符串,允许用户指定可变而非固定的的minibatch大小。 例如,可以指定--minibatch-size=64,128,这样,对于每种类型的样本,首先以128进行切分并输出,直至输入的末尾;若末尾剩下样本数>=64,再以64为大小进行切分并输出。 --minibatch-size也支持数字范围,如 --minibatch-size=1:64表示首先以64帧为单位进行切分,然后将所有剩余的样本组合为一个minibatch。 还可以为不同大小的样本指定不同的规则(不带参数运行nnet3-merge-egs以获取详细信息);这可使得GPU内存占用不容易溢出。

 
 

循环解码(Looped decoding)

 
 

 
 

 
 

可修改"xconfig"配置文件中LSTM组件的decay-time参数,以使用循环解码,如: "decay-time= 20"。这似乎不会降低WER,并且消除了普通解码和循环解码之间的差异(即,它使得网络能够容忍比训练中看到的更长的上下文)。

 
 

脚本steps/nnet3/decode_looped.sh(Kaldi 5.1以上)仅接收两个与块或上下文相关的参数:frames-per-chunk(仅影响速度/延迟权衡,而非解码结果),以及extra-left-context-initial,该参数应与训练时(在最新脚本中通常为零)相同。

 
 

在撰写本文时,尚未实现支持循环解码的online2-wav-nnet3-latgen-faster;这是我们后续将要实现的。

 
 

nnet3配置中的上下文和chunk(块)大小的更多相关文章

  1. nnet3配置中的“编译”

    编译概述 编译流程将Nnet和ComputationRequest作为输入,输出NnetComputation.ComputationRequest包含可用的输入索引 以及 请求的输出索引. 不提供输 ...

  2. MongoDB 查看chunk块大小

    使用mongo shell连到mongos执行命令:AllChunkInfo("dbname.cellname",true) 点击(此处)折叠或打开 AllChunkInfo = ...

  3. Castle ActiveRecord配置中需要注意的地方

    关于Castle 的开发可参考李会军老师的Castle 开发系列文章,里面有关于ActiveRecord学习实践系列和Castle IOC容器系列两个部分,是比较好的教程. 这里主要说明在Castle ...

  4. 【译】在Asp.Net中操作PDF – iTextSharp -利用块,短语,段落添加文本

    原文 [译]在Asp.Net中操作PDF – iTextSharp -利用块,短语,段落添加文本 本篇文章是讲述使用iTextSharp这个开源组件的系列文章的第三篇,iTextSharp可以通过As ...

  5. webpack 中,module、chunk、bundle 的区别(待补充)

    项目 区别 module 是开发中的单个模块 chunk 中文意思是"块",是指 webpack 在进行模块依赖分析的时候,代码分割出来的代码块 bundle

  6. WINDOWS 负载均衡NLB配置中单播与多播区别(转载)

    单播 在单播模式下,NLB重新对每个NLB节点中启用NLB的网络适配器分配MAC地址(此MAC地址称为群集MAC地址),并且所有的NLB节点均使用相同的MAC地址(均使用群集MAC地址),同时NLB修 ...

  7. 回发或回调参数无效。在配置中使用 pages enableEventValidation=true 或在页面中使用 %@ Page EnableEventValidation=true % 启用了事件验证

    WebForm中回发或回调参数无效问题的解决 解决 .NET中回发或回调参数无效问题的解 该错误的详细提示信息为: 回发或回调参数无效.在配置中使用 <pages enableEventVali ...

  8. WPF:指定的命名连接在配置中找不到、非计划用于 EntityClient 提供程序或者无效的解决方法

    文/嶽永鹏 WPF 数据绑定中绑定到ENTITY,如果把数据文件做成一个类库,在UI文件中去应用它,可能遇到下面这种情况. 指定的命名连接在配置中找不到.非计划用于 EntityClient 提供程序 ...

  9. 在web.config配置中添加xml内容

    在web.config 中添加需要的内容时, 就是在<configuration>节点内添加一个新的<configSections>元素, 在configSections元素中 ...

随机推荐

  1. kafka-rest:怎么愉快的build?

    愉快的build该项目吧 git clone https://github.com/confluentinc/kafka-restmvn clean install -Dmaven.test.skip ...

  2. Linux:Day12(下) 进程、任务计划

    vmstat命令: vmstat [options] [delay [ count]] procs: r:等待运行的进程的个数: b:处于不可中断睡眠态的进程个数:(被阻塞的队列的长度): memor ...

  3. Jenkins pipeline:pipeline 使用之语法详解

    一.引言 Jenkins 2.0的到来,pipline进入了视野,jenkins2.0的核心特性. 也是最适合持续交付的feature. 简单的来说,就是把Jenkins1.0版本中,Project中 ...

  4. Java面试准备之JVM

    介绍JVM中7个区域,然后把每个区域可能造成内存的溢出的情况说明 程序计数器:看做当前线程所执行的字节码行号指示器.是线程私有的内存,且唯一一块不报OutOfMemoryError异常. Java虚拟 ...

  5. .NET Core 开源工具 IPTools - 快速查询 IP 地理位置、经纬度信息

    快速查询IP信息,支持国内和国外IP信息查询,支持查询经纬度,地理位置最高支持到城市. 1. IPTools.China 快速查询中国IP地址信息,包含国家.省份.城市.和网络运营商.非中国IP只支持 ...

  6. 如何卸载VS 2017之前版本比如VS 2013、VS2015、 VS vNext?

    前言 大学专业为软件工程,进入大学之后才知道这个专业需要用到笔记本,我的笔记本配置为I3,内存4个G,已经有大几年了,中间坏了修了一次一直用到现在,这个笔记本还是我哥打工过年回来身上仅有的三四千块钱所 ...

  7. SpringCloud(7)服务链路追踪Spring Cloud Sleuth

    1.简介 Spring Cloud Sleuth 主要功能就是在分布式系统中提供追踪解决方案,并且兼容支持了 zipkin,你只需要在pom文件中引入相应的依赖即可.本文主要讲述服务追踪组件zipki ...

  8. Golang 入门 : 字符串

    在 Golang 中,字符串是一种基本类型,这一点和 C 语言不同.C 语言没有原生的字符串类型,而是使用字符数组来表示字符串,并以字符指针来传递字符串.Golang 中的字符串是一个不可改变的 UT ...

  9. U盘文件被隐藏

    转自https://blog.csdn.net/zichen_ziqi/article/details/80171891 文章原地址:http://www.uqidong.com/help/1625. ...

  10. Python使用turtle库与random库绘制雪花

    记录Python使用turtle库与random库绘制雪花,代码非常容易理解,画着玩玩还是可以的. 完整代码如下:   效果图如下: