文章目录

  • 输入处理
  • 输出处理
  • 模型
    • Listen, Attend, and Spell (LAS)
      • Listen
      • Attention
      • Spell
    • Connectionist Temporal Classification (CTC)
    • RNN Transducer (RNN-T)
    • Neural Transducer
    • Monotonic Chunkwise Attention (MoChA)
  • HMM
    • 引入深度学习
  • Alignment of HMM, CTC and RNN-T
  • Language Modeling
    • N-gram语言模型
    • NN-based LM
  • 参考

  在语音辨识中输入是语音信号,输出是对应的文字。语音表示为一个序列向量(长度为T\text{T}T,维度为 d\text{d}d)。输出的Text一般表示为一个Token序列,长度为N\text{N}NV\text{V}V个不同的token所构成,通常 T>N\text{T} > \text{N}T>N

  在实际运用的过程中,有时候也会从声音信号直接得到word embeddings,或者连着翻译(Translation)一起做了,或者引入意图分类( Intent classification,常见于客服电话这些),或者加上槽填充(Slot Filling,填槽指的是为了让用户意图转化为用户明确的指令而补全信息的过程,我的理解是:比如在Chatbot中引导用户给出明确指令。)

输入处理

  拿到一个语音信号我们一般是如何处理的呢?也就是如何将语音信号表示为一个序列向量(长度为T\text{T}T,维度为 d\text{d}d)。或者称之为提取它的声学特征(acoustic feature),下图是一种解决办法的流程:

  拿到一段语音信号之后首先需要对其进行初步处理,一般25ms的时间窗取出一个frame(对应就有400个采样点(16KHz);使用MFCC会得到39维向量、filter bank输出是80维),然后开始滑动,类似滤波操作,一般每个时间窗的间隔为10ms,那么1s内就有100frame。更多的学习资料可以参考:

  • 數位語音處理 第七章Speech Signal and Front-end Processing

  如何处理每个frame呢?如下图所示:

  先输入声音信号,经过离散傅里叶变换(DFT) 变成频谱图,经过多个不同的filter bank(古圣先贤们设计出来的)处理后, 得到一系列向量,通过对数变换,再经过离散余弦变换(DCT),使用再结合MFCC方法得到向量。当然在实际过程中很多学者也不是都采取需要将上述过程全部走完得到MFCC输出的方式,2019年大部分工作都是在filter bank输出之后就将其作为特征输出。

输出处理

  输出问文字部分,文字的表示方法不同大体可以分为以下五种:

  1. Phoneme(phoneme,发音的基本单位):这里相当于音标,然通过Lexicon(词典)将phoneme转换成word。而这个词典需要语言学家事先定义好,因此是这种方法的弊端。
  2. Grapheme:(Grapheme,书写的基本单位),也就是说通过字母,标点,空格这些来表示一个词。比如one_punch_man这个词中N=13, V=26+;如果是中文,则由单个汉字组成文本,比如:“一”,“拳”,“超”,“人”,N=4, V≈4000
  3. Word:顾名思义,就是用词来表示句子,但是有些词汇可能超大,无法穷举。
  4. Morpheme:(Morpheme,语素,可以传达意思的最小单位,小于词,大于字母),例如英文中:unbreakable可以拆成 “un“ ”break“ ”able”。语素的获取主要有两种方式,一种是由语言学家给出,另一种是统计单词中某些字母的组合,从而进行估计。
  5. Bytes:当然还有一种暴力的方法,通过字节直接定义,此时V一直可表示为256(8字节)。

  2019年使用最多的是grapheme这种字母的表现形式。

模型

  传统的神经网络模型无法解决变长的序列学习问题。主流的有两种解决思路:1. Encoder-Decoder;2. Connectionist Temporal Classification (CTC)。

Listen, Attend, and Spell (LAS)

  LAS15年比较流行的几个动词叠在一起的叫法,本质还是Seq2seq

  • Listen, Attend and Spell:https://arxiv.org/abs/1508.01211v2

  属于Encoder-Decoder,只不过在神经网络中加了attention机制,主要是提取特征,过滤掉杂讯信号。LAS主要可以分三点来展开:Listen, AttendSpell

Listen

  Listen部分主要是时序声音信号的处理,可以采用循环神经网络(RNN)、或者卷积神经网络(CNN)的方式来处理,而目前主流的方法都是在循环处理部分引入self-attention机制。而声音的时序信号往往太长,相邻的声音讯号在RNN序列中带有重复信息,因此在这里做下采样能够大大减少运算量但对实际效果影响会比较小。作者这里采用了Pyramin RNN这样一种下采样(Down Sampling)的技术。

  Down Sampling大体上可以分为4种:

  1. Pyramin RNN:用于LAS中,如果没有Pyramin RNNLAStrain不起来的,所以起到了至关重要的作用,主要是将RNN的输出的相邻两个节点进行相加

  1. Pooling Over Time:用于RNN中,将RNN输出相邻两个中只取一个。首次提出是Bahdanau. et al.,在ICASSP’16上提出。

  • End-to-End Attention-based Large Vocabulary Speech Recognition

  1. Time-Delay DNNTime-Delay DNN也被称作时延神经网络,早在1989年就已经被提出。主要目的有两个:1)使用不变性对模式进行分类,以及 2)在网络的每一层建模上下文。

  不变移位分类意味着分类器在分类之前不需要显式分割。对于时间模式(例如语音)的分类,TDNN因此避免了在对声音进行分类之前必须确定声音的起点和终点。

  对于TDNN中的上下文建模,每一层的每个神经单元不仅从下一层的激活/功能接收输入而且从单元输出及其上下文的模式接收输入。对于时间信号,每个单元随时间从下面的单元接收激活模式作为输入。将TDNN应用于二维分类(图像,时频图)时,可以在坐标空间中进行平移不变性训练,并避免在坐标空间中进行精确分割

  用于CNN的一维卷积中,可以值取CNN输出的第一个和最后一个,与Dilated CNN(空洞卷积)类似。

  • Waibel, A., Hanazawa, T., Hinton, G. E., Shikano, K., & Lang, K. J. (1989). Phoneme recognition using time-delay neural networks. IEEE Transactions on Acoustics, Speech, and Signal Processing, 37(3), 393-404.

  • Peddinti, V., Povey, D., & Khudanpur, S. (2015). A time delay neural network architecture for efficient modeling of long temporal contexts… conference of the international speech communication association.

  1. Truncated Self-Attention:以往的attention是注意在整个sequence上面,而truncated self-attention只考虑部分sequence,因为语音的sequence非常长。具体多长是一个需要调整的参数,也就是说只注意一个窗口内的元素,至于这个窗口是多大是一个待调整的参数。

  • Transformer-Transducer: End-to-End Speech Recognition with Self-Attention

