论文阅读 - CRNN

文章目录

    • 1 概述
    • 2 模型介绍
      • 2.1 输入
      • 2.2 Feature extraction
      • 2.3 Sequence modeling
      • 2.4 Transcription
        • 2.4.1 训练部分
        • 2.4.2 预测部分
    • 3 模型效果
    • 参考资料

1 概述

CRNN(Convolutional Recurrent Neural Network)是2015年华科的白翔老师团队提出的,直至今日,仍旧是文本识别领域最常用也最好用的方法。CRNN主要由三部分组成,分别是feature extraction,sequence modeling和transcription,如下图1-1所示。
CRNN总体结构图

图1-1 CRNN总体结构图

feature extraction用于按宽度抽取图像特征,sequence modeling用于融合这些特征并输出label的预测分布,transcription用于将这个特征序列转化为文本。

CRNN强大的地方就是它只是一个框架,其中的feature extraction和sequence modeling部分都是可以替换成不同的模型的,比如feature extraction部分,可以换成任意的抽取图像特征的模型,想要追求性能就换成小模型,想要追求效果就换成大模型,非常灵活。

2 模型介绍

2.1 输入

输入是一般是文本检测的输出,一个长条形的图片,是横向长条的,因为我们的文字都是横着写的。而且这一长条里只能有一行文字,不能多行。多行就得要切成多个单行的长条分别输入。

文本有一些倾斜问题不大,但最好是在文本检测部分调整,即在文本检测部分检测多边形,再仿射变换成长条形,使得文本部分不倾斜。也有论文提出在CRNN的前面前置一个STN。STN要真的有效,需要有好的训练数据。就算有好的数据,也降低了模型的总体性能,增大了模型的训练难度。STN可以看成一个极简版的物体检测模块。

输入的尺寸一般为h×w×c=32×280×3h \times w \times c = 32 \times 280 \times 3h×w×c=32×280×3,不是这个尺寸的就resize and pad成这个尺寸,尽量不要只resize,这会使得文字变形。输入尺寸www会根据需求做调整,如果文本都是短文本,则可以考虑w=100w=100w=100

2.2 Feature extraction

Feature extraction就是对32×280×332 \times 280 \times 332×280×3的输入进行特征抽取的一个deep convolutional neural networks,输出1×w/4×d=1×70×5121 \times w/4 \times d=1 \times 70 \times 5121×w/4×d=1×70×512的向量。w/4w/4w/4表示对32×432 \times 432×4的一小块图片区域抽取一个512维的特征。这一小块区域被称为receptive field(感受野),或是帧。
特征抽取示意图

图2-1 特征抽取示意图

帧的尺寸是可以变的,输出的特征维度也是可以变的,这些都是超参数。也正是因为CRNN这种抽取特征的方式,使得它没法办法处理竖向的文本,所有高度上的像素都被压到一个特征里了,分不开了。帧的尺寸决定了模型的精度,比如有两个文字完全都在同一帧内,那模型就没法把这两个文字分开了,识别就有问题了。

要处理竖向的文本,需要训练一个识别文本方向的分类网络,然后根据文本的方向对竖向的文本进行旋转或者切片拼接等不同的操作。目的就是变成CRNN可以处理的输入。

2.3 Sequence modeling

我们令feature extraction部分的输出为x=x1,x2,...,xT\bold{x}=x_1, x_2, ..., x_Tx=x1,x2,...,xTT=70T=70T=70xtx_txt表示第ttt帧的特征,为一个512维的向量。假设字典的长度为NNN,Sequence modeling就是一个双向的LSTM,输出y=y1,..,yT\bold{y} = y_1, .., y_Ty=y1,..,yTyty_tyt表示第iii帧为每个字典中字符的概率,是一个N+1N+1N+1维的向量。

Sequence modeling部分的总输出是一个T×(N+1)T \times (N+1)T×(N+1)的概率图。
序列模型

图2-2 序列模型

使用双向LSTM的好处是:
(1)文本是一个序列,抽取特征的CNN模型只能看到附近几帧的图片特征,而双向LSTM可以融合更远的特征,使得模型看到完整的整个字;
(2)LSTM可以和CNN使用Back-Propagation Through Time (BPTT)的方法拼接起来一起训练;
(3)LSTM可以处理任意长度的输入。

2.4 Transcription

这部分是使用CTC来做的,它在训练和预测时有着不同的处理方法。2.3中的y\bold{y}y之所以维度为N+1N+1N+1就是因为CTC需要一个空白符"ϕ\phiϕ"。CTC的对齐基于两个规则:

(1)先合并所有的重复字符;
(2)再删除所有的空白符。

比如,下面两个序列s\bold{s}s经过对齐之后,都是"Hello"。

HϕeeeϕlllϕϕϕlllϕooHeeϕϕlllϕϕllllϕoooH \phi eee \phi lll \phi\phi\phi lll \phi oo \\ H ee \phi\phi lll \phi\phi llll \phi ooo HϕeeeϕlllϕϕϕlllϕooHeeϕϕlllϕϕllllϕooo

2.4.1 训练部分

训练时,我们是知道文本标签的。

假设我们的训练数据为{Ii,li}\{\bold{I}_i, \bold{l}_i\}{Ii,li}Ii\bold{I}_iIi为第iii张训练图片,li\bold{l}_ili为第iii张图片的文本标签,yi\bold{y}_iyi为第iii张图片的预测概率图(序列都用粗体进行了表示)。我们的目标就是

argmin⁡−∑ilogp(li∣yi)(2-1)arg\min -\sum_{i} log p(\bold{l}_i|\bold{y}_i) \tag{2-1} argminilogp(liyi)(2-1)

其中,p(li∣yi)p(\bold{l}_i|\bold{y}_i)p(liyi)表示用概率图yi\bold{y}_iyi得到文本序列li\bold{l}_ili的概率。

p(li∣yi)=∑s:B(s)=lip(s∣yi)(2-2)p(\bold{l}_i|\bold{y}_i) = \sum_{\bold{s} : \Beta(\bold{s})=\bold{l}_i} p(\bold{s}|\bold{y}_i) \tag{2-2} p(liyi)=s:B(s)=lip(syi)(2-2)

s\bold{s}s表示可以变成文本l\bold{l}l的一条路径,B(s)\Beta(\bold{s})B(s)表示对s\bold{s}s进行CTC对齐操作。p(li∣yi)p(\bold{l}_i|\bold{y}_i)p(liyi)也就是所有可以从s\bold{s}s变为li\bold{l}_ili的路径概率和。

p(s∣yi)=∏t=1Tystt(2-3)p(\bold{s}|\bold{y}_i) = \prod_{t=1}^T y_{s_t}^t \tag{2-3} p(syi)=t=1Tystt(2-3)

要找到所有可以从s\bold{s}s变为li\bold{l}_ili的路径,用枚举法是不行的,这里一般会用HMM中的前向后向算法,也就是动态规划。

2.4.2 预测部分

预测时,我们是不知道文本标签的。

这个时候要去计算所有可能的文本序列的概率,再找到最大的,简直无法想象。所以预测时,我们只能寄希望于模型训练的足够好,每一帧都预测得很准。然后用greedy search或者beam search的方法来找到最有路径。

greedy search是实际最常用的方法,就是取每帧概率最大的标签。

beam search是在每帧去概率最大的前n条路径,一直保留n条概率最大的路径,直到最后一帧,当n取1时,beam search就退化为greedy search。

以上说的都是只有字典的情况,当我们有词表lexicon时,我们可以根据结果,取编辑距离小于δ\deltaδ的所有词,然后再看取这些词时,概率最大的是哪个词,以此确定最终的输出。

3 模型效果

作者还对比了不同数据集下,CRNN对比其他模型的效果,不过这都是2015年的时候的了,看看即可。
CRNN和其他模型对比结果
不如看下百度开源的paddle-ocr里的对比结果。CRNN虽然不是准确率最高的,但是是paddle-ocr最推荐的算法。它的效果和性能的综合优势是最高的。
paddle-ocr对比结果

参考资料

[1] An End-to-End Trainable Neural Network for Image-based Sequence Recognition and Its Application to Scene Text Recognition
[2] 一文读懂CRNN+CTC文字识别
[3] PaddleOCR

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/470516.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python easygui_Python里的easygui库

想要用python开发一些简单的图形界面,于是接触了easygui库,由于这是新手教程,我会把它写的尽量简单,希望大家都能看懂。1.msgboxmsgbox( )有一个标题,内容和一个ok键(是可以更改的)。举个例子:import easyg…

Rust小技巧 - 让函数既可接受String或str,也可以返回String或str

文章目录1 场景说明2 解决方案2.1 允许不同的输入参数2.2 允许不同的输出参数2.3 让调用方来做处理参考资料1 场景说明 假设我们有一个函数foo,它既要允许&str也要允许String作为输入参数。或是既要允许&str也要允许String作为输出。&str和String之间的…

JSP九大内置对象(转载)

JSP中一共预先定义了9个这样的对象,分别为:request、response、session、application、out、pagecontext、config、page、exception 1、request对象 request 对象是 javax.servlet.httpServletRequest类型的对象。 该对象代表了客户端的请求信息&#xf…

recv发送失败 缓冲区太小_从 GFS 失败的架构设计来看一致性的重要性

作者简介 陈东明,饿了么北京技术中心架构组负责人,负责饿了么的产品线架构设计以及饿了么基础架 构研发工作。曾任百度架构师,负责百度即时通讯产品的架构设计。具有丰富的大规模系统构 建和基础架构的研发经验,善于复杂业务需求下…

Rust小技巧 - 把异步函数放进vector当中

文章目录1 场景说明2 解决方案2.1 无借用参数2.2 有借用参数参考资料1 场景说明 有些时候,我们希望将将异步函数放到vector当中,或者说是注册进vector当中,然后在某个地方遍历这个vector来实现对已经注册了的异步函数的调用。 Cargo.toml中…

好用的记事本_分类记事本软件哪个好用?大家推荐一个苹果手机用的分类记事本便签呗...

随着“互联网”的发展,现在都开始在软件上记事备忘了。那么,都有哪些好用的记事本软件可以选择使用呢?大家在选择记事本软件的时候,都有哪些标准呢?不知道大家的标准是什么,小编有一个不能妥协的标准&#…

tch-rs指南 - Tensor的基本操作

文章目录1 概述2 Tensor的基本操作2.1 Tensor的初始化(1)通过数组创建(2)通过默认方法创建(3)通过其他的tensor创建(4)通过opencv::core::Mat创建2.2 Tensor的属性2.3 Tensor的运算&…

命令行运行jmeter脚本

1、通过gui界面的jmeter创建一份脚本;2、打开cmd,切换到jmeter程序的Bin目录;3、执行jmeter.bat -n -t bookair_0613.jmx -l log_3.jtl;4、使用gui界面添加一个监听器,打开log_3.jtl文件,来分析测试结果。转载于:https…

bootstrap table 分页_Java入门007~springboot+freemarker+bootstrap快速实现分页功能

本节是建立在上节的基础上,上一节给大家讲了管理后台表格如何展示数据,但是当我们的数据比较多的时候我们就需要做分页处理了。这一节给大家讲解如何实现表格数据的分页显示。准备工作1,项目要引入freemarker和bootstrap,如果不知…

Rust小技巧 - 通过FFI编程运行tensorrt模型

文章目录1 概述2 使用说明2.1 配置说明2.2 修改c头文件2.3 编写build.rs2.4 测试参考资料1 概述 shouxieai/tensorRT_Pro是一个文档完善,效果也很不错的tensorrt库,里面有对yolov5,yolox,unet,bert,retina…

1+X web中级 Laravel学习笔记——查询构造器简介及新增、更新、删除、查询数据

一、新增数据 插入多条数据: 二、更新数据 更新某条数据: 自增某字段的值: 自减某字段的值: 自增的同时改变其他字段的值: 三、删除数据 四、查询 查面构造器查面数据 有以下几种方法 get(&…

【HTML5】Canvas画布

什么是 Canvas? HTML5 的 canvas 元素使用 JavaScript 在网页上绘制图像。 画布是一个矩形区域,您可以控制其每一像素。 canvas 拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法。 * 添加 canvas 元素。规定元素的 id、宽度和高度: &l…

SynthText流程解读 - 不看代码不知道的那些事

文章目录1 概述2 流程解读2.1 生成文字mask2.2 plane2xyz的bug2.3 文字上色2.4 图像融合参考资料1 概述 SynthText是OCR领域生成数据集非常经典,且至今看来无人超越的方法。整体可以分为三个大的步骤,分别是生成文字的mask,这里用到了图像的…

python if name main 的作用_Python中if __name__ == '__main__':的作用和原理

if __name__ __main__:的作用 一个python文件通常有两种使用方法,第一是作为脚本直接执行,第二是 import 到其他的 python 脚本中被调用(模块重用)执行。因此 if __name__ main: 的作用就是控制这两种情况执行代码的过程&#x…

1+X web中级 Laravel学习笔记——Eloquent ORM查询、更新、删除、新增

Eloquent ORM简介 larave1所自带的Eloquent oRM是一个非常优美简洁的ActiveRecord实现,用来实现数据库的操作他的每个数据的表都有对应的模型(model)用于数据表的交互模型的建立 一、Eloquent ORM的查询 二、Eloquent ORM新增 通过模型新增…

使用复合设计模式扩展持久化的CURD,Select能力

大家可能会经常遇到接口需要经常增加新的方法和实现,可是我们原则上是不建议平凡的增加修改删除接口方法,熟不知这样使用接口是不是正确的接口用法,比如我见到很多的项目分层都是IDAL,DAL,IBLL,BLL&#xf…

python脚本加密_教你如何基于python实现脚本加密

这篇文章主要介绍了如何基于python实现 脚本加密,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 from pathlib import Path import python_minifier import compileall import sys def get_save_path(from_dir,…