本文介绍ctc算法1。之前有了解过大致细节,发现还是很容易忘记。还是需要自己啃一下论文。以下是论文笔记。有一些疑问,待看了源码再做补充。
介绍
ctc用在语音识别,取得不错的效果。最近学术界以及我自己在ocr的实践也证明了其可行性。
语音识别
对于传统的语音识别来说,一般需要先对语音进行分帧处理。每帧10ms。一般需要使用”强制对齐“的方式,使得语音和标签一一对应,然后再训练这个预测关系。
这样预测是前后文独立的,这个对齐结果对最后结果也会有较大影响。
ocr
传统的文字识别一般分为检测,分割,识别三个步骤。先检测到文字位置,再将每个文字切割出来,放到svm等分类器进行分类。但分割本身是非常麻烦的问题。对于手写字有黏连的情况,或者验证码这种故意扭曲的图片,很难有很好的结果。
基于ctc的文字识别就是直接把整张图片和对应的文本标签扔进来,由算法学习里面的对齐关系。并按照概率最大,输出对应的标签。
下文主要以ctc在语音识别上的应用进行举例。改天再专门介绍ctc在ocr上的应用实例。
工作原理
以上图片来自这篇一篇很好的博客2。
我们先用上面这张图来说明ctc的基本工作原理。第一行是输入的波形。第二行是分帧预测结果。第三行是对结果进行合并。合并规则如下:
- 合并相同的标签
- 去除blank符号
blank符号用于表示一种犹豫不定的状态。后文用ϵ 表示。
那么大家可能心里就会问,多了一个ϵ有啥特殊的吗?跟分帧预测有什么区别吗?
我们先来看一张图。在这张图中,可以看到ctc预测结果和分帧有明显的不同。
上图第一行是波形,第二行是分帧预测结果,第三行是ctc的结果。(岂不是说,使用ctc很难准确获取每个音素的起始结束时间?待确定todo)
从上图可以看到对于分帧预测来说,需要在一个音素持续的时间内,持续地保持该音素是最大的概率。如果不是,则会导致最后结果不对。(当然,可以通过语言模型进行修正)
而最后一行的ctc预测则完全不一样。在整个预测过程大部分时间都是blank状态,在少数位置上输出对应的音素。与rnn进行结合,有前后文信息,进一步提高预测的准确性。
预测
ctc其实是一种损失函数。在预测的时候,可以使用跟分帧完全一样的方式进行处理。
符号
为了方便表达,我们先引入一些符号。
- L: 原来的标签集合
- L′: 原本的标签 + blank
- ytk: 第t帧是k标签的观测概率
- π: 路径
- B: 用来表示多对一映射。比如说: B(a−ab−)=B(−aa—abb)=aab
那么:
p(l∣x)=∑π∈B−1(l)p(π∣x)(1)上式的意思是,对于给定输入x, 输出l的概率是:所有可能通过B映射而获得l的路径π的概率和。
一听到路径概率和,有没有一种冲动:用vertebi算法 :)。额,这里用不了。与hmm和crf不同,这里没有转移概率。
这里比较复杂的是有个映射。通常使用prefix search(待细化)来搞。但比较耗时。也有按照高于一定阈值的blank来划分成多个段来减少耗时。
常用的方法就是直接取每个位置最大概率的标签。
那么现在剩下的问题就是训练了。
训练
前向后向
训练使用前向后向算法。(可以先复习一下hmm的前向后向训练,对于理解ctc有帮助。)
αt(s)表示在第t帧,前面的预测序列是l1:s的概率。
at(s)=∑π∈NT,B(π1:t)=l1:st∏t′=1yt′πt′后面我们会看到,αt(s)可以表示成αt−1(s)和αt−1(s−1). 从而大大节约计算量。
在训练的时候会将标签从l改成l′。主要是在每个标签之间插入blank。使得总长度是2∣l∣+1.
如下图所示,横向表示时间帧。纵向表示标签序列(白色是blank,黑色是正常标签)。cat的概率是所有可能路径之和。
对于一个序列,可以从blank开始,也可以用正确的标签开始,所以有以下初始条件:
- α1(1)=y1ϵ
- α1(2)=y1l1
- α1(s)=0,∀s>2
其中 ˉαt(s)=αt−1(s)+αt−1(s−1)
解释一下为什么这里需要分这两种情况考虑。
比如对于abb这样的序列,对应的l′是: -a-b-b-
- 第一种情况
- 在预测到ϵ的时候,必须保证前面一个是ϵ或者前面已经是正确的标签了
- 预测第二个b的时候,必须保证前面一个是ϵ或者b
- 第二种情况
- 在预测第一个b时,前面一个是a,b,ϵ都是可以的。
同理或者后向 βst
最大似然训练
p(l∣x)=∣l′∣∑s=1αt(s)βt(s)ytl′s对于ytk,只需要考虑标签k就可以了。
因为会有重复,所以我们需要几下标签k出现的位置(todo:论文这里没有说清楚这个k指的是当前这个k,还是所有跟k相同标签的位置。回头看下mxnet ctc代码再做补充):
lab(l,k)={s:l′s=k}与hmm的区别
hmm的训练参考之前的文章. 待补充
mxnet ctc 实现
todo
参考文献: