CTC算法详解
最近在学习语音识别,就看了一下这个算法,下面简单总结一下
什么是端到端?
对于传统的语音识别,通常会分为3个部分:语音模型,词典,语言模型。语音模型和语言模型都是分开进行训练的,因此这两个模型优化的损失函数不是相同的。而整个语音识别训练的目标(WER:word error rate)与这两个模型的损失函数不是一致的。
对于端到端的语音识别,模型的输入就为语音特征(输入端),而输出为识别出的文本(输出端),整个模型就只有一个神经网络的模型,而模型的损失采用的CTC Loss。这样模型就只用以一个损失函数作为训练的优化目标,不用再去优化一些无用的目标了。
CTC算法概念
CTC算法全称叫:Connectionist temporal classification。从字面上理解它是用来解决时序类数据的分类问题。
传统的语音识别的声学模型训练,对于每一帧的数据,需要知道对应的label才能进行有效的训练,在训练数据之前需要做语音对齐的预处理。而语音对齐的过程本身就需要进行反复多次的迭代,来确保对齐更准确,这本身就是一个比较耗时的工作。
图1 “你好”发音的波形示意图
如图1所示,是“你好”这句话的声音的波形示意图, 每个红色的框代表一帧数据,传统的方法需要知道每一帧的数据是对应哪个发音音素。比如第1,2,3,4帧对应n的发音,第5,6,7帧对应i的音素,第8,9帧对应h的音素,第10,11帧对应a的音素,第12帧对应o的音素。(这里暂且将每个字母作为一个发音音素)
与传统的声学模型训练相比,采用CTC作为损失函数的声学模型训练,是一种完全端到端的声学模型训练,不需要预先对数据做对齐,只需要一个输入序列和一个输出序列即可以训练。这样就不需要对数据对齐和一一标注,并且CTC直接输出序列预测的概率,不需要外部的后处理。
既然CTC的方法是关心一个输入序列到一个输出序列的结果,那么它只会关心预测输出的序列是否和真实的序列是否接近(相同),而不会关心预测输出序列中每个结果在时间点上是否和输入的序列正好对齐。
图2 ctc预测结果示意图
CTC引入了blank(该帧没有预测值),每个预测的分类对应的一整段语音中的一个spike(尖峰),其他不是尖峰的位置认为是blank。对于一段语音,CTC最后的输出是spike(尖峰)的序列,并不关心每一个音素持续了多长时间。
如图2所示,拿前面的nihao的发音为例,进过CTC预测的序列结果在时间上可能会稍微延迟于真实发音对应的时间点,其他时间点都会被标记会blank。
这种神经网络+CTC的结构除了可以应用到语音识别的声学模型训练上以外,也可以用到任何一个输入序列到一个输出序列的训练上(要求:输入序列的长度大于输出序列)。
比如,OCR识别也可以采用RNN+CTC的模型来做,将包含文字的图片每一列的数据作为一个序列输入给RNN+CTC模型,输出是对应的汉字,因为要好多列才组成一个汉字,所以输入的序列的长度远大于输出序列的长度。而且这种实现方式的OCR识别,也不需要事先准确的检测到文字的位置,只要这个序列中包含这些文字就好了。
CTC的对齐
在语音识别中,我们的数据集是音频文件和其对应的文本,让模型更有效地收敛。不幸的是,由于人的语速的不同,或者字符间距离的不同,音频文件和文本很难再单词的单位上对齐。
传统语音识别模型中,数据的预处理操作需要人工将标签文本与语音进行严格对齐。很费时间,而且预测的结果不是整个序列的输出结果,还需人工操作。CTC是一种让网络自动学会对齐的好方法,十分适合语音识别和书写识别。
为了描述地更形象一些,我们可以把输入序列(音频)映射为X=[x1,x2,…,xT],其相应的输出序列(转录)即为Y=[y1,y2,…,yU]。这之后,将字符与音素对齐的操作就相当于在X和Y之间建立一个准确的映射。
给定一个X,CTC能基于所有可能是准确映射的Y给出输出分布。根据这个分布,我们可以推理最可能的输出,或计算分布内各字符的可能性概率。
CTC算法的输入X和输出Y的对齐方式有下列属性:
1、输入与输出的对齐方式是单调的,即如果输入前进到下一时间片,输出会保持不变或者也会移动到下一个时间片段 (本质上就指的是“多对一”)
2、输入与输出是多对一的关系
3、输出的长度不能大于输入
RNN+CTC模型的训练
导入
参考
[1]:https://blog.csdn.net/Left_Think/article/details/75577512
[2]: https://blog.csdn.net/luodongri/article/details/80100297
[3]: https://www.jianshu.com/p/a968334f585d
[4]: https://blog.csdn.net/laolu1573/article/details/78791992