Attention

  对于attention不了解的可以参考以下文章:

  • TransFormer学习笔记附代码(一)

  这里对其数学部分进行简要描述:

  首先我们有一个序列:x1,⋯,xix_{1},\cdots,x_{i}x1,,xi,是我们的输入信号,首先经过一个学习权重矩阵 WWW 得到输出:a1,⋯,aia_{1},\cdots, a_{i}a1,,ai (即ai=Wxia^{i}=Wx^{i}ai=Wxi)。再将每个 aia_{i}ai 乘以三个不同的权重参数:WqW^{q}WqWkW^{k}WkWvW^{v}Wv,得到query qiq^{i}qikey kik^{i}kivalue viv^{i}vi

qi=Wqaiki=Wkaivi=Wvaiq^{i} =W^{q}a_{i}\\ k^{i} =W^{k}a_{i}\\ v^{i} =W^{v}a_{i} qi=Wqaiki=Wkaivi=Wvai

  每个query qqq 对每个key kkkattention (相当于对每个输入乘以权重系数,用于表示输出更注重于哪个输入,用这种乘以权重系数的方法表述注意力机制):

α1,i=q1⋅ki/d\alpha_{1,i} = q^{1} \cdot k^{i} / \sqrt{d} α1,i=q1ki/d

  也就是Attention是吃两个向量,输出这两个向量有多匹配(输出一个分数),可以看到上述方法是采用Scaled Dot-Product Attention的方式得到。dddqqqkkk 的维度,除以d\sqrt{d}d

是相当于归一化的处理,用于减少方差。

  除了Dot-product Attention的方法还有Additive Attention的方法,即二者相加再经过tanh函数和权重矩阵得到最后的α\alphaα结果,可以如下文献中找到具体算法:

  • Chorowski, J., Bahdanau, D., Serdyuk, D., Cho, K., & Bengio, Y. (2015). Attention-based models for speech recognition. neural information processing systems.

  到此我们可以得到对输入iii个向量xix_{i}xi的全部注意力α1,1⋯,α1,i\alpha_{1,1} \cdots, \alpha_{1,i}α1,1,α1,i,再将其送入Softmax层得到α^1,i\hat{\alpha}_{1,i}α^1,i

α^1,i=exp⁡(α1,i)/∑jexp⁡(α1,j)\hat{\alpha}_{1, i}=\exp \left(\alpha_{1, i}\right) / \sum_{j} \exp \left(\alpha_{1, j}\right)α^1,i=exp(α1,i)/jexp(α1,j)

  再将α^1,i\hat{\alpha}_{1,i}α^1,iviv^{i}vi相乘再求和得到第一个输出:b1=∑iα^1,ivib_{1}=\sum_{i}\hat{\alpha}_{1,i}v^{i}b1=iα^1,ivi。由此可以看出attention通过α^\hat{\alpha}α^决定看哪些信息,不看哪些信息。用 q2q_{2}q2attention,依此类推可以计算得到b2b_{2}b2。而上述算法其实就是一堆矩阵运算,因此可以用GPU加速。(当然上述的attention过程可以做多份,也就是类似的 qqqkkkvvv做多份,只要是由不同的参数矩阵WWW所生成出来的就可以,这种叫做Multi-head Self-attention。对于输入有先后关系的数据需要引入位置编码(Positional Encoding)将位置信息送入)。

  LAS中的做法与之有些许不同:

  编码器和解码器中间的注意层会有一个z0z^{0}z0参数作为要搜索的Query,而编码器输出的隐层嵌入每位置的向量hih^{i}hi是要注意的Key。我们用z0z^{0}z0和每一个hih^{i}hi去计算注意力得分(点积或加性的方式):

  之后 c0c^{0}c0 会是decoder的输入。

