OCR文本识别教程系列一:CRNN的文本检测识别


title: OCR文本识别教程系列一:CRNN的文本检测识别
date: 2020-07-17 15:11:37
category: 默认分类

本文介绍 OCR文本识别教程系列一:CRNN的文本检测识别

OCR文本识别教程系列一:CRNN的文本检测识别

本文由林大佬原创,转载请注明出处,来自腾讯、阿里等一线AI算法工程师组成的QQ交流群欢迎你的加入: 1037662480

这是我们的OCR系列教程的第一篇, 文本识别, 因为它相对来说更简单, 下一篇我们会将DBNet做文本检测. 如果你感兴趣欢迎关注我们的专栏, 同时转发一下, 点个赞, 你的支持是我们持续创作的动力!

很久没有更文章了,前端时间我们的平台网站由于重新备案导致无法访问,期间我们社群的很多同学反应没有神力平台写代码都很无力,这对于我们来说无疑是很大安慰,也让我们有更大的动力把这项工作持续的做下去,给更多同学带来更简单易懂,更有用的AI教程. 另外我们的平台已经可以正常访问了, 欢迎大家来踩一踩:

http://manaai.cn

社区论坛:

http://t.manaai.cn

在很久之前我们做过一个中文手写字符识别的教程, 链接在这里:

https://zhuanlan.zhihu.com/p/68356509

当时我们是基于TensorFlow2.0实现的一个中文手写字符识别的教程. 简单来说就是做一个模型, 识别这里面的字:

我们大概实现到了一个这样的效果:

看起来其实也还蛮差不错, 相关代码感兴趣的朋友可以点击到对应文章去细读一下, 当然我们也提供完整的代码, 获取方式都在那篇文章里. 这篇文章要做到的效果, 可以说更进一步.

简单来说, 就是不再是一张图片一个字的方式来预测, 我们将使用CNN卷积网络和RNN循环递归网络来stack一个模型, 然后再来做这整个的识别.

让我们先来看看效果怎么样:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ix3tdezA-1594975250675)(https://i.loli.net/2020/07/17/pKwOTa9NtAsj5eL.png)]

这是我们从谷歌网页随便截的一张图, 然后把这张图送进去 我们的模型里面, 最终输出OCR的结果.

为了给大家展示一下我们做的这个模型的强大识别能力, 我们准备了一张这样的图片:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SpYmoqg2-1594975250676)(https://i.loli.net/2020/07/17/3M59uH6Bo7EzUhY.png)]

让我们输入到网络里面看看结果怎样:

image-20200717152352012

由于方格的存在, 它识别出来了边界线, 但大部分的字还是可以识别的! 甚至可以看到即便是识别错误的字, 人眼看起来他们也很像! 这张图有点难为我们的OCR AI了, 我们测试几张简单一些的吧:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DS0iZaSp-1594975250678)(https://i.loli.net/2020/07/17/QkaNwp42YLEXHD1.png)]

可以看到基于可以百分百的识别. 再测试一张:

image-20200717153116554

预测结果:

虽然手写体没有完全检测出来, 但是也八九不离十了. 识别印刷体还是很稳的. 接下来就干货时间了.

01. CRNN文本识别

应该来说现在做文本识别的结构都是CRNN. 文本识别实际上是一个下游任务, 当你把文本检测出来之后,在对对应的image patch做识别, 识别里面的每一个字符. 我们学过CNN的都知道, CNN是无法完成序列任务的, 因为CNN一般都是回归联系变量. 这就需要RNN来帮忙了. 细心的同学应该会发现, 我们上面测试的每一张图片, 对应的图片长度都是不一样的. 因为检测出来的每一个小文本区域, 它的长度不可能一模一样. 从而这也就完成了不同字数的检测实现. 得以与RNN的变长特性, 在这个任务中它将发挥巨大的作用.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n7V4aNRl-1594975250693)(https://i.loli.net/2020/07/17/ozpm9OYMyCxscKv.png)]

借鉴一张某位博主的图片, 大概阐述这其中的原理.

CRNN最复杂的不是CNN, 也不是RNN, 而是CNN和RNN的链接部分. 这部分实现我们使用的一个技巧是: 将CNN的channle看做是特征非连续的序列.

这如何理解呢? 其实就是把不同的channel,没一个channel当做是sequence里面的一个离散量, 那这就和RNN的输入对上了. 因为RNN的输出实际上就是一个N维的M时间跨度的形状.

02. CTC loss

说到用RNN来做生成任务, 就不得不说CTC loss. 大家仔细想一想, 上面我们说的模型搭建很简单, 但是实际上训练的时候你会遇到什么问题呢?

最典型的问题就是输出的长度和label的长度对不上.

举个例子, RNN可能输出了10个output sequence, 然而我的label有28个, 换句话说, 我这张图片里面有28个字, 你只检测出来了10个. 且不说每个字的概率你有没有分类正确, 但就这个数目你就不对了. 更加严重的是, 在模型训练初期, 确实会存在这个问题, 那这样我们如何去计算loss呢?

CTC loss便是解决不定长预测和标签的损失函数计算问题. 这个CTC loss在Tensorflow和Pytorch里面都有实现:

tf.nn.ctc_loss(
    labels, logits, label_length, logit_length, logits_time_major=True, unique=None,
    blank_index=None, name=None
)

torch.nn.CTCLoss()

用法和具体的逻辑都是参照2016年的那一篇原始paper实现的.

事实上,CTC loss算的不是类似于神经网络里面的那种MSE loss或者CrossEntropy, 而是马尔科夫链的条件 判别概率. 这一点想必学语音或者NLP的同学体会会更加深刻.

我们也不在这里深究, 丢一个paper给大家细看: https://dl.acm.org/doi/10.1145/1143844.1143891 Connectionist temporal classification: labelling unsegmented sequence data with recurrent neural networks.

03. 模型的主要架构

在01中, 我们就简单的说了这个模型的大概构建方式, 实际上根据我们的测试下来, 这个模型还有很大的优化空间, 主要优化方式就两个:

  • 对CNN特征提取进行简化 比如我们可以用CV领域很前沿的backbone替换掉原有的CNN结构, 如Ghostnet, SqueezeNet, ResNest18等;
  • 对RNN结构进行优化, 采用LSTM, 或者是BidirectionalLSTM, 甚至是加上attention 机制来提升模型的表达能力.

总的来说, 我们发现, 对于这个任务本身, 即便是一个相对来说很简单的CNN, 以及一个RNN Head, 其模型性能也能达到一个较好的水准.

另外对于模型本身的一些设计原则, 加一些Pooling层通常有利于提高模型看得清楚的能力, 但这有可能会提高模型的computation cost. 最终我们会在模型的大小和速度之间取得一个较好的tradeoff.

最后给大家看一看我们的ONNX导出的我们的简化版本的CRNN的效果:

image-20200717161301768

实际上我们的RNN Head用的就是两个BidirectionalLSTM. 模型最终的大小大概40m, 预测的速度在20-30ms之间.

05. 模型训练

本文教程下面会提供教程对应的源码, 训练之前, 我们可能需要花费一天的时间来下载这个超级大的中文字符识别数据集:

  • Synthetic Chinese String Dataset https://pan.baidu.com/s/1ufYbnZAZ1q0AlK7yZ08cvQ
  • 软链接解压到的images到你的代码目录的 datasets/scsd 下面;

  • 下载对应的label:labels (password: eaqb), 这个label实际上就包含了所有的字符, 和每一张图片的字标注.

最后准备就绪开始训练:

python3 train.py

image-20200717162650391

单卡训练7个epoch, 差不多就可以得到一个很好的模型.

04. FutureWork

我们会在这个baseline的基础上, 继续探究更小的模型来达到同样的准确率. 同时我们也会将模型迁移到MNN或者TensorRT来获得更大的加速. 也会进一步的和我们下一期要提供的文本检测模型进行整合, 来做一个端到端的文本检测系统.

和往常一样, 本文用到的所有工程代码都在神力平台, 神力平台是国内最大的AI算法市场, 海量AI算法开箱既用:

http://manaai.cn

本文代码链接:

http://manaai.cn/aicodes_detail3.html?id=64

如果你想学习人工智能,对前沿的AI技术比较感兴趣,可以加入我们的知识星球,获取第一时间资讯,前沿学术动态,业界新闻等等!你的支持将会鼓励我们更频繁的创作,我们也会帮助你开启更深入的深度学习之旅!

image-20200515153654923

往期文章

https://zhuanlan.zhihu.com/p/149398749

https://zhuanlan.zhihu.com/p/147622974

https://zhuanlan.zhihu.com/p/144727162

References

[1]. Connectionist temporal classification: labelling unsegmented sequence data with recurrent neural networks

[2]. CRNN

  • 4
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值