CTC的理解

CTC技术近些年搭着End2End的顺风火了起来,查了一下原文,竟然是出在2006 Pittsburgh “International Conference on Machine Learning”的会议文章。Paper很容易找,搜索一下,能找到很多可用链接。

还是郑重地给出这篇文章的名字:

Connectionist Temporal Classification: Labelling Unsegmented
Sequence Data with Recurrent Neural Networks

要想理解这篇文章,要解决几个问题:

1. 如何实现了end2end?

2. 损失函数有什么特别?

3. 前后向算法在这个算法中的作用是什么?

其实理解这篇文章之后,这三个问题的本质是一样。

第一个问题:CTC如何实现了end2end?

在ASR领域,像DNN,LSTM这样的深度模型,输出的CD-phone的state。要做后面的文字的输出,需要加入字典(Lex)、语言模型(LM),与声学模型(AM)构成解码图后才可以。CTC越过字典与语言模型,直接输出phone或者字母(英文)、字(中文),虽然在性能上达不到其他的非e2e的模型的识别率,但这肯定是未来的大趋势,毕竟技术的发展应该是越来越简单,越来越直接。而且在实现的工程上,CTC在做识别时,也会结合LM,效果会更好。

与传统的声学模型训练相比,采用CTC作为损失函数的声学模型训练,是一种完全端到端的声学模型训练,不需要预先对数据做对齐,只需要一个输入序列和一个输出序列即可以训练。这样就不需要对数据对齐和一一标注,并且CTC直接输出序列预测的概率,不需要外部的后处理。

对于一个200帧的音频数据,假设真实的输出是7。经过神经网络后(可以dnn,rnn,lstm等),出来的序列还是200。比如说“chengyu”,将chengyu扩展到200的长度,路径有许多种。扩展的原则是:将一个字符扩展成连续多个,所有字符的长度总和为200,所有以下这几种都是合理的:

ccccc…hhhh…eeeeeee…ngyu

chengyyyyyyyyyy….uuuuuuuu

这时有一个问题,那就是像hello中有两个l,怎样处理?方法是在两个l之间插入一个无意义的\epsilon,例如hh…e…lllll\epsilonlll…o..。

RNN模型本质是对 P(z|x) 建模,其中s表示输入序列,o表示输出序列,z表示最终的label,o和l存在多对一的映射关系,即:P(z│x)=P(o|x),其中o是所有映射到z的输出序列。因此,只需要穷举出所有的o,累加一起即可得到P(z│x),从而使得RNN模型对最终的label进行建模。

第二个问题:CTC的损失函数有什么特别?

不同于用于分类的cross entropy准则和回归的MSE准则,CTC的损失函数巧妙在设计为-logP(z│x)。使P(z│x)的最大,等价于损失最小,通过求log的负值,转化成一个求最小值问题。

3. 前后算法在这个算法中的作用是什么?

要想计算出每一条可能路径的得分再将所有这些得分加起来,用蛮力方式显然是不可能,巧妙地运用语音识别中的前后向算法,即baum-welch算法可以大大减少计算量,用动态规划的算法思想有效在提高了效率。