人工智能:语音识别理解与实践
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

4.3 实际应用

在4.2节中讲述的反向传播算法理论上比较简单,但是要高效地学习一个有用的模型,还需要考虑许多实际的问题[48, 185]

4.3.1 数据预处理

数据预处理在许多机器学习算法中都扮演着重要的角色。最常用的两种数据预处理技术是样本特征归一化和全局特征标准化。

如果每个样本均值的变化与处理的问题无关,就应该将特征均值归零,减小特征相对于深层神经网络模型的变化。例如,减去一张图片的强度均值,可以减少亮度引起的变化。在手写字符识别任务中,规整图片的中心可以减少字符位置引起的变化。在语音识别中,倒谱均值归一化(CMN)[166]是在句子内减去梅尔倒谱系数(MFCC)特征的均值,可以减少声学信道扭曲带来的影响。以CMN为列,对于每个句子,样本归一化首先要用该句子所有的帧特征估算每维i的均值

其中,T表示该句子中特征帧的个数,然后该句中的所有特征帧减去该均值

全局特征标准化的目标是使用全局转换缩放每维数据,使得最终的特征向量处于相似的动态范围内。例如,在图像处理中,经常将[0, 255]范围内的像素值缩放到[0, 1]范围内。在语音识别任务中,对于实数特征,例如MFCC和FBANK,通常会使用一个全局转换将每维特征归一化为均值为0,方差为1[12]。两种数据预处理方法中的全局转换都只采用训练数据估算,然后被直接应用到训练数据集和测试数据集。给定训练数据集(可能已经使用样本特征归一化处理),对每维特征i,计算均值

然后训练和测试数据中的所有数据可以使用如公式(4.36)所示的方式标准化:

当每维特征被缩放到相似的数值范围时,后续的处理过程通常能取得较好的结果,所以全局特征标准化是有效的[48]。例如,在DNN训练中,通过特征归一化,在所有的权重矩阵维度上使用相同的学习率仍然能得到好的模型。如果不做特征归一化,能量维或者MFCC特征第一维c0会遮蔽其他维度特征;如果不使用类似AdaGrad[186]的学习率自动调整算法,这些特征维度会在模型参数调整过程中主导学习过程。

4.3.2 模型初始化

4.2节讲述的学习算法都始于一个初始模型。因为DNN是一个高度非线性模型,并且相对于模型参数来说,训练准则是非凸函数,所以初始模型会极大地影响最终模型的性能。

有很多启发式方法可以初始化DNN模型。这些方法大部分都从以下两方面出发:第一,初始化的权重必须使隐层神经元节点在sigmoid函数的线性范围内活动。如果权重过大,许多隐层神经元节点的输出会趋近于1或者0,并且根据公式(4.25)可知,梯度往往会非常小。相反,如果隐层神经元节点在线性范围内活动,就可以得到足够大的梯度(趋近于最大值0.25),使得模型学习的过程更加有效。注意,隐层节点输出的激发值依赖于输入值和权重,若输入特征如4.3.1节所述被归一化,这里就可以更加简单地初始化权重。第二,随机初始化参数也很关键。这是因为DNN中的隐层神经元节点是对称和可互换的。如果所有的模型参数都有相同的值,那么所有的隐层神经元节点都将有相同的输出,并且在DNN的底层会检测相同的特征模式。随机初始化的目的就是打破对称性。

LeCun和Bottou[48]建议从一个均值为0、标准差为的分布中随机取值初始化公式(4.1)中定义的隐层权重,其中N为与权重连接的输出节点的个数。对于语音识别系统中的DNN,通常每个隐层有1000~2000个隐层神经元节点,并使用(w;0, 0.05)高斯分布或者一个取值范围在[−0.05, 0.05]的正态分布随机初始化权重矩阵;偏差系数b通常被初始化为0。

4.3.3 权重衰减

和很多机器学习算法类似,过拟合是模型训练过程中通常会遇到的问题。因为DNN模型与其他机器学习算法相比有更多的模型参数,所以该问题尤为严峻。过拟合问题主要是因为通常希望最小化期望损失函数公式(4.7),但是实际上被最小化的是训练集合中定义的经验损失。

缓和过拟合问题最简单的方法就是正则化训练准则,这样可以使模型参数不过分地拟合训练数据,最常用的正则项包括基于L1范数的正则项

和基于L2范数的正则项