Spell

  c0c^{0}c0z0z^{0}z0(关键字) 作为 解码器RNN的第一个输入,然后输出一个token的分布,取max可以得到第一个token

  再拿z1z_{1}z1与原编码器的隐层向量做注意力,得到一个新的注意力分布c1c^{1}c1,再次输入给RNN,得到第二个token,直到终止符<EOS>

  由于解码中RNN的输出会影响下一个点的输出,因此有了Greedy DecodingBeam Search两种方式。这里考虑RNN输出只有两种情况的例子对其举例说明。若采用Greedy Decoding的方式:

  会得到ABB的输出结果,但是BBB的置信分数确是最高的。Beam Search的方式是说每次找K条路径进行搜索,窗口大小为K的贪心搜索。从每个节点我们都保留K个最好的路径,一直往下。

  如果在训练RNN的时候,第二个节点用第一个节点真实的标签进行训练的话,这种技术叫做Teacher Forcing

  之前的注意力阶段,我们每次是用解码器的输出隐层去与编码器的输出做注意力。除此以外,还有另一种做注意力的方式。我们把解码器的隐层ztz_{t}zt拿出来与hih_{i}hi做注意力得到ctc^{t}ct。这个ctc^{t}ct不是保留到下一个时间才使用,在当前时间点立刻使用。我们把ztz_{t}ztctc^{t}ct丢给解码器RNN,得到新分布zt+1z_{t+1}zt+1。这两种注意力的区别在,注意力得到的结果是下一个时间使用还是当前时间使用。在LAS中作者采用了全都要的方式:

  • Location-aware attention

  语音识别是否非要用注意力不可呢?注意力最早是用在Seq2Seq翻译上解决源语言与目标语言的对齐问题。这个弹性很大的注意力,在语音上用会有种杀鸡焉用牛刀的感觉。因为语音上,每次注意跳跃是有限的。而不会出现像机器翻译那样,开头注意到结尾的的大跳跃情况。我们可以用Location-aware attention来优化。我们的注意力不能够随便乱跳,而是要考虑前一个时间步得到的注意力权重影响。我们把ttt之前的注意力权重α0\alpha_{0}α0αt−1\alpha_{t-1}αt1的向量,做一个线性映射后再输入给解码RNN。 这样模型就能学到,每解码出一个token,注意力就要往右移动一点。

  LAS模型需要在海量数据集上训练,和一些调参技巧,与传统方法相比才会有显著提升。但LAS有另一个好处是,它的模型参数可以比传统方法变得很小。

  LAS的注意力可视化出来发现,即便没有用Location-aware attention,模型也可以自己学到这样的注意规律。

  LAS虽然神通广大,但它也有一些问题。我们期待我们的模型可以做online的识别,即能够一边听,一边做语音识别。而不是模型听完整句话后,等上一秒,模型才输出辨识结果。往后要讲的模型,就是解决LAS的这个问题。

Connectionist Temporal Classification (CTC)

  • Graves, A., Fernandez, S., Gomez, F., & Schmidhuber, J. (2006). Connectionist temporal classification: labelling unsegmented sequence data with recurrent neural networks. international conference on machine learning.

  CTC是能够做到on-line的语音辨识算法,因为是Online的算法,所以其RNN输入是单向的。在RNN输出后接一个线性模型用于预测token的分布。

  RNN中输入语音信号xix^{i}xi,得到输出hih^{i}hi,再经过一个线性模型,相当于乘以参数矩阵WWW再经过Softmax层得到token的分布。由于在语音信号中当前的音频 xix^{i}xi 可能并没有对应的token,往往是多个xix^{i}xi才能得到一个token,所以预测的token类别要多一个空的类别,用ϕ\phiϕ定义,表示模型并不知道要输出什么。

  CTC没有下采样(down sampling) 因此输入 TTTacoustic features,会输出得到 TTTtokens,这 TTTtokens会包含ϕ\phiϕ,并且我们需要合并相同的tokens,并移除ϕ\phiϕ。如果我们得到的输出为ϕϕddϕeϕeϕpp\phi \phi \mathrm{d} \mathrm{d} \phi \mathrm{e} \phi \mathrm{e} \phi \mathrm{p} \mathrm{p}ϕϕddϕeϕeϕpp,那我们最终得到的输出就是deep

  这也会存在一个问题,就是输入的语音信号往往是会比输出的token要多的,那此时的label就会有很多种情况,比如ϕdddϕeϕeϕpp\phi \mathrm{d} \mathrm{d} \mathrm{d} \phi \mathrm{e} \phi \mathrm{e} \phi \mathrm{p} \mathrm{p}ϕdddϕeϕeϕpp也代表是deep,这样的话标注就会变的非常困难。CTC的训练过程中穷举所有的label,做cross-entropy

  • Graves, A., & Jaitly, N. (2014). Towards End-To-End Speech Recognition with Recurrent Neural Networks. international conference on machine learning.

  token采用词汇的方式也会有效果,可参考下文。

  • Sak, H., Senior, A. W., Rao, K., & Beaufays, F. (2015). Fast and Accurate Recurrent Neural Network Acoustic Models for Speech Recognition. arXiv: Computation and Language,.

  CTC的算法也存在一些问题,比如后面输出的token并不知道前面token所发生的事情,即线性模型的解码器是独立工作的,如果训练的时候label还穷举所有可能的话,就会存在前面如果输出了正确的token d\mathrm{d}dϕ\phiϕ 之后,后面的输出并不知道这一点可能会再次输出 d\mathrm{d}d 导致重复。也就是我们需要考虑线性模型这一层的前后依赖关系。

RNN Transducer (RNN-T)

  在RNN-T之前,有一个算法是用来解决线性模型这一层的前后依赖关系的,Recurrent Neural Aligner(RNA)由Sak, H在2017年提出:

  • Sak, H., Shannon, M., Rao, K., & Beaufays, F. (2017). Recurrent Neural Aligner: An Encoder-Decoder Neural Network Model for Sequence to Sequence Mapping. conference of the international speech communication association.

  主要工作是将线性模型那一层神经网络换成了RNN

  在此基础之上,如果我们让解码的RNN是吃一个输入,输出多个token,比如th只是一个音。对于CTC而言,它只能先输出t再在下一个时间点解码输出h,而我们希望它直接输出th。这种输入一个隐层,预测多个tokens的模型便是RNN-T

  如上图所示,这种方式会有 TTTϕ\phiϕ 的输出。RNN-TCTC同样会遇到训练数据难标注,标注多标准的问题。我们会穷举所有可能的标注给模型训练。

