a unit of sound 是声音的最基本单位,每个词语token的声音由多个 phoneme 组成
smallest unot of a writing system 每个单词书写最基本的单位,简单来说:
英文的grapheme可以认为是词缀, 由 [26个英文字母 + 空格 + 标点符号]组成
中文的grapheme是汉字
英文可以用单词作为语音识别的最基本单位,但包括中文在内的很多语言无法使用word作为最基本的单位(word数量太过于庞大,word之间难于分隔等)
the smallest meaningful unit 类似英文单词中词缀
用byte的序列来表示计算机中的每个字符(比如使用utf-8对字符编码),用用byte作为语音识别的基本单位可以让是识别系统将不同的语言统一处理,和语言本身无关,英文上叫 The system can be language independent
获取语音特征的方法从难到易依次是:
语音识别的结构一般可以分为两种,一种是直接输出 word embedding(feature base);一种将语音识别模型和和其他模型相组合的end2end结构,如:speech recognition + 翻译模型、speech recognition + 分类模型、speech recognition + Slot filling模型,这里主要分析这一种类型
主流的语音模型总体上可以分为seq2seq结构和HMM结构,而seq2seq结构有LAS、CTC、RNN-T、Neural Transducer、MoChA等
LAS网络是一个 seq2seq的结构(encoder-decoder),其中:
注意:Attend中的 Attention 和 encoder 中的 Self-Attention 没有关系:
因为语音识别的数据量很大,因此在LAS的 encoder 内往往需要对数据进行下采样的操作,从而降低数据维度,在RNN中,一般使用如下两种方式进行下采样:
对于TCNN,可以使用上左图的方式进行下采样操作:
一般的TCNN网络会读取整个范围内所有序列的数据,但是为了减少数据量,我们可以只输入序列的开始和结束的 embedding
对于 Self-Attention,为了减少数据量,我们可以只对一定范围内的序列数据进行 attention,如上右图所示,对于输入 x 3 x_3 x3,只对其周围的 x 2 x_2 x2 和 x 4 x_4 x4 进行 Attention
下边使用一个例子来说明 Beam search 的过程
假如 token 的个数为2,分别为A和B,同时序列长度为3,我们可以使用下图来展示语音识别的整个过程:
对于第一个token,识别为A的概率是0.6,B的概率是0.4,我们将三个token识别出来的所有可能展示出来就如下图所示;如果每次我们都选择概率最大的token,我们会得到红色路径代表的结果,但是如果我们第一次没有选择概率最大的A,而是选择了B,那么我们会得到绿线代表的结果,我们发现绿线的结果反而更好;因此我们可以同时选择多条路线同时预测,最后选择效果最好的结果返回,其实这就是 beam search的思想,其中 beam size 就代表同时进行的路线数量
LAS中的Attention可以有两种形式:
一种是上文提到的,将decoder的当前时刻隐含层数据 z t z^t zt在encoder的输出 h i h^i hi上做Attention,并将此生成的语义变量 c t c^t ct作为下一时刻decoder(RNN)的输入;
一种是将decoder的当前时刻隐含层 z t z^t zt和在encoder的输出上做Attention,并将此生成的语义变量和当前时刻的隐含层 z t z^t zt作为当前时刻decoder(RNN)的输入放入RNN中
这两种注意力的区别在,注意力得到的结果是下一个时间使用还是当前时间使用。第一篇拿Seq2Seq做语音识别的论文,用的是二者的合体版本。
Location-aware attention 在计算每个 h i h^i hi的权重时, 不仅考虑 z i z^i zi和 h i h^i hi,同时将上一时刻得到的部分权重;之所以是部分权重是因为只考虑上一时刻 h i h^i hi邻域内的权重,具体实现方式可以参考下图
我们用 one-hot 编码来表示每个token, 同时计算模型输出和正确token one-hot编码的交叉熵,使模型输出的结果逐步接近正确token的one-hot编码,如下图所示:
但是,有一点需要注意,在decoder端,我们并不会将上一时刻的输出作为当前时刻的输入,而是将上一时刻正确的token作为当前时刻输入,
如下图所示,当我们要预测cat中的a时,我们并关心上一时刻(第一个token)得到什么结果,而是直接将上一时刻的正确结果 c 作为当前时刻decoder的输入 这个训练方式叫做 teacher forcing
由于LAS是seq2seq结构,而seq2seq结构需要将整个输入序列编码成一个语义向量,要得到整个输入序列之后才能开始输出第一个token,因此无法实现在线学习,或者说是在线语音识别
和LAS相比,CTC能够实现实时识别的功能,CTC模型的基本结构如下图所示:
首先,模型先通过一个encoder结构将输入的token转化为一个高维隐层嵌入,然后对于每一个token的输出使用一个分类器(全连接网络)进行分类,最终的到每个token对应的预测结果;虽然CTC网络没有Attention机制,但encoder往往使用LSTM网络,从而每个token也能够得到上下文的信息;CTC会遇到如下两个问题:因为 CTC模型的输入是音位,因此多个相邻的token可能出现重复或者某个token的输出为空的情况:
同样因为 CTC模型的输入是音位,因此我们无法准确的到每个序列对应的标签,以下边的例子为例,同样对于好棒这个语音的音位序列,他的标签可以是下边标签的任意一个,问题是我们要用哪一个做为这个语音序列的标签呢?CTC其实是用到了下边的所有标签,原理这里暂且不做讲解
在认识 RNN-T之前,首先要认识一下RNA(Recurrent Neural Aligner)网络;前边我们了解了CTC网络,RNA网络就是将CTC中encoder后的多个分类器换成了一个RNN网络,使网络能够参考序列上下文信息
RNN-T 网络在RNA网络的基础上使每个输入token可以连续输出多个结果,当每个token输出符号 ∅ ∅ ∅ 时,RNN网络再开始接受下一个 token,具体过程如下图所示:
其实,在RNN-T中,RNN网络的的输出并不是简单的将上一时刻的输出作为当然时刻的一个输入,而是将上一时刻的输出放入一个额外的RNN中,然后将额外RNN的输出作为当前时刻的一个输入;这个额外的RNN可以认为是一个语言模型,可以单独在语料库上进行训练,因为在一般的语料库上并不包含 ∅ ∅ ∅ 符号,因此这个额外的RNN网络在训练时会忽略符号 ∅ ∅ ∅
和RNA、CTC、RNN-T不同,Neural Transducer 每次接受多个输入,并对这些输入做Attention,然后得到多个输出的语音识别模型;
和 LAS 对整个输入序列做 Attenton不同,Neural Transducer只对窗口内的多个输入做attention
Neural Transducer 模型结构如下图所示:
Neural Transducer 中 Attention 的实现方式在网上没有找到明确的说明,这里以后做补充
MoCha 是一个窗口可变的语音识别模型,和 Neural Transducer 最大的区别是MoCha每次得到的窗口大小可以动态变化,每次的窗口大小是模型学习的一个参数;同时因为MoCha的窗口动态可变,因此MoCha的decoder端每次只输出一个token,MoCha模型结构如下图所示:
模型 | Attention | 输入 | 输出 | 编码器 | 解码器 | 是否支持实时识别 |
---|---|---|---|---|---|---|
LAS | 对整个序列 Attention | 每次输入整个序列 | 每次输出一个Token | CNN、RNN、Self-Attention等 | LSTM | 否 |
CTC | 无 | 单个Token | 每个分类器输出一个Token | 单向LSTM | 每个token对应一个独立的分类器 | 是 |
RNA | 无 | 单个Token | 单个Token | 单向LSTM | LSTM | 是 |
RNN-T | 无 | 单个token | 多个Token | 单向LSTM | 两个LSTM | 是 |
Neural Transducer | 对同一窗口内的token做Attention | 多个Token(窗口大小固定) | 多个token | 单向LSTM | 两个LSTM | 是 |
MoCha | 对同一窗口内的token做Attention | 多个Token(窗口大小动态) | 单向LSTM | 一个窗口输出一个Token | 两个LSTM | 是 |
下一篇文章将介绍 HMM+GMM 语音识别模型的基本原理->#透彻理解# GMM+HMM 语音识别模型过程