其中,Wij是矩阵W中第ij列的值;是将矩阵W中的所有列串联起来得到的向量。另外,‖vec(W)‖2等于‖WF——矩阵W的Frobenious范数。在神经网络文献中,这些正则项通常被称为权重衰减(Weight Decay)。

当包含正则项时,训练准则公式如下:

其中,J(W, b; S)是在训练集S上优化的经验损失JMSE(W, b; S)或者JCE(W, b; S),R(W)是前面所述的R1(W)或者R2(W),λ是插值权重或者被称作正则化权重。另外,

当训练集的大小相对于DNN模型中的参数量较小时,权重衰减法往往是很有效的。因为在语音识别任务中使用的DNN模型通常有超过一百万的参数,插值系数λ应该较小(通常在10−4数量级),甚至当训练数据量较大时被设置为0。

4.3.4 丢弃法

控制过拟合的一种方法是前面所述的权重衰减法。而应用“丢弃法”(Dropout)[187]是另一种流行的做法。Dropout基本的想法是在训练过程中随机丢弃每一个隐层中一定比例(称为丢弃比例,用α表示)的神经元。这意味着即使在训练过程中有一些神经元被丢弃,剩下的(1−α)的隐层神经元依然需要在每一种随机组合中有好的表现。这就需要每一个神经元在检测模式的时候能够更少地依赖其他神经元。

我们也可以将Dropout认为是一种将随机噪声加入训练数据的手段。因为每一个较高层的神经元都会从较低层中神经元的某种随机组合那里接收输入。因此,即使送进深层神经网络的输入相同,每一个神经元接收到的激励也是不同的。在应用Dropout后,深层神经网络需要浪费一些权重来消除引入的随机噪声产生的影响。或者说事实上,Dropout通过牺牲深层神经网络的容量(Capacity)来得到更一般化的模型结果。

当一个隐层神经元被丢弃时,它的激活值被设置成0,所以误差信号不会经过它。这意味着除了随机的Dropout操作,对训练算法不需要进行任何改变就可以实现Dropout。然而,在测试阶段,我们并不会去随机生成每一个隐层神经元的组合,而是使用所有组合的平均情况。我们只需要简单地在与Dropout训练有关的所有权重上乘以(1−α),就可以像使用一个正常的深层神经网络模型(即没有应用Dropout的模型)一样使用新的模型。所以,Dropout可以被解读为一种在深层神经网络框架下有效进行模型(几何(Geometric))平均的方式(与Bagging类似)。

另一种稍微不一样的实现方式是在训练过程中,在神经元被丢弃之前将每一个激活值都除以(1−α)。这样,权重就自动乘以(1−α)。因此,模型在测试阶段便不再需要进行权重补偿。应用这种方法的另一个好处是我们可以在不同训练的轮次中使用不同的丢弃比例(Dropout Rate)。经验表明,通常在取丢弃比例为0.1~0.2时,识别率会有提升。而如果使用将初始的丢弃比例设置得比较大(例如0.5),然后渐渐减小丢弃比例的更智能的训练流程的话,那么识别的表现可以得到更进一步提高。原因在于使用较大的丢弃比例训练出的模型,可以被看作使用较小丢弃比例的模型的种子模型。既然结合较大丢弃比例的目标函数更平滑,那么它就更不可能陷入一个非常坏的局部最优解中。

在Dropout训练阶段,我们需要重复对每一层激活取样得到一个随机的子集。这必将严重拖慢训练过程。为此,随机数生成和取样代码的运行速度成为缩减训练时间的决定性因素。当然,也可以选择文献[188]中提出的一个快速丢弃训练算法。这个算法的核心思想是从近似的高斯模型中采样或直接积分,而不是进行蒙特卡罗采样。这种近似方法可由中心极限法则和实际经验证明其有效性,它可以带来显著的速度提升和更好的稳定性。该方法也可以扩展到其他类型的噪声和变换。

4.3.5 批规范化

在数据预处理章节中提到过对输入数据进行标准化有助于神经网络的训练,这个操作一般是在训练网络之前基于所有数据计算得到的统计量进行的全局操作。同样的思想可以被动态地运用于神经网络训练过程中。

批规范化(Batch normalization, BN)[189]的提出是为了改善深层神经网络不容易训练的问题,具体来讲,是为了解决网络训练过程中遇到的内部协变量偏移(Internal Covariate Shift, ICF)的问题。ICF指神经网络每一层的输入分布在训练过程中都会不断变化,从而造成网络的非线性激活逐渐饱和,使得网络难以得到有效训练。究其根本,批规范化有效的原因是它在一定程度上防止了“梯度弥散”。

BN的算法实现非常直接,可以表示为算法4.3。

可以看到相对于传统使用的数据规范化方法,BN有如下两个特点:

1.统计量的计算是以mini-batch为单位而不是在所有数据上进行的;

2.引入了两个额外的超参数γβ,用来对数据进一步地缩放和偏移(scale and shift)。

以mini-batch为单位计算均值和方差使得在网络训练过程中可以动态地调整各个隐层输出的分布,跟现在主流的基于mini-batch的网络优化方法比较兼容,同时可能带来的问题是,如果batch size比较小,则会造成统计量估计不稳定。而γβ的引入使得网络可以还原之前的输入,从而保证了加入BN操作后的网络保持原先的容量(capacity)。

总体来讲,采用批规范化可以在一定程度上解决网络训练中常遇到的梯度问题,从而使训练深度网络变得更稳定,同时可以加速网络训练过程。

4.3.6 批量块大小的选择

参数更新公式(4.14)和公式(4.15)需要从训练样本的一个批量集合(batch)中进行经验的梯度计算。而对批量大小的选择同时会影响收敛速度和模型结果。

最简单的批量选择是使用整个训练集。如果我们的唯一目标就是最小化训练集上的损失,利用整个训练集的梯度估计得到的将是真实的梯度(也就是说方差为0)。即使我们的目标是优化期望的损失,利用整个训练集进行梯度估计仍然比利用任何其子集得到的方差都要小。这种方法经常被称为批量训练(Batch Training)。它有如下优势:首先,批量训练的收敛性是众所周知的;其次,如共轭梯度和L-BFGS[190]等很多加速技术在批量训练中表现最好;最后,批量训练可以很容易地在多个计算机间并行。但是,批量训练需要在模型参数更新前遍历整个数据集,这对很多大规模的问题来说,即使可以应用并行技术,也是很低效的。

作为另一种选择,我们可以使用随机梯度下降(Stoachstic Gradient Decent,SGD)[191]技术,这在机器学习领域中也被称为在线学习。SGD根据从单个训练样本估计得到的梯度来更新模型参数。如果样本点是独立同分布的(这一点很容易保证,只要从训练集中按照均匀分布抽取样本即可),则可以证明

换句话说,从单个样本点进行的梯度估计是一个对整个训练集的无偏估计。然而,估计的方差为