Neural Transducer

  Neural Transducer与之前所作方法的改变在输入 hih^{i}hi 上,其输入不再是单个 hih^{i}hi ,而是一把 hih^{i}hi,然后做attention

  首先我们会让声学特征通过编码器产生隐层输出,再对一个窗口的小范围隐层做注意力后,再输出给解码的RNN。若窗口大小内信息已经用完了,解码的RNN就会输出空类别。接下来我们再移动窗口,对下一个窗口内的隐层重复刚才的操作。

  • Jaitly, N., Le, Q. V., Vinyals, O., Sutskever, I., Sussillo, D., & Bengio, S. (2016). An Online Sequence-to-Sequence Model Using Partial Conditioning. neural information processing systems.

Monotonic Chunkwise Attention (MoChA)

  MoChA是一种动态的窗口移动算法(dynamically shift the window),能够动态地去调整窗口到底放在哪里会比较好。

  输入z0和隐层h1,输出yes/no,表示要不要把窗口开头放在此处位置。如果不要,就往右移动窗口,再检查下一个位置的隐层h2。一旦确定放置窗口,就对窗口内的隐层向量做注意力,解码出的token不会包含空类别。

  • Chiu, C., & Raffel, C. (2018). Monotonic Chunkwise Attention. international conference on learning representations.

HMM

  HMM (Hidden Markov Model) 与上述这种End-To-End的神经网络方法有什么区别呢?以前神经网络不像现在这么流行的时候是如何来做这样一件事情的呢?

  语音辨识要做的事情就是输入一个向量XXX,输出产生一串token YYY。传统的HMM采用统计的方法,穷举所有可能的YYY,找到一个可以使得P(Y∣X)P(Y|X)P(YX)最大的那一个YYY,即:Y∗=arg⁡max⁡YP(Y∣X)Y^{*}=\arg \max _{Y} P(Y | X)Y=argmaxYP(YX),也就得到了最终的结果。这种算法通常被称作解码(decode),根据贝叶斯定律我们有以下等式变换:

Y∗=arg⁡max⁡YP(Y∣X)=arg⁡max⁡YP(X∣Y)P(Y)P(X)=arg⁡max⁡YP(X∣Y)P(Y)\begin{array}{l} \mathrm{Y}^{*}=\arg \max _{\mathrm{Y}} P(\mathrm{Y} | X) \\ \qquad \begin{array}{l} =\arg \max _{\mathrm{Y}} \frac{P(X | \mathrm{Y}) P(\mathrm{Y})}{P(X)} \\ =\arg \max _{\mathrm{Y}} P(X | \mathrm{Y}) P(\mathrm{Y}) \end{array} \end{array}Y=argmaxYP(YX)=argmaxYP(X)P(XY)P(Y)=argmaxYP(XY)P(Y)

  前面这项P(X∣Y)P(X|Y)P(XY)Acoustic ModelHMM可以建模,后面那项P(Y)P(Y)P(Y)Language Model,有很多种建模方式。

  输出的YYY可以有很多不同的粒度,比如拿音标,字或词。但这些单位,对HMM的隐变量来说,都太大了。所以我们需要为P(X∣Y)P(X|Y)P(XY)建模,变成为P(X∣S)P(X|S)P(XS)建模。SSS为状态,是人定义的。它是比音素Phoneme还要小的单位。序列中的每一个音素,都会受到前后音素单位的影响。我们会用一个Tri-phone,把当前的每一个音素,都加上它前后的音素,相当于把原来的音素切得更细。这样d后面的uw,和y后面的uw表达出来就会是不同的单位。

  HMM建模过程中有两种概率:一种是转移概率(Transition Probability),如P(b∣a)P(b|a)P(ba),即当前状态转移到其它状态或不转移状态的概率,另一种是输出概率(Emission Probability),如P(x∣"t−d+uw1")P(x|"t-d+uw1")P(x"td+uw1"),即该状态输出某个样子的声学特征向量的概率。 假设每一个状态,它产生出来的声学特征向量有一个固定的分布。我们可以用高斯混合模型,或者GMM来表示这个概率。

  这便是为什么我们要用比Phoneme还要小的单位来表示状态。因为我们要假设每个状态输出出来的分布稳定。为什么我们不用字符单位来当作状态呢?c这个字母它的发音不是固定的。它在很多时候是发"ke",但它在h后面就发音"ch"。这样就不适合拿来当作HMM的状态。

  假设我们已经用给定好的数据算好了Emission ProbabilityTransition Probability,我们还是算不出P(X∣S)P(X|S)P(XS)的概率。假设我们有3个状态abc。我们需要知道把它变成aabbcc的序列才可以和声学特征对齐一样,但是会存在很多各种不同可能的对齐方式,比如h=abbbbch = abbbbch=abbbbc。给定的候选对齐状态不同,算出来产生的声学特征的概率P(X∣h)P(X|h)P(Xh)也就会不一样。因此就需要穷举所有可能,找到它产生与观测XXX的声学特征概率最大,最一致的对齐方式。关键技术在Alignment

Pθ(X∣S)=?∑h∈align(S)P(X∣h)\mathrm{P}_{\theta}(X | S)=? \sum_{h \in align(S)} P(X | h)Pθ(XS)=?halign(S)P(Xh)

