Reading Scene Text with Attention Convolutional Sequence Modeling
这篇文章主要就是将RNN替换成了CNN,同时在特征提取网络中加入了attention的结构,效果还不错,速度提高了很多。
介绍
目前,有3中比较典型的架构来做文字的识别,如下图,前3个分别是目前常用的方法,我们提出的方法是第4个。
目前的方案主要是先用CNN提取图像特征,再用RNN处理序列,最后用CTC或者Attention来得到最后的结果。RNN对于处理序列信号是非常有效的一种方式,可以获取长期的依赖关系。但是,计算的时候,每一步都依赖与之前的步骤,不能进行计算的并行化。所以,RNN模型的计算非常依赖于输入序列的长度,常常计算时间很长。RNN训练的时候也不是很容易,会有一些梯度的消失或爆炸的问题。相比之下,CNN可以高度的并行化,计算复杂度也低。目前已经有一些方法用CNN来处理序列模型进行机器翻译,构建语言模型。这篇文章中,我们提出了一个端到端的卷积网络来处理文本识别的问题,结合使用了CNN和CTC,不需要任何的循环单元。我们用一个序列到特征图的映射,将序列转换为2D的特征图,然后作为CNN的输入,使用层叠的CNN来提取不同层次的上下文的特征表示,可以获取长期的依赖,而且依赖的长度可以通过卷积的数量来进行控制。这个结构时全卷积的结构,非常容易并行化,对序列的长度也是没有要求的。
另外,为了增强文本的表达能力,抑制噪声,我们在小的Dense网络中使用了一个残差的注意力机制,来获取更具分离度的注意力特征。
本文的主要贡献如下:
(1)提出了新的端到端的注意力卷积网络来进行文本识别,这个是全卷积的结构,同时具有高精度和高效率。
(2)使用了层叠的CNN来代替RNN,可以高效的获取上下文依赖,计算复杂度低,容易并行化。
(3)在小的Dense网络中使用了残差注意力模块,可以抑制背景噪声,提高前景文本的表达能力。
提出的方法
我们这个注意力卷积网络的全貌可以看图2,由一个注意力特征编码器,一个卷积序列模型和一个CTC模块组成。下面一个一个的说。
注意力特征编码器
为了提高CNN特征的可分性,我们设计了一个dense的注意力编码网络,在dense block中,dense连接可以提高层之间的信息流动,同时,加上注意力机制,背景的噪声可以有效的抑制。 然后,我们把特征图转换成序列,再从左到右拼成一张图像。
Dense连接
利用Densenet的优势,后面的层可以得到前面每一层的信息,梯度的反向传播更加的容易。
残差注意力
注意力机制在特征学习的过程中扮演非常重要的角色,可以聚焦显著性的区域,提高相关相关部分的表达能力。对于自然图像的文本识别,往往会有许多干扰的的东西,包括阴影,不相干的符号以及背景的纹理等等。使用注意力机制可以有效的抑制背景的这些干扰。
残差模块放在dense block之间,分成两个分支,特征分支进行的是前向传播,注意力分支生成soft attention的权重。attention分支设计成bottom-up top-down的结构,这样可以获取高层次的语义信息来指导可分性特征的选择。卷积后面会接一个max pooling,然后层叠几个来扩大感受野,收集全局的信息。然后,用一个对称的结构,使用上采样来恢复原来的分辨率,上采样用双线性插值。然后,attention的特征图作为权重加到对应的特征图的每个位置。考虑到attention的权重是0~1的,特征图和attention图的对应的元素乘积会导致有用信息的减少。因此,使用了一个残差attention来解决这个问题,和Resnet类似,残差attention模块的输出为:
其中,F和A分别表示特征分支和attention分支。这样的话,背景的噪声可以有效的抑制,同时提高了原始特征的可分性。
卷积序列建模
我们这里使用CNN来获取序列之间的双向依赖,这样比RNN要快。给定一个特征序列f=(f1, f2, …, fw),为了得到上下文信息c=(c1, c2, …, cw),循环神经网络R是通过循环连接ci=R(ci-1, fi)得到的,这是一个链式结构,不能并行。
我们的方法是使用卷积操作来对序列的依赖进行建模。首先,把特征序列放在一起,构成一个2D的图,每一列就是一个的原始的词图像相关的局部区域。然后,我们对输入使用宽度为k的卷积核进行卷积操作,得到输入序列的k个元素的上下文信息,用层叠的卷积来增大感受野,得到不同层次的特征表达。比如,4个卷积层,卷积核尺寸为5,可以获取17个输入元素的信息。这样,我们可以很方便的控制空间依赖的范围。当层的个数足够多的时候,可以获取到高层次的特征,得到需要的上下文信息。另外,卷积操作不依赖与之前的步骤,和输入序列的长度也无关。因此,这种操作可以大大的加速计算,此外,卷积操作消耗的内存空间也很少。
在序列建模的过程中,我们通过补零padding来保证序列的长度不变,然后,为了得到可以送到CTC中的输出,我们重新把特征图存成序列的形式。假设CNN的特征图的形状为CxHxW,我们把每一列的所有通道拼接在一起,得到一个向量,向量的长度为CxH,因此,我们可以得一个序列,具有W个向量,这就是上下文信息c=(c1, c2, …, cw)。最后,对于生成的序列,我们可以通过一个线性层得到概率的分布:
CTC
不多说了,主要用来克服输出序列长度和输入序列长度不一样的问题,通过在中间补空格,形成新的序列,解码的时候再使用一定规则把空格去掉。这样的话,输出可以解码成label的概率是什么呢?因为根据补的空格的位置和个数不一样,有很多种序列都可以最终解码成和label一样的序列,这样,输出可以解码成label的概率就是这些所有可以最终解码成和label一样的序列的概率之和。不过呢,这样计算太慢了,需要遍历所有的可能性,因此需要一个快一点的方法,这个方法就是类似隐马尔科夫过程的前向后向算法,最终得到的也是所有可以最终解码成和label一样的序列的概率之和。然后取对数损失就是CTC损失了。
Lexicon-free Recognition
推理的时候,每一步把概率最大的那个字作为结果就好了。
Lexicon-based Recognition
这个是有限制条件的,事先有个词典,用条件概率最大的那个作为输出,这个计算量很大,不够灵活,所以,我们用一个近似的方法,比较Lexicon-free方法得到的序列以及词典中单词的编辑距离,选择最小编辑距离的单词作为输出的label。
实验
实现细节
网络结构见表1,每个dense block中有4个卷积层,增长率为18。对于残差attention,特征分支有一个卷积层,attention分支是一个bottom-up,top-down的结构。细节上,3,2最大池化分别用在两个残差attention模块中。用sigmoid来归一化attention map的权重。另外,加上skip连接融合不同尺度的信息。此外,CNN序列建模的时候,包含4个卷积层,这样,输出可以覆盖9个输入元素的上下文信息,所有的卷积层都使用补零的padding,激活函数为ReLU和bn。
在训练和测试的时候,图像缩放到32x100,使用灰度图,用msra来初始化权重,使用Adam来训练,minibatch为64,梯度的clipping为5,用tensorflow实现。
消融研究