CTC——下雨天和RNN更配哦

本文收录在无痛的机器学习第二季目录

前面我们一直在讲CNN的事情,从今天开始,我们要尝试扩展新方向了!这个新方向就是RNN。介绍RNN的时候,我的内心还是充满紧张的。因为相对而言RNN的理解还是会比CNN弱一些。但是万事开头难,然后中间难,最后结尾难。所以我们一起开车了。

RNN的结构我们放在后面介绍,我们先来看一下RNN和CNN相比的特点:对输入输出的维度不必限定。这一点和CNN很不相同。虽然不限定维度的输入输出带来了极大的灵活性,但是也带来了一些其他的问题。当然这些问题我们放在后面慢慢说。下面我们来关注一下CTC的背景。

这个问题就是对齐问题。比方说对于OCR,我们利用RNN进行识别,我们会得到一连串的输出结果,但是真实的结果可能比这一连串输出要少,所以我们需要做一个对齐的工作:哪些RNN输出对应着同一个真实结果?


关于这个问题,我们可以使用CTC解决。我们先来约定下各种变量的名字,不然一会儿会要晕掉的:

我们把RNN输出的内容就称为R,RNN会随着时间的推进不断记忆前面的信息从而后面的结果,我们在此定义RNN经过的时间长度为T,那么RNN输出结果中的一个维度就确定了。

RNN的另一个维度和输出的类别数量有关。在CNN的分类问题中,我们经常使用softmax层输出表示输入内容对所有类别的概率,这里我们同样用RNN输出这样的信息,我们定义类别的数量为C,那么现在我们就可以确定主角之一的三围,哦不是二围了:C*T。

这个二维的RNN输出要匹配的是真正的ground_truth,我们直接给出它的维度:1*L。它的长度为L,其中每一个时刻有一个类别。那么我们的目标就是把C*T和1*L这两个东西对上,并求出RNN输出结果的Loss和梯度。

说到这种形式的序列问题,我们很容易想起ML人民的老朋友:马尔科夫链。实际上在CTC横空出世前,很多人喜欢把两者匹配的问题转换成一个HMM(隐马尔科夫模型)的问题。CTC的套路实际上和HMM有点相近。

好了,下面我们首先来介绍CTC的一个核心思想:

CTC的核心思想

CTC的核心思想是什么?好吧我们这里很显然地知道T是大于等于L的(这个很显然吧),那么用脚想也会知道,RNN的结果里肯定存在着一些冗余信息,比方说在相邻的2个时刻,我们实际上预测了同一个类别,这是很容易发生的事情。那么我们就需要制定一个套路,来帮助我们去掉那些冗余信息。

套路第一步,就是定义一个额外的类别,这个类别叫做blank。我们可以想象在进行手写识别时,字与字之间会存在着一些空隙,语音识别时的字与字之间也会存在着一些间断。我们可以把其中的这些间断的状态定义为blank。为了让匹配的过程更加全面,我们可以在ground_truth的每一个输出类别的前后加上blank,以表示这些字之间存在着的某种间断。

当然了,你说我们还会遇到某些极端情况,那就是字与字之间没有blank,这时候硬塞一个blank也不是很合适啊。所以在一般情况下,字与字之间的blank是可有可无的。但是有一个情况除外,那就是重复的字。在中文中,这种看似有点卖萌的叠字实际上还是出镜率很高的。

比方说你在街上看到一只小狗,长得还挺萌的(我觉得泰迪还蛮萌),于是你气沉丹田,说了一个字——“狗~~”,这种间完全没有中断,于是大家除了觉得你有点神经病之外,只会觉得你说了一个字。但是你如果面如桃花般地说“狗狗~”,相信这两个字之间总会存在一个小小的空隙,让人们把你和上面那位气功大师分别开来。而拆成两个字的关键就是着中间有一个停顿。所以为了区分一段时间内的输出是一个状态还是两个状态,我们需要一个停顿,一个blank。

当然,关于blank的好处,官方文章写了好多。这里直接照抄实在没什么意思,大家去看文章就好。好了套路一结束了。

下面是套路二:现在我们要把C*T和1*(2L+1)对应起来了。但是这个时候它们的维度还是不一样,怎么办?下面我们就要开始变身了。首先我们确保重叠字中间有一个blank,这时候ground_truth的长度为L'。理论上这时候的L'还是小于等于T的。但是马上我们的ground_truth要变身了,我们要通过变身让ground_truth的长度最终等于T。变身的规则主要是复制。ground_truth下的每一个输出都可以从原本的1个输出变成多个输出,同时每一对输出之间都可以加入blank。

听上去有点复杂,我们来举个例子。假如我们说了一段话,这话有8个时刻,也就是说T=8,我们实际说出来的字是“无痛的机器学习”,有7个字,根据刚才的规则,我们需要扩充一个字让它的长度也等于8。我们用B表示blank。那么首先扩充的方法是加入blank:

B无痛的机器学习 无B痛的机器学习 无痛B的机器学习 无痛的B机器学习
无痛的机B器学习 无痛的机器B学习 无痛的机器学B习 无痛的机器学习B

其实真要把上面的复制念出来还是笑点满满的,除了加一个B,我们还可以复制本身存在的字:

无无痛的机器学习 无痛痛的机器学习 无痛的的机器学习 无痛的机机器学习
无痛的机器器学习 无痛的机器学学习 无痛的机器学习习

念完了这一组话,我TM脑子里就只剩一个人了——东北F4,你值得拥有:


好了,通过这种方法我们完成了对齐。既然已经对齐了,我们就来计算ground_truth扩充后所有可能结果的概率,并且把这些概率加起来,得到我们预测结果的总概率。对于每一个序列,由于对齐后序列中每一个输出的内容间相互独立,所以我们直接把softmax层的输出连乘起来就好了。最后就是一个乘加的工作,大家用意念去想一想就会明白。

到这里,CTC的核心思想也就差不多了。下面留给了我们一个艰巨的问题,刚才这个case比较简单,万一遇上复杂的情况,难道我们还要一个一个地把ground_truth扩展么?

看来我们要上点高科技了。

广告时间

更多精彩尽在《深度学习轻松学:核心算法与视觉实践》

编辑于 2017-11-22

文章被以下专栏收录