引入深度学习

  1. Tandem:之前的声学特征用的是MFCC做的,深度学习在做的是,输入一个MFCC,预测它属于哪个状态的概率。
  2. DNN-HMM HybridHMM中有一个高斯混合模型。我们想把它用DNN取代掉。高斯混合模型做的事情是给定一个状态,预测声学特征向量的分布,即P(x∣a)P(x|a)P(xa)DNN是训练一个State的分类器,计算给定一个声学特征下,它是某个状态的概率,即P(a∣x)P(a|x)P(ax)。基于贝叶斯定律,可以得到P(x∣a)=P(a∣x)P(x)/P(a)P(x|a) = P(a|x)P(x) / P(a)P(xa)=P(ax)P(x)/P(a)P(a)P(a)P(a)可以通过在训练资料中统计得到。P(x)P(x)P(x)可以忽略。

  我们要如何训练一个状态分类器呢?它的输入是一个声学特征(Acoustic features),输出是它是某个状态的概率。做这样的任务我们需要标注数据(每个声学特征和状态之间的对应关系),但是我们并没有这样的标注数据。过去的做法是训练一个HMM-GMM,那这个粗糙的模型去做找出一个概率最大的对齐。然后再根据声学特征与状态之间的对齐数据,去训练状态分类器。

  接着,我们再拿这个训练好的状态分类器,替换掉原来的HMM-GMM 再对数据对齐,来训练出一个更好的状态分类器。我们反复重复这个过程。用训练得到的DNN去对数据做对齐,再用对齐的数据去训练一个新的DNN

  • Yu, D., Xiong, W., Droppo, J., Stolcke, A., Ye, G., Li, J., & Zweig, G. (2016). Deep Convolutional Neural Networks with Layer-Wise Context Expansion and Attention… conference of the international speech communication association.

  • Saon, G., Kurata, G., Sercu, T., Audhkhasi, K., Thomas, S., Dimitriadis, D., … & Hall, P. (2017). English Conversational Telephone Speech Recognition by Humans and Machines… conference of the international speech communication association.

Alignment of HMM, CTC and RNN-T

  对于端对端的语音识别系统,比如说LAS,你可以想成它可以直接计算P(Y∣X)P(Y|X)P(YX)。对于序列中的第一个c0c_{0}c0,它通过RNN计算P(a∣c0)P(a|c_{0})P(ac0)的概率。生成出aaa之后,它又计算P(b∣a,c0,c1)P(b|a,c_{0},c_{1})P(ba,c0,c1)的概率……我们把这些每步计算的概率连乘起来就可以得到P(Y∣X)P(Y|X)P(YX)。训练的时候,是找一个最优的模型参数,来让P(Y^∣X)P(\hat{Y}|X)P(Y^X)越大越好。而测试(解码)的时候,则是用Beam Search来遍历所有可能的YYY,来让P(Y∣X)P(Y|X)P(YX)越大越好,如下图所示:

  对于CTCRNN-T是无法直接计算P(Y∣X)P(Y|X)P(YX)的,我们需要额外的alignment(使得输出、输入长度对齐,一样),也就是我们需要先计算P(h∣X)P(h | X) \quadP(hX),其中h=aϕbϕ→abh=a \phi b \phi \rightarrow a bh=aϕbϕab

