RCNN + CTC 文本识别原理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RCNN + CTC 文本识别原理相关的知识,希望对你有一定的参考价值。

参考技术A

对于 OCR 任务来说,目的是为了将图像中的文字识别出来,近几年的研究主要包含以下几个步骤:

目前研究主要集中在文字检测和文字识别两个任务,本文只介绍文字识别任务中的一种模型,即 CRNN+CTC Loss 方案;另外一种方案是基于 Attention 机制。主要区别在于(后续重点介绍 CTC):

CRNN 网络结构如图 2-1 所示,输入为经过文字检测的文本框(小图),输出为具体的文字内容 “state”,从下往上的结构依次为:卷积层、循环层和翻译层。

卷积层:使用深度 CNN 进行图像的局部特征提取。如图 2-2 所示,整个 CRNN 网络的层级以及参数设置。

注意: 卷积核的大小是 3x3,步长 s 和 padding 都为 1,则证明卷积层在不改变图像的尺寸大小情况下进行特征提取;池化层有四个,大小分别为 2x2、2x2、1x2、1x2,则对于图像的高度减半 16 倍,宽度减半 4 倍。然后再经过最后的 Conv 层,例如:图像的输入尺寸为 (channel, height, width) = (1, 32, 160),CNN 的输出尺寸为 (512,1,40)。

经过 CNN 层的特征图(512,1,40)是不能直接送给 LSTM 进行训练的,通过对特征图中的 40 作为特征向量的序列数,每列包含 512 维特征,构成了 40x512 大小的维度矩阵,输入到 LSTM 网络中。论文 [5] 中提到:

使用双向的 LSTM 进行时序特征的提取,通过上一步,输入到 LSTM 的特征大小为(40x512),每个 LSTM 的时间步为 40,每个时间点的特征维度为 512。LSTM 网络的目标:预测每个时间步的字符内容,即输出为所有字符的 softmax 概率分布,然后将这个后验概率矩阵传入 CTC 层。

总结为:

对于 LSTM,正常使用多分类的交叉熵进行训练,完成参数更新,则每一时间步的输出对应一个字符,也就意味着训练时候每张样本图片都需要标记出每个字符在图片中的位置。但是实际上是不可能实现的,所以 CTC 提出一种对不需要对齐的 Loss 计算方法,用于训练网络,被广泛应用于文本行识别和语音识别中。

对于输入 X 和 输出标签 Y 长度都不一致且变换的情况,CTC 提供解决方案为:对于一个给定的输入序列 X ,CTC 给出所有可能的输出分布 Y。根据这个分布,我们可以输出最可能的结果或者给出某个输出的概率。

RNN 进行时序分类时,不可避免出现冗余信息,如图 3-1 所示,5 个时间步分别被识别为 [a,a,a,b,b],然后将重复的字符合并为 “ab”,但是对于如 book 等字符,合并字符后变成了 bok ,显然不行,所以 CTC 使用 blank 机制解决这个问题。

定义一条路径 的输出概率为:

其中, 代表 时间步为 t 时刻的输出概率,使用连乘的方式得出整条路径的概率值。但是存在多条路径经过上一步的合并冗余机制得到相同的路径结果,如(“a-a-a-b-b”和“aa-aa-a-b-b-”通过合并序列之后都为“aaabb”),所以定义:

其中, 代表合并之后的路径,由所有合并之后的相同路径求和所得。常规解法是将所有的合法路径输出概率,然后进行求和,但是实际上路径组合数量非常大,无法逐条求和直接计算 。

借用概率图 HMM 的 “向前-向后” 算法计算:
训练的目的在于最大化概率 ,使用对数似然法定义损失函数为:

递推公式为:

对于递推公式的解释说明,可以看到 X 轴代表时间步,z 轴代表输出的字符串,输出标签为“ZOO”:

上图主要分为以下两种情况:

递推公式为,解释见前向:

得到了前向和后向概率,将其概率相乘再经过转化,就可以计算 的概率,公式如下:

对于 来说,可以表示为每个时间步输出 label 的概率之和,因为上面的公式都是在 这一点进行前向和后向概率的计算。

为计算每个时刻每个因素的梯度: 观察公式 7 中右端求各项,仅有 的项包含 ,其他项的偏导都为 0,不用考虑,于是有:

公式 8 中,分子第一项是因为 中包含为两个 乘积项(即 ),其他均为与 无关的常数。 中可能包含多个 字符,它们计算的梯度要进行累加,因此,最后的梯度计算结果为:

通过对对数似然进行求导,梯度计算如下:

其中, 通过前向计算可得,就是最后输出为 "-" 或者最后一个 的前向概率值: 。其中,由于某时刻某因素的前向和后向概率都已经求出,都为常数,故此梯度计算完成,通过优化算法进行参数调整即可。

预测就是找到概率值最大的路径,目前存在两种方案:一是 Greedy Search,二是 Beam Search。

构建CTC语音识别解码网络

技术分享

  本文介绍 kaldi-ctc 构建 CTC[1, 2, 3, 4] 语音识别加权有限状态机(WFST)解码网络的方式。

  示例相关资源 lifeiteng/codingmath/CTC-decoding-graph

  构建语言模型

  以 单句 “how are you are” 作为文本语料,训练 bi-gram(order=2)语言模型

技术分享

  生成 G.fst [data/lang_2/G.pdf],如下图

技术分享

  准备"发音" 词典

  不同单元 phone[1, 2] / character[3, 4],都可以抽象为“发音”词典的形式,以 phone 词典为例

技术分享

  其中 !SIL SIL 为额外添加,作为 OOV 的替换符号使用,亦可使用其他记号 e.g. UNK NSN 。

技术分享

  其中 --num-sil-states 1 --num-nonsil-states 1 用于构建单状态TransitionModel(HMM)。

  生成 L.fst [data/lang_2/L.pdf]

技术分享

  Optinal 的 SIL( SIL : / 2_1 )使得发音词典与语言模型 Composition 之后的搜索空间允许单词间停顿而不影响语言模型概率计算。

  构建HCLG

  像 DNN-HMM hybrid 系统一样构建HCLG[5]:

技术分享

  kaldi-ctc 可以方便构建CI[1] phone / CD[2] phone / character[3, 4] 的 CTC 系统,只需构建相应 CI-phone / CD-phone / character 的决策树和训练数据即可。

  HCLG [exp/mono_ctc_decoding_graph/HCLG.pdf] 网络:

技术分享

  修改HCLG 构建CTC解码网络

  修改 HCLG 的 input label(即 TransitionId)并插入 blank loop 构建CTC解码网络。

  arc.ilabel++, 添加 blank loop

技术分享

  最终 CTC 解码网络如下: [exp/mono_ctc_decoding_graph/CTC.pdf]

技术分享

  解码时从解码网络获得TransitionId转为对应的PdfId做为 RNN 输出层索引获得

  log_likelihood = log(RNN output[pdf_id]) - log(prior[pdf_id])

  尖峰现象

  以 CTC 准则训练的 RNN 模型输出概率有明显的尖峰现象[1]: [images/pink.png]

技术分享

 

  解码时跳过blank概率接近1的帧可以极大提升实时率。

以上是关于RCNN + CTC 文本识别原理的主要内容,如果未能解决你的问题,请参考以下文章

构建CTC语音识别解码网络

OCR文字识别—文本识别的算法

OCR文字识别—文本识别的算法

文字识别:CRNN

RCNN 目标识别基本原理

Tesseract 微调错误 - 计算 CTC 目标失败