OCR,即光学字符识别,是在信息时代提升信息交互效率必不可少的技术。它可以帮助计算机从冗杂的图像资料中提取出所需的文字信息,极大地促进了办公和工业的自动化。
一年半前,我们推出了首个版本的 MMOCR,旨在促进学术和工业界对于 OCR 模型的研究创新、公平比较和高效产出。
https://github.com/open-mmlab/mmocr
(欢迎体验,觉得好用欢迎点亮小星星)
它是一个基于 PyTorch 和 MMDetection 的开源工具箱,支持众多 OCR 相关的模型,涵盖了文本检测、文本识别以及关键信息提取等多个主要方向。它还支持了大多数流行的学术数据集,并提供了许多实用工具帮助用户对数据集和模型进行多方面的探索和调试,助力优质模型的产出和落地。
MMOCR 效果展示图
经过一年多的迭代,MMOCR 终于在 9 月迎来了 1.0 版本的发布。但面对着成吨的修改以及如山的文档,相信很多朋友都会一脸懵逼,不知道除了版本号的变化外,还做了什么样的更新以及该从何下手。
所以,开发者们以自己的数撮头发为代价,为大家火速整理出了一份更新文档。接下来,我们就一起来了解一下 MMOCR 1.0 中的主要变化吧!
易用性全面提升
MMOCR 1.0 以用户体验为核心,重构了常见的接口和用户文档,降低了用户上手的难度。针对社区在使用和开发上常见的需求,MMOCR 均针对性地作出了优化和改进。
两行命令快速安装
对于曾经广受诟病的“安装复杂”问题,MMOCR 1.0 通过引入 MIM,如今最短只需要两行即可完成安装:
pip install -U openmim
mim install 'mmocr>=1.0.0rc0'
当然,若用户需要调整和修改 MMOCR 中的代码,还是免不了从源码安装的步骤。但相较于旧版本中繁琐的步骤,安装过程也同样变得十分顺畅而简单。
一键准备多数据集
在 OCR 领域中,各语种和场景下不同的数据集多如牛毛,使得用户在尝试在不同子方向的数据集上进行研究时,不得不屡次投入大量的精力去收集、处理和准备各种数据。此前尽管 MMOCR 0.x 中已经支持了50多个数据集,但用户仍然需要手动从原地址下载数据集,再逐个通过脚本转换格式,过程颇为复杂。
如今,我们推出了全新的 Dataset Preparer,帮助大家一键下载、解压和预处理数据集,彻底让大家从繁琐的手工作业中解脱。同时,该组件也在设计层面上规范化了数据集处理的步骤,通过组件化的设计极大地促进了代码复用,降低了 MMOCR 支持新数据集的难度。
简单灵活跨库调用
跨库调用,是 OpenMMLab 家族算法库之间的一种联动方式。如下图所示,MMOCR 通常支持两种形态的跨库调用:一是调用其他算法库的预训练 backbone,用作 OCR 模型的一部分;或是调用其他算法库的模型,套用在 MMOCR 的特定任务上进行训练和推理。
在 MMEngine 的支持下,MMOCR 1.0 的跨库调用变得非常简单。我们可以仅仅只修改几行配置,就直接调用 MMClassificatoin 的 backbone;或是直接将 MMDetection、MMRotate、MMYOLO 的检测模型迁移到 MMOCR 的任务上进行文本检测。
这两种情况都能通过直接修改配置在 MMOCR 中得到实现,我们在也会在后续的详解跨库调用的文章中为大家进一步讲解具体的实现和操作。
强大全面的可视化
MMOCR 1.0 新增了 Visualizer 组件,从而大大增强了对可视化的支持。其优点主要可以概括为多种类、全流程、多后端。
下图展示了一些 Visualizer 在 MMOCR 中可视化的例子:
架构全方位升级
在全新的 OpenMMLab 2.0 框架下,MMOCR 的整体代码上遵循了 OpenMMLab 的架构。与其它算法库一样,MMOCR 的部署任务现在统一由 MMDeploy 负责。在不久的未来,MMOCR 还会与更多 OpenMMLab 家族的算法库进行联动,进一步降低研究者们进行跨领域研究的门槛。
MMOCR 1.0 在 OpenMMLab 2.0 的规范的基础之上,结合 OCR 任务本身的特性对各个组件也进行了彻底的重构和升级。下图展示了 MMOCR 运行过程中各个组件被调用到的顺序:
在运行时,数据的标注会经过 Dataset 类,传入到 Transform 中。图片则会直接由 Transform 在解析标注后读入。经过一系列的数据变换(如数据增广、格式化等)操作后,数据会被打包成一种约定好的统一格式——DataSample,并被传入 Model 中进行运算。训练时,Model 所产出的 loss 会被传入 MMEngine 的 OptimWrapper。测试时,结果和 ground truth 则会经过 MMEngine 的 Evaluator,传入 MMOCR 的 Metric 中进行性能评估。
接下来,我们会逐个部分介绍 MMOCR 1.0 中的新变化。
对于不同的 OCR 任务(如文本检测、文本识别、端到端 OCR),MMOCR 如今均推荐采用 OpenMMLab 2.0 格式来统一表示数据。统一的数据格式不仅能减少对不同任务重复标注的痛苦,还有利于将来跨 OpenMMLab 算法库调用相同数据集。
我们已经更新了所有数据集的转化脚本,因此用户在按照文档转化数据集格式后,默认得到的数据集标注便已经是最新的格式。对于已经拥有 0.x 版本数据集的用户,我们也在迁移手册-数据集迁移中提供了迁移和兼容指南。
功能丰富的数据集
MMEngine 中实现了一个通用的数据集基类 BaseDataset。该类除了能直接读入 OpenMMLab 2.0 的数据集以外,还新增了许多使用的新功能,包括:
基于 BaseDataset,MMOCR 实现了 OCRDataset (OCR 任务)和 WildReceiptDataset(KIE 任务)以读取不同任务格式下的标注。
此外,对于暂时不便从 0.x 版本数据集迁移的用户,我们也实现了针对文本检测任务的兼容类 ICDARDataset,以及针对文本识别任务的兼容类 RecogTextDataset、RecogLMDBDataset,便于用户在不更新数据集格式的情况下直接在新版 MMOCR 中复用数据集。
当然,考虑到新格式未来的扩展性以及旧版格式存在的一些不合理之处,我们会在未来的版本中逐渐抛弃对旧版格式的支持。
独立高效的评价指标
此外,在 MMOCR 1.0 中,我们将原本作为 Dataset 一部分的评测部分解耦为独立的评测指标(Metric),并根据任务和评价尺度,对其进行了重构和优化。
简洁鲁棒的数据变换
我们在新版本的 MMOCR 中亦对旧版的数据变换(Transform)作了一次全面的升级,整理、合并、优化了数个 Transform,大大减少了代码的冗余度。
同时,重构后的 Transform 也修复了一些边界条件下的 bug,使整体鲁棒性也获得提升。经实验,MMOCR 1.0 中的检测模型在使用与旧版完全等价的 transform 训练后,产出权重的准确率数值平均增加了 0.44%:
另外,我们也针对研究者和开发者优化了文档体验。对 OpenMMLab 框架有所了解的用户应该知道,多个 transforms 组成的 pipeline 本质上是对数据标注作一系列的修改操作,最终转化成模型所需的标准输入。下图展示了一个典型的 pipeline 案例:
然而,在旧版的 MMOCR 中,除了阅读源码,用户并无法得知每个 transform 对输入字段的要求和运行后会做出改动。如今,我们在 docstring 内加入了详细的字段说明,方便用户全面了解使用该 transform 的场景:
另外,为了便于用户查找 transforms, 我们也根据功能的不同,对 transform 的文件分布作了整理,如下表所示:
功能 | 文件分布 |
---|---|
数据读取 | loading.py |
数据格式化 | formatting.py |
跨库数据转换 | adapters.py |
数据增广 | ocr_transforms.pytextdet_transforms.pytextrecog_transforms.py |
外部库包装 | wrappers.py |
系统化的模型设计
新版本的 MMOCR 在 Model 的执行逻辑上也有所不同。
如下图所示,Model 的输入被统一成图像特征 imgs 和包含了对应实例元信息(如 ground truth 标注)的 DataSamples。
它们在运行时会先被传入 Data Preprocessor,由该组件对图像进行 padding、normalize 及颜色通道翻转等操作。之后,处理过的数据会被传入模型的各个组件,按顺序进行计算。按照功能,它们可以粗略地被分为 3 类:
由于模型执行的部分会随着其运行状态不同产生变化,我们也对 Head/Decoder 的结构作出了新的抽象设计。具体而言,模型在训练时需要输出 loss,而在测试时则要输出预测结果。
如图,我们将这两部分别抽象为两个新的模块:ModuleLoss 和Postprocessor,并把它们设置为 Head / Decoder 的子模块。
其中,ModuleLoss 会先根据 ground truth 计算 target,再结合模型的原始输出计算出 loss 值,最后输出包含所有 loss tensor 的字典。而在预测时,Postprocesor 就负责把模型的输出转化成任务的标准输出,即对应任务的 DataSample。
除此以外,针对文本任务的需求,MMOCR 1.0 引入了 Dictionary 类,并把它作为 Head/Decoder 中的子模块使用。Dictionary 除了负责 string 跟 index 的互相转换外,也开放了一些内部属性供其它模块使用,减轻了用户开发和使用的负担。
例如,我们在旧版 MMOCR 上调试模型时,如果要改变一个字典的字符数量,还需要手动修改文本模型的输出层大小,才能保证模型输出结果的合理性。
如今在 Dictionary 引入后,模型可以根据 Dictionary.num_classes 动态调整输出层的大小,而用户只需要保证 Dictionary 类的字典配置正确即可。这样的设计既简化了配置,也规避了许多可能产生的低级错误。
Dictionary 示意图
总结
经过数个月的密集开发,MMOCR 1.0 的整体架构已经变得更加成熟和鲁棒,构成了一套稳固的学术研究基座。我们希望通过这一开源项目,推进领域研究的规范化,促进 OCR 方向良性的学术发展,并让更多前沿的成果更快地普及到实际应用和工业界上来。
尽管大规模的升级暂时已经告一段落,但我们还会持续迭代 MMOCR 1.0,不断地推出更多的新功能,满足各方面的需求。例如,我们会推出更简便易用的推理接口,新增更详细的文档教程,也会持续支持更多前沿的学术成果。
开源项目的核心是社区共建,因此,我们也希望让更多社区成员有机会参与算法库的开发和管理中,成为开发者的一员。
我们已经推出了一个社区任务列表,把一些难度适中的开发项公开给大家,欢迎有兴趣的朋友前来认领。很快,我们也会公开更多的开发者文档,并邀请有兴趣的社区开发者进行 review 和修改。
如果你认为参与这些活动都有一些困难,没关系——试用和吐槽 MMOCR 1.0 也是一种贡献 。如果大家在试用 MMOCR 的时候有遇到什么槽点,欢迎通过 issue 或者公测问卷及时向我们反馈!
任务列表:
https://github.com/open-mmlab/mmocr/issues/1493
公测问卷:
https://uua478.fanqier.cn/f/3dsjbvcz
想了解更多 MMOCR 1.0 相关内容,欢迎查看直播回放视频~
双版本维护计划
因为 MMOCR 1.0 相较于 0.x 版本变动较大,我们也采取了较为保守的维护策略,确保熟悉了 0.x 版本的用户有充足的时间迁移至新版本。
开发维护计划如下图所示,整体按时间会分为公测期、兼容期和维护期。
公测期(2022/9/1 - 2022/12/31)
兼容期(2023/1/1 - 2023/12/31)
维护期(2024 起)