P(Y∣X)=∑h∈align(Y)P(h∣X)\mathrm{P}(\mathrm{Y} | X)=\sum_{h \in \text {align}(Y)} P(h | X)P(YX)=halign(Y)P(hX)

  那如何穷举所有可能的alignment?如何把所有的alignment加起来,如何来训练 θ∗=arg⁡max⁡θlog⁡Pθ(Y^∣X)\theta^{*}=\arg \max _{\theta} \log \mathrm{P}_{\theta}(\hat{Y} | X)θ=argmaxθlogPθ(Y^X)?若采用梯度下降算法,那得对其求梯度∂Pθ(Y^∣X)∂θ=?\frac{\partial \mathrm{P}_{\theta}(\hat{Y} | X)}{\partial \theta}=?θPθ(Y^X)=?,如何计算?当模型训练好了,又要怎么做推断 Y∗=arg⁡max⁡YP(Y∣X)Y^{*}=\arg \max _{Y} P(Y | X)Y=argmaxYP(YX) 呢?

  1. 穷举所有可能的alignment:假设输入有6个声学特征向量,输出是三个以英文字母为最小单位的tokens,“c”, “a”, 和"t"。虽然实际中不会用字符为最小单位,但这里我们只是为了方便比较。对于HMM,它们为隐变量状态。我们需要对cat分别做一些重复,变成ccaaat或者 caaaat等等。而对于CTC,它有两种选择,一个是重复,另外一个是加上空类别,变成 cϕaattc\phi aattcϕaatt或者 ϕcaϕtϕ\phi ca\phi t\phiϕcaϕtϕ等等。对于RNN-T,它要加上Tϕ\phiϕ。它的运作是每次解码器输出一个ϕ\phiϕ的时候,它就读下一个声学特征。因此它需要输出6ϕ\phiϕ,才能把所有的声学特征读完。变成cϕϕϕaϕϕtϕc\phi \phi \phi a\phi \phi t\phicϕϕϕaϕϕtϕ 或者 c∅∅a∅∅t∅∅c∅∅a∅∅t∅∅cat等等,每一种就是一个alignment。但对于LAS来说,它完全不需要考虑对齐的问题。

  用隐马尔可夫链来可视化三种模型的对齐方式,就可以直观地看到他们的关联:

  1. 计算所有的alignments总和:假设 h=ϕh=\phih=ϕ с ϕϕ\phi \phiϕϕ а ϕ\phiϕ t ϕϕ\phi \phiϕϕ,此条alignment概率计算公式为:P(h∣X)=P(ϕ∣X)×P(c∣X,ϕ)×P(ϕ∣X,ϕc)⋯P(h | X) =P(\phi | X) \times P(c | X, \phi) \times P(\phi | X, \phi c) \cdotsP(hX)=P(ϕX)×P(cX,ϕ)×P(ϕX,ϕc)

  RNN-TCTC不同的地方在,它另外训练了一个解码的RNN。这个RNN会把解码出来的token当作输入,去影响它接下来的输出。一开始我们没有任何输入,就先输入一个让它产生一个向量。一开始产生的是l0l_{0}l0,我们把编码产生的h1h_{1}h1,与l0l_{0}l0一起输入给解码器MLP,让它产生一个概率p1,0p_{1,0}p1,0,表示输入第一个隐层,没产生任何token时,RNN-T产生出的概率分布。它是ϕ\phiϕ放在句首的概率。接下来我们要算,有了这个ϕ\phiϕ之后,产生下一个tokenc的概率。上面的解码RNN也不会造成任何影响。它只在解码器MLP生成了实在的token,它才会往下计算。但产生ϕ\phiϕ是表示当前由编码器输出的隐层h1h_{1}h1的信息模型已经用尽了。接下来我们要计算下一个token的隐层h2h_{2}h2。我们把h2h_{2}h2和之前的l0l_{0}l0一起输入编码器MLP,输出得到概率p2,0p_{2,0}p2,0。由于我们解码出了实在的token ccc。往后一步这个ccc就会输入给上面的RNN,来计算一个新的l1l_{1}l1l1l_{1}l1h2h_{2}h2一起丢给解码器MLP就会得到概率p2,1p_{2,1}p2,1。以此类推… 这些输出的概率全部相乘,就是最终P(h∣X)P(h|X)P(hX)的概率。

  RNN-T 它神奇的地方是,它把 tokentoken之间的关系,独立用 RNN 来表示。这刚好是HMM的独立观测假设。

  HMM是用向前和向后传播算法来计算所有候选对齐的概率分数。RNN-THMM所用的方法,是一模一样的。我们定义αi,jα_{i,j}αi,j为,已经读了第iii个声学特征且输出了第jjjtoken的所有对齐分数之和。比如说α4,2α_{4,2}α4,2可以从α4,1α_{4,1}α4,1α3,2α_{3,2}α3,2转移过来,那么就有α4,2=α4,1p4,1+α3,2p3,2α_{4,2} = α_{4,1} p_{4,1} + α_{3,2}p_{3,2}α4,2=α4,1p4,1+α3,2p3,2。如此一来,我们就很容易推出动态规划的递推式 αi,j=αi−1,jpi−1,j+αi,j−1pj−1,iα_{i,j} = α_{i-1,j}p_{i-1,j} + α_{i,j-1}p_{j-1,i}αi,j=αi1,jpi1,j+αi,j1pj1,i。这样我们只需要遍历一个T×NT \times NT×N的网格,我们就能算出所有的分数之和。有了所有候选对齐的概率分数之和,我们就得到了P(Y∣X)P(Y|X)P(YX)

  1. 接下来是思考要怎么训练了。我们要找到一个模型参数 θ\thetaθ,来让 logP(Y^∣X)logP(\hat{Y}|X)logP(Y^X)最大。

∂P(P∣X)∂θ=?∂p4,1(a)∂θ∂P(P∣X)∂p4,1(a)+∂p3,2(ϕ)∂θ∂P(P∣X)∂p3,2(ϕ)+⋯\frac{\partial P(P | X)}{\partial \theta}=? \quad \frac{\partial p_{4,1}(a)}{\partial \theta} \frac{\partial P(P | X)}{\partial p_{4,1}(a)}+\frac{\partial p_{3,2}(\phi)}{\partial \theta} \frac{\partial P(P | X)}{\partial p_{3,2}(\phi)}+\cdotsθP(PX)=?θp4,1(a)p4,1(a)P(PX)+θp3,2(ϕ)p3,2(ϕ)P(PX)+

  对于前一项,每个箭头对参数θ\thetaθ的偏微分,计算方式就是经典的BPTT时序的反向传播。一开始最右边的结果计算和标签的损失,反向传播传到编码器,再传到上面的解码器RNN

  对于后一项,整个P(Y^∣X)P(\hat{Y}|X)P(Y^X)对每个箭头的偏微分,我们要先用之前的动态规划算法得到P(Y^∣X)P(\hat{Y}|X)P(Y^X)。算的时候,要把包含当前pi,jp_{i,j}pi,j和不包含当前pi,jp_{i,j}pi,j分开来计算。对于前面包含pi,jp_{i,j}pi,j的,求导后就只剩非pi,jp_{i,j}pi,j的概率相乘求和。对于第二项没有包含pi,jp_{i,j}pi,j的求导,它就没了。我们把第一项再整理一下,就可以得到最终的计算式。得到P(Y^∣X)P(\hat{Y}|X)P(Y^X)后除以当前箭头pi,jp_{i,j}pi,j的概率。

  这时,我们再引入另一个辅助变量βi,jβ_{i,j}βi,j。它与αi,jα_{i,j}αi,j很像,它表示从第iii个声学特征开始且输出到第jjjtoken的所有候选对齐分数之和。β4,2β_{4,2}β4,2如图所示,它表示已经产生了4个声学特征和输出两个token的情况下,它们当前位置走到结尾为止的所有路径的分数总和。βi,jβ_{i,j}βi,j刚好是αi,jα_{i,j}αi,j的反过来。前面αi,jα_{i,j}αi,j对应着 HMM 的正向传播算法,这里βi,jβ_{i,j}βi,j对应着 HMM 的反向传播算法。通过动态规划算法,于是我们有递推式,βi,j=βi+1,jpi,j+βi,j+1pi,jβ_{i,j} = β_{i+1,j}p_{i,j} + β_{i,j+1}p_{i,j}βi,j=βi+1,jpi,j+βi,j+1pi,j

  当我们可以算 αi,jα_{i,j}αi,jβi,jβ_{i,j}βi,j 之后,我们就可以计算出,所有包含p4,1(a)p_{4,1}(a)p4,1(a)的分数总和。如图示,P(Y^∣X)P(\hat{Y}|X)P(Y^X) 的计算方式可以改写为,所有从起始位置到 (4,1) 的候选对齐路径的分数和 α4,1α_{4,1}α4,1 乘上 p4,1(a)p_{4,1}(a)p4,1(a)后,再乘上所有从位置 (4,2) 到终点的候选对齐路径的分数和 β4,2β_{4,2}β4,2。这样我们把它再除以p4,1p_{4,1}p4,1,就消掉了p4,1p_{4,1}p4,1。这样 P(Y^∣X)P(\hat{Y}|X)P(Y^X) 对某个箭头概率 pi,jp_{i,j}pi,j 的偏微分就可以改写为 αi,jβi,j+1α_{i,j}β_{i,j+1}αi,jβi,j+1。带入最终的式子后,就能计算全部候选对齐的得分,对模型参数的梯度。然后反向传播更新模型参数进行训练。

  训练好模型之后,我们要进行推断,即遍历所有可能的候选YYY,来使得模型输出的概率P(Y∣X)P(Y|X)P(YX)最大,从而找到最优的解码YYY。但现实中遍历所有可能候选YYY不大容易。我们只能退一步求其次,通过贪心近似估计的方法。我们不把所有的候选对齐分数加起来,而是比每一个YYY中,分数最高的那个对齐方式。概率最高的对齐方式叫作h∗h^{*}h。我们要探究h∗h_{*}h它背后的Y∗Y^{*}Y是什么。

  实际中要怎么找一个概率最高的对齐方式呢?RNN-T每一个时间步都会跑出一个概率分布。我们把每个概率分布中,概率最大的那个token取出来,就是h∗h^{*}h的一个近似。由于取当前概率最大的未能让整个路径最大的。如果我们想要得到更好的近似,就用beam search,加大K。在精度和计算效率上进行折中和平衡。

  比较一下这三个模型。在解码部分,LASRNN-T会考虑前面的时序对当前时序的影响。而CTC没有考虑之前的时间步,已经生成出来的token。在对齐部分,因为中间的注意力层,LAS不用显示地考虑对齐。由于注意力一次要看全部,这也导致它不能在线学习。而CTCRNN-T没有注意力层,RNN一步一步地对输入解码,让它可以在线学习。但缺点是需要把输入和输出进行对齐。而且针对需要对齐的训练,会比较麻烦。

Language Modeling

  Language Modeling(LM)用于估测一段token sequence出现的机率。比如在HMMY∗=arg⁡max⁡YP(X∣Y)P(Y)Y^{*}=\arg \max _{Y} P(X | Y) P(Y)Y=argmaxYP(XY)P(Y)中的P(Y)P(Y)P(Y)就是LM。而LAS虽然是对条件概率P(X∣Y)P(X|Y)P(XY)建模,看起来不需要P(Y)P(Y)P(Y),但我们实际上很容易得到P(Y)P(Y)P(Y)的分布。我们让P(Y)P(Y)P(Y)去乘上P(Y∣X)P(Y|X)P(YX)来像HMM一样解码,能让表现变得更好。而且,计算条件概率我们只需要成对的资料,会比计算联合概率容易得多。

N-gram语言模型

  某一个 token sequence y1,y2,⋯,yny_{1}, y_{2}, \cdots , y_{n}y1,y2,,yn 可能在训练数据中出现的概率为0,但是我们并不能说这个句子在现实生活中出现的机率是0。N-gram语言模型将其拆分成比较小的窗口的概率连乘:P(y1,y2,⋯,yn)=P(y1∣BOS)P(y2∣y1)⋯P(yn∣yn−1)P(y_{1},y_{2},\cdots,y_{n})=P(y_{1}|BOS)P(y_{2}|y_{1})\cdots P(y_{n}|y_{n-1})P(y1,y2,,yn)=P(y1BOS)P(y2y1)P(ynyn1)。但是这种方式也会存在一些问题,就是当原始训练数据中有某个词汇yky_{k}yk后面接某个特定的词汇yk+1y_{k+1}yk+1时,其概率为0,如果连乘起来,整个序列出现的概率也就会0。这是因为数据稀疏导致的。此时可以采用 language model smoothing 的方法,赋予其一个较低的值。

  在深度学习之前,用的是一种从推荐系统中来的 Continuous LM。通过对矩阵分解的方式来解决上述问题,概率为0的问题。通过这种方式,它就会自动把0补成学到的参数。矩阵分解参考:经典机器学习系列之【个性化推荐之协同过滤】。

  L=∑(i,j)(vi⋅hj−nij)2L=\sum_{(i, j)}\left(v^{i} \cdot h^{j}-n_{i j}\right)^{2}L=(i,j)(vihjnij)2也可以采用Deep Learning的方法来做。hjh^{j}hj 作为输入,viv^{i}vi作为参数,nijn_{i j}nij作为标签。

NN-based LM

  NN-based LM 最早是想要取代 N-gram 的语言模型。它训练目标是通过输入前面的词,来预测后面的词出现的概率。

  有了NN-based LM 就自然会进入 RNN-based LM。它可以解决输入序列较长的问题。

  RNN有各式各样的变形。曾经人们的想法是,把 RNN 尽可能地做复杂,看能不能做出更强的语言模型。甚至还有人用 Nerual Turning Machine 改一改来做语言模型。近几年也有研究表明,LSTM加上合适的优化器和正则项就可以表现得很好。也不见得需要用非常神妙的奇技淫巧。

  之后就是拿这些语言模型与LAS结合,也有很多种方法:

参考

【1】李宏毅-基于深度学习的人类自然语言处理
【2】https://zhuanlan.zhihu.com/p/124327822

深度学习系列(二)【人类语言处理--语音辨识】相关推荐

  1. 点云深度学习系列博客(二): 点云配准网络PCRNet

    目录 一. 简介 二. 基础结构 三. 项目代码 四. 实验结果 总结 Reference 今天的点云深度学习系列博客为大家介绍一个用于点云配准的深度网络:PCRNet [1].凡是对点云相关应用有些 ...

  2. 深度学习系列:深度学习在腾讯的平台化和应用实践

    深度学习系列:深度学习在腾讯的平台化和应用实践(一) 莫扎特 2015-01-04 6:05:13 大数据技术 评论(0) 深度学习是近年机器学习领域的重大突破,有着广泛的应用前景.随着Google公 ...

  3. 【深度学习系列】——神经网络的可视化解释

    这是深度学习系列的第三篇文章,欢迎关注原创公众号 [计算机视觉联盟],第一时间阅读我的原创!回复 [西瓜书手推笔记] 还可获取我的机器学习纯手推笔记! 深度学习系列 [深度学习系列]--深度学习简介 ...

  4. R语言︱H2o深度学习的一些R语言实践——H2o包

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- R语言H2o包的几个应用案例 笔者寄语:受启发 ...

  5. 辣鸡准备稍微碰一下深度学习系列(1/21)---上

    Hello Tensorflow(2.3.0)集ctrlCV之大成 -- MNIST 手写数字检测上 前BB MNIST数据集 一.是啥玩意? 二.怎么得到? 第一种:找大腿(keras) 第二种:伸 ...

  6. 图机器学习(GML)图神经网络(GNN)原理和代码实现(前置学习系列二)

    图机器学习(GML)&图神经网络(GNN)原理和代码实现(PGL)[前置学习系列二] 上一个项目对图相关基础知识进行了详细讲述,下面进图GML networkx :NetworkX 是一个 P ...

  7. 机器学习与深度学习系列连载(NTU-Machine Learning, cs229, cs231n, cs224n, cs294):欢迎进入机器学习的世界

    欢迎进入机器学习的世界 本教程是根据台湾大学李弘毅老师的课程机器学习课程,斯坦福大学CS229.CS231N.CS224N.CS20i.伦敦大学学院 ([UCL-Course])(http://www ...

  8. A.图机器学习(GML)图神经网络(GNN)原理和代码实现(前置学习系列二)

    图学习图神经网络算法专栏简介:主要实现图游走模型(DeepWalk.node2vec):图神经网络算法(GCN.GAT.GraphSage),部分进阶 GNN 模型(UniMP标签传播.ERNIESa ...

  9. 腾讯深度学习系列——深度学习及并行化实现概述

    深度学习及并行化实现概述 摘要: 深度学习可以完成需要高度抽象特征的人工智能任务,如语音识别.图像识别和检索.自然语言理解等.深层模型是包含多个隐藏层的人工神经网络,多层非线性结构使其具备强大的特征表 ...

  10. 用MXnet实战深度学习之二:Neural art

    用MXnet实战深度学习之二:Neural art - 推酷 题注:本来这是第三集的内容,但是 Eric Xie 勤劳又机智的修复了mxnet和cuDNN的协作问题,我就把这篇当作一个卷积网络Conv ...

最新文章

  1. 「天才少年」稚晖君调戏机械臂!加上AI视觉,2小时学会抓螺母【文末送5本书】...
  2. linux postgresql默认安装目录,PostgreSQL for Linux 安装方式
  3. uvm 形式验证_UVM基础
  4. asp.net mvc post 后台model_搭建restful api后台
  5. 攻击者可提前检测到 Linux 内核的补丁并开发 exploit
  6. 从Ruby中删除数组中的重复元素
  7. 由sqlite在手机上的存储位置,引发的onCreate在哪里执行的小结
  8. java彩票开奖程序_用java 实现彩票摇奖,猜拳程序
  9. linux fastboot 工具,fastboot工具(FastbootCommander)
  10. OSChina 周六乱弹 ——程序员想让对象一辈子跟你的秘籍
  11. Vue.js快速原型开发问题汇总
  12. 密码学技术背后的计算困难性理论
  13. Android打字机动画,Android 打字机效果
  14. 使用PDFLib生成PDF文档(C语言版)
  15. linux越狱amd卡代码,为Linux内核贡献27.5万行代码中:AMD意外泄漏下一代APU信息
  16. 1560_AURIX_TC275_NMI Trap以及PMC
  17. 以太坊学习路线——(一)私有链搭建与基本操作
  18. SM 2256K AB 无缓存量产工具
  19. 蓝桥杯模拟题.花园灌溉(bfs)
  20. 安装程序配置服务器失败。参考服务器错误日志和C:\WINDOWS\sqlstp.log

热门文章

  1. 第一周周二一天工作总结和周三工作计划——PM(李忠)
  2. C++中如何使类不能继承
  3. linux和emwin的区别,emWin“自带软件GUIBuilder的使用”
  4. C++网络编程实例(初识多线程)
  5. 游戏开发之C++面向对象模型(C++类中成员变量和成员函数的存储原理及this指针)(C++基础)
  6. HCIE Security 全套笔记整理
  7. 关于MPLS静态 LSP建立的问题——针对上题的另一种解法
  8. Find命令使用详解及实例分析
  9. 小程序swiper效果高宽设置(微信小程序交流群:604788754)
  10. 关于easyui遇到的一些问题