除非所有的样本都是相同的,也即∇Jt(W, b; o, y)=E(∇Jt(W, b; o, y))(为简单起见,我们定义,否则上式取值总是非零的。因为上述算子对梯度的估计是有噪声的,所以模型参数可能不会在每轮迭代中都严格按照梯度变化。这看起来是不利之处,实则是SGD算法与批量训练算法相比的一个重要优势。这是因为DNN是高度非线性的,并且是非凸的,目标函数包含很多局部最优,其中不乏很糟的情况。在批量训练中,无论模型参数初始化在哪一个盆地(Basin)里,都将找到其最低点。这会导致最终模型估计将高度依赖初始模型。然而由于SGD算法的梯度估计带噪声,使它可以跳出不好的局部最优,进入一个更好的盆地里。这个性质类似于模拟退火[192]中让模型参数可以向局部次优而全局较优的方向移动的做法。

SGD通常比批量训练快得多,尤其表现在大数据集上。这是以下原因导致的:首先,通常在大数据集中,样例有很多是相似或重复的,用整个数据集估计梯度会造成计算力的浪费。其次,也是更重要的一点是,在SGD训练中,每看到一个样本就可以迅速更新参数,新的梯度不是基于旧的模型,而是基于新的模型估计得到的。这使得我们能够更快速地继续寻找最优模型。

然而,即使在同一台计算机上,SGD算法也是难以并行化的。而且,由于对梯度的估计存在噪声,它不能完全收敛至局部最低点,而是在最低点附近浮动。浮动的程度取决于学习率和梯度估计方差的大小。即使这样的浮动有时可以减小过拟合的程度,也并不是在各种情况下都令人满意。

一个基于批量训练和SGD算法的折中方案是“小批量”(Minibatch)训练。小批量训练会从训练样本中抽出一小组数据并基于此估计梯度。很容易证明,小批量的梯度估计也是无偏的,而且其估计的方差比SGD算法要小。小批量训练可以让我们比较容易地在批量内部进行并行计算,使得它可以比SGD更快地收敛。既然我们在训练的早期阶段比较倾向于较大的梯度估计方差来快速跳出不好的局部最优,在训练的后期使用较小的方差来落在最低点,那么我们可以在最初选用数量较少的批量,然后换用数量较多的批量。在语音识别任务中,如果我们在早期使用数量为64到256的样本,而在后期换用数量为1024到8096的样本,可以学习得到一个更好的模型。而在训练一个更深的网络时,在最初阶段选用一个数量更少的批量可以得到更好的结果。批量的数量多少可以根据梯度估计方差自动决定,也可以在每一轮通过搜索样本的一个小子集来决定[193, 194]

4.3.7 取样随机化

取样随机化(Sample Randomization)与批量训练是无关的,因为所有的样本都会被用来估计梯度。而在随机梯度下降和小批量训练中,取样随机化是十分重要的。这是由于为了得到对梯度的无偏估计,样本必须是独立同分布的。如果训练过程中连续的一些样本不是随机从训练集中取出的(例如,所有样本都来自同一个说话人),模型的参数将可能会沿着一个方向偏移得太多。

假设整个训练集都可以被加载进内存,取样随机化将变得很容易。只需要对索引数组进行排列,然后根据排列后的索引数组一个一个地抽取样本即可。索引数组一般比特征要小得多,所以这样做会比排列特征向量本身要轻量得多。这在每一轮次的完整数据训练都需要随机顺序不同的情况下尤甚。这样做也保证了每个样本在每一轮次的完整数据训练中都只被送到训练算法中一次,而不会影响到数据分布。这样的性质可以进一步保证学习出的模型的一致性。

如果我们使用像语音识别领域中那样较大规模的训练集,那么整个训练集将不可能被载入内存。在这种情况下,我们采用滚动窗的方式每次加载一大块数据(通常为24~48小时的语音或者8.6M到17.2M个样本)进内存,然后在窗内随机取样。如果训练数据的来源不同(例如来自不同的语言),则可以在将数据送进深层神经网络训练工具之前对音频样本列表文件进行随机化。

4.3.8 惯性系数

众所周知,如果模型更新是基于之前的所有梯度(更加全局的视野),而不是仅基于当前的梯度(局部视野),收敛速度是可以被提升的。使用这个结论的一个例子是Nesterov加速梯度算法(Nesterov’s Accelerated Gradient Algorithm)[195],它已经被证明在满足凸条件下是最优的。在DNN训练中,这样的效果通常采用一个简单的技巧——惯性系数来达到。当应用惯性系数时,公式(4.16)和公式(4.17)变成

其中,ρ是惯性系数,在应用SGD或者小批量训练的条件下,其取值通常为0.9~0.99[3]。惯性系数会使参数更新变得平滑,还能减少梯度估计的方差。在实践中,反向传播算法在误差表面(Error Surface)有一个非常窄的极小点的时候,通常会出现参数估计不断摆动的问题,而惯性系数的使用可以有效地缓解此问题,并因此加速训练。

上述惯性系数的定义在批量大小相同时可以表现得很好。而有的时候我们会想要使用可变的批量大小。例如,我们会希望类似在4.3.6节中讨论的那样,最初使用较小的批量,而在后面使用较大的批量。在第15章将要讨论的序列鉴别性训练中,每一个批量可能因为文本长度不同而使用不同的大小。在这些情况下,上述对惯性系数的定义便不再可用。既然惯性系数可以被考虑成一种有限脉冲响应(Finite Impulse Response,FIR)滤波器,我们可以定义在相同层面下的惯性系数为ρs,并推出在不同批量大小Mb的条件下的惯性系数取值为

ρ=exp(Mbρs)  (4.48)

4.3.9 学习率和停止准则

训练DNN中的一个难点是选择合适的学习策略。理论显示,当学习率按照如下公式设置时,SGD能够渐进收敛[191]

其中,t是当前样本的数量,c是一个常量。实际上,这种学习率将很快变得很小,导致这种衰减策略收敛很慢。

请注意,学习率和批量大小的综合作用会最终影响学习行为。像我们在4.3.6节中讨论的那样,我们在开始几次完整的数据迭代中用更小的批量数量,在后面的数据中使用更大的批量数量。既然批量大小是一个变量,我们可以定义每一帧的学习率为

并将模型更新公式变为

与原始的学习率定义相比,上述改变也减少了一次矩阵除法。

使用这个新的更新公式时,我们可以凭经验确定学习策略。首先确定批量大小及一个大的学习率。然后训练数百个小批量数据组,这在多核CPU或GPU上通常要花费数分钟,我们在这些小批量训练上监视训练准则变化,然后减少批量中的数据数量、学习率或者两个同时减小,以使ϵsMb结果减半,直到训练准则获得明显的改善。然后把学习率除以2作为下一个完整数据迭代轮次的初始学习率。我们会运行一个较大的训练数据子集,把ϵsMb的值增加四到八倍。请注意,这个阶段的模型参数已经被调整到一个相对好的位置,因此增加ϵsMb将不会导致发散,而会提高训练速度。这个调整过程在文献[193]中的模型已经可以自动进行。

我们发现两个有用的确定其余学习率的策略。第1个策略是如果观察到训练准则在大的训练子集或开发集上有波动的情况,就把批量大小加倍,并将学习率减少1/4,同时,在学习率小于一个阈值或者整体数据的训练迭代次数已经达到预设次数的时候停止训练。第2个策略是在训练准则波动时减少学习率到一个很小的数,并在训练集或开发集上再次出现训练准则波动时停止训练。对于从头开始训练的语音识别任务,我们发现在实际情况下,ϵs对深层和浅层网络分别取值0.8e−4和0.3e−3,在第2阶段取值1.25e−2,在第3阶段取值0.8e−6,效果很好。超参数的搜索也可以自动使用随机搜索技术[185]或者贝叶斯优化技术[196]

4.3.10 网络结构

网络结构可以被认为是另外需要确定的参数。既然每层都可以被认为是前一层的特征抽取器,那么每层节点的数量都应该足够大以获取本质的模式。这在模型底层是特别重要的,因为开始层的特征变化比其他层更大,它需要比其他层更多的节点来模拟特征模式。然而,如果某层节点太大,它容易在训练数据上过拟合。一般来说,宽且浅的模型容易过拟合,深且窄的模型容易欠拟合。事实上,如果有一层很小(通常被称为瓶颈),模型性能将有重大的下降,特别是当瓶颈层接近输入层时。如果每层都有相同数量的节点,则添加更多的层可能把模型从过拟合转为欠拟合。这是因为附加的层对模型参数施加了额外的限制。由这个现象,我们可以先在只有一个隐层的神经网络上优化每层的节点个数,然后叠加更多的相同节点个数的隐层。在语音识别任务中,我们发现拥有5~7层,每层拥有1000~3000个节点的DNN效果很好。相对一个窄且浅的模型,通常在一个宽且深的模型上更容易找到一个好的配置。这是因为在宽且深的模型上有更多性能相似的局部最优点。

4.3.11 可复现性与可重启性

在DNN训练中,模型参数都是被随机初始化的,而且模型样本都是以随机的顺序进入训练器的。这不可避免地增加了我们对训练结果可复现性的担心。如果我们的目标是对比两个算法或者模型,我们可以多次运行实验,每次用一个新的随机种子并记录平均的结果及标准的误差。但在一些其他情况下,我们可能要求在运行两次训练后获得恰好完全一样的模型及测试结果。这可以通过在模型初始化及训练样本随机化时使用相同的随机种子来实现。

当训练集很大的时候,通常需要在中间停止训练并在最后的检查点继续训练。这时,我们需要在训练工具中嵌入一些机制,来保证从检查点重新开始将产生和训练没有中断时完全一样的结果。一个简单的诀窍是在检查点的文件中保存所有必要的信息,包括模型参数、当前随机数、参数梯度、惯性系数等。另一个需要保存更少数据的有效方法是在每个检查点都重置所有的学习参数。

[1]深层神经网络这个术语首次在语音识别中出现是在文献[13] 中。在文献[12] 中,早期使用的术语“深度置信网络”(Deep Belief Network)被更加合适的术语“深层神经网络”(Deep Neural Network)所代替。深层神经网络这个术语最开始用来指代多隐层感知器,然后被延伸成有深层结构的任意神经网络。

[2]虽然反向传播这个术语是在1986 年的文献[47]中才被确定的,但是作为一个多阶段动态系统最优化方法,这个算法的产生其实可以追溯到1969 年的文献[184]。

[3]在实践中,我们发现如果在第一轮训练之后再应用惯性系数,则可以得到更好的结果。