语音识别的技术原理是什么?

语音识别的技术原理是什么?

大家说了很多传统Hybrid语音识别的原理,我来输出一下端到端语音识别的原理,力争浅显易懂,让做NLP和CV的人也能明白端到端语音识别模型。其中大部分感悟为在6万5千小时数据上(https://arxiv.org/pdf/2005.14327.pdf )进行实验得到的经验。

我们先明确端到端语音识别的输入和输出。

输入是 Mel谱(MFCC特征),可以理解为将语音信号经过采样,大约每10毫秒可以得到一个向量,向量的维度一般是80,如果语音有10秒,整个mel input的就是一个 80 * 1000 的矩阵。这和NLP中的word embedding输入十分类似,但是NLP的文本长度大部分任务会比语音短一些。

输出是一串Subword,和NLP类似,目前Subword是最好的端到端系统的输出单位,一般用sentence piece等工具将文本进行切分。

-------------------------模型分割线-------------------------

端到端模型粗略可以分为label-sync和frame-sync,label-sync可以理解为NLP之中传统的beam search方案,给定音频输入,解码器每个time step解码一个词语,beam search时候会保存beam size个结果,直到解码出<EOS> 符号。典型的label-sync的模型是经典的Seq2Seq模型

Seq2Seq:

随着基于Transformer的模型的兴起,当下最流行的模型结构是Transformer,和传统NLP中Transformer不同的是,开始时候如果使用CNN对语音输入进行处理,会提升语音识别的最终性能。

至于其他都和Transformer S2S没有本质区别。然而所有的Seq2Seq ASR模型都有两个缺点:其一是很难处理流式的输入(用户边说边识别),其二是输出的文字结果有可能非常短,需要一些coverage的操作才可以避免这个问题。

在这里打一个小广告,我们开源的StreamingTransformer系统,以及其背后的Offline Transformer结构目前都是英文语音识别数据集Librispeech Seq2Seq同参数的比较下最好的系统,尤其是这种流式的Transformer处理方式,应该比其他的流式模型在Librispeech数据集都好很多。

说完label-sync,转到另一个方案。frame-sync十分有语音的特色,给每一个frame都打一个标签,标签可以为空,如下图所示,五帧每个对应一个word,</>代表空

然而,一个明显的问题浮现出来了,如何自动对齐frame和label,这就引出了语音里面最经典的模型CTC以及他的衍生品Transducer。CTC和Transducer说到底是一个loss function,它十分明确的定义了一个优化目标,它并不是一个网络结构,而是利用RNN或者Transformer对每个frame输出之后,定义了一个loss,让两个不等长序列X和Y可以一个frame和一个word对应上(通过给word集合加入空,以及CTC中相邻两个frame可以是一个词)

CTC

CTC有非常经典的英文blog,https://distill.pub/2017/ctc/

我简单总结一下,首先encoder会在每个frame输出一个词的distribution,且frame之间没有依赖,如果词典5000(含空),那么输出就是5000,之后CTC会给所有合法路径算概率,例如上图的hello </></> world</>有5帧,那么其他的合法路径还有hello world </></></>,hello </></></> world 等等。之后会计算每个路径的概率(概率比较好算,就是step概率的乘积),CTC把所有这些合法路径加起来,并进行优化

Transducer

Transducer可以理解为CTC的衍生品,因为CTC在建模的时候第i个词只与X有关,没有考虑之前输出的词语 ,所以会在语言模型上有些问题,在实际应用中往往需要搭配语言模型使用。所以,Transducer在建模的时候改变了这一个问题,它建模的是 ,考虑了额外的语言模型部分,模型图如下所示

Encoder会给每一个frame一个hidden state,之后还有个preditor network,它会根据已经输出的序列给出下一个词的hidden state,然后两个一拼,得到了该时刻词语分布的概率。之后仍旧是动态规划,如果是空就横着走,否则竖着走,算出所有合法路径的概率,优化

RNN-T由于是frame sync模型,且克服了CTC没有建模词语互相的关系,是非常适合工业界的流式模型,也是目前Google device上上线的流式模型,只是训练时候显存消耗非常大,不太好训练。

最后一些个人想说的:

1 目前,seq2seq仍然是给定完整音频,之后进行识别,准确率最佳方案。前提是结合一些防止生成太短的技术

2 流式的情况下,transducer或者ctc加lm可以根据资源选用,如果卡少只能ctc

3 seq2seq流模型比较复杂,虽然性能也不错但经常换了数据集会出问题

4 Transformer比RNN更适合建模长一些的语音序列,短的差不多,而且RNN跑得快。