前言:

目标检测是计算机视觉领域的一个大佬,就连大名鼎鼎的图像识别从某种程度上可以看做目标检测的一个特例,即图像中 only one object 同时不需要检测目标在图像中的位置。常见的 object detection 都是关于动物(猫)交通工具(飞机)常规物体(杯子)等实物,即可以通过一些视觉特征如轮廓、形状等准确的识别出物体。然而,但是,如果图像中出现了文本信息呢?如何识别视觉图像中的文本信息。显然,我们不能再通过 object 的视觉信息识别文字,我们需要提取文本目标的合适特征用于识别任务。

算法原理

文本信息都是上下文相关的,单个词语在特定的语境中会有不同的解读,所以对于文本的处理必须兼顾上文和下文。双向的LSTM可以同时处理左到右和右到左的序列数据,我有一个大胆的想法。图像中的文本也是文本,如果可以把它提取成LSTM可以处理的序列数据,那么是不是就实现了图像中文本信息的识别呢?是的,可以,这就是CRNN的出发点。

CRNN的思想就是通过CNN网络提取文本图像的特征,然后转化这些特征用于RNN(LSTM)识别具体的文本内容。(猜测Attention 机制应该可以,找机会试一下)

一般处理文本数据时最先想到的就是LSTM模型,这是因为文本的理解和处理必须在特定的语境(上下文)中进行,LSTM模型的输入通常都是学习到或者人工设定的 word-vector,CRNN的一个最大的优点就是通过预训练的CNN网络直接同图像中学习文本的表达向量,在最大程度上保证输入到LSTM的序列是最好的表达。

网络结构:

CRNN网络结构

如上图,对于图像中的STATE单词,首先通过CNN的卷积层提取特征,之后用这些特征生成LSTM需要的序列特征,在训练好的双向RNN网络中完成识别。下面会重点记录网络中的一些细节。先来看一下网络各层的具体参数。

CRNN网络层参数

首先是提取特征的CNN网络,可以是任意一款深度网络,VGG、resnet、googleNet、mobileNet等网络均可,论文中用的是VGG16,需要注意的是无论选取哪种网络要保证最终输出的特征是二维的即(N,H,W,C)中H必须为1,否则是不能用作LSTM的输入的。为了保证这一点,论文中对VGG16网络进行了微调,分别对第三、四Max-pooling 的尺寸进行改变,从(2,2)变为(1,2)。对于经典的VGG16网络,原始图像经过四个Max-pooling层后,图像的W、H变为原来的W/2^{4},H/2^{4}H/2^{4},如果对最后两个Max-pooling层进行改变后,原始图像的W则会变为W/2*2,H变为原来的1/16,所以为了确保CNN网络输出的feature的H为1,所以输入图像的H必须是32(针对VGG16)。同时,训练时为了加速LSTM,在第四和第五卷积层后增加了BatchNormalization层。

之后是Map-to-Sequence,其实就是按照从左到右的顺序把CNN最后一层卷积的输入进行拆分,而由前面的知识我们知道LSTM输入序列的长度是 W/4。

tf.squeeze(input_tensor, axis=1)

在tensorflow中的实现,input_tensor 是cnn网络最后一层卷积层的输出。

注释:下文中 tf 代表 tensorflow。

然后是LSTM层,这是一个双向深层的RNN网络,在 tf 中有两种实现方式。

tf.nn.bidirectional_dynamic_rnn
深层双向LSTM
tf.contrib.rnn.stack_bidirectional_dynamic_rnn
stack双向LSTM

论文中采用的是第二种实现方式。

最后是 Transcription Layers,即把LSTM的输出转换成具体的字符。对图像识别有所了解的同学应该知道图像识别实际上是通过 softmax 函数实现的一个多分类模型,类似的我们可以对LSTM的输出作softmax处理然后选取最大值所对应的标签(字符),但这样做是有问题的。一、标注问题,在图像识别问题中,输出位置和标签是一一对应的,但是对于文本数据,显然做不到输出位置和类别的一一对应。二、文本通常都是不定长度的,softmax输出类别数目是固定的,无法处理不定长度的label。CTC-loss,解决所有与文本相关的问题。我不懂。。。

总之,通过引入CTC-loss完美的解决了softmax搞不定的问题,既不需要逐个位置标注字符又可以输出任意长度的label。原理部分到此结束,小提示,可以先熟悉CNN和LSTM的基本原理和结构,然后理解起来还是很easy的。

下面是实现阶段。其实也没有太多可说的,需要注意的是要对输入图像进行检察,即 W/4 >= len(label),换句话说,图像的lable即文本内容的长度要小于等于图像W的1/4,否则的话网络输出的文本长度会大于输入序列的长度,这是犯罪。

当然,还有一些别的细节,这个就不一一列举了,在代码和readme中都有相应的注释,我的项目地址在:github 上传失败,把它放在下载项吧。

注意:图像tensor 的shape是(N*H*W*C)还是(N*W*H*C),这个在网络第三和第四max-pooling层的参数设置上是有区别的,就是(2,1)、(1,2)的不同。本文这里是采用的第二种。

另外,关于tensorflow fine-tuning 的一些基本操作,注释 init_op = tf.global_variables_initializer(),该用

saver = tf.train.Saver()

saver.restore(sess=sess,save_path=path_to_pre_trained_model)

https://download.csdn.net/download/zshluckydogs/11026575

Keras实现

在tensorflow实现的基础上做了以下调整:

1、用ResNet50代替VGG16获得更好的图像特征表达

2、舍弃LSTM层加速训练(单卡1080ti,batch_size=32,训练时间长达15小时,

如果保留LSTM层训练时间会更久,当然如果你的硬件设备算力足够的话可以带上LSTM层。)

为什么batch_size 

Inference:

1、https://zhuanlan.zhihu.com/p/43534801

2、论文原文 An End-to-End Trainable Neural Network for Image-based Sequence Recognition and Its Application to Scene Text Recognition

 

 

GitHub 加速计划 / te / tensorflow
184.55 K
74.12 K
下载
一个面向所有人的开源机器学习框架
最近提交(Master分支:2 个月前 )
a49e66f2 PiperOrigin-RevId: 663726708 2 个月前
91dac11a This test overrides disabled_backends, dropping the default value in the process. PiperOrigin-RevId: 663711155 2 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