前前前文介绍了OCR系统的概况。 前前文介绍了OCR系统第一大的难点文字检测。 前文介绍了OCR系统第二大的难点文字识别。 那么是否完成了这两个大的部件,就能够完成OCR的搭建呢? 还需要什么样的知识呢?
Data 数据问题
数据!数据!数据!
数据格式
目前开源社区里面,存在若干种不同的数据格式来表征OCR样本,大致上可以分为以下四种:
行级别矩形
生活中的任意场景文字,往往是十分的多样化,有横排的文字,有竖排的文字,甚至有曲形的文字,等等。但是在深度学习以前,视觉机器学习方法往往难以处理过于复杂的情况,所以一般会专注于解决文档文字,而文档文字一般是横向平整的文本行。对此,数据标注的格式可以简单地采取行级别或词级别的矩形标注。一般英语场景倾向于使用词级别标注,因为英语单词之间是存在空隙的,图像上实际上可以认为是可分开的,而中文场景倾向于使用行级别标注,因为中文字符之间不存在空格,无法从图像上分开每一个词语。
行级别四边形
由于文字场景不可能是矩形,所以OCR数据的标注进化成为四边形就很好的解决了文字角度等文字。现阶段一般的数据集都采取此种标注。
行级别多边形
当文字场景从平直的文本行扩展到曲形的文本行的时候,四边形实际上是无法表征的,所以OCR任务若专注于曲形文本的时候,需要改变四边形标注方案成为多边形。
字符级别标注
字符级别标注自2019年以来逐渐流行
TODO
数据量
真实数据
TODO
合成数据
TODO
Speed 速度问题
对于公司里面的研发人员,”生产环境不可能使用比赛中刷榜所用的巨无霸模型”,已经是一个老生常谈的话题。实际生产环境中,有极高的速度需求,所以有很多很多对于速度的优化细节。
Programing Language 编程语言
众所周知,编程语言在运行速度上有着巨大的差异。自深度学习以来,python成为主流的编程语言,特别是训练深度学习模型的基础框架,如pytorch和tensorflow。然而在生产环境中,则主要应用c++。当然,除了速度有一定差异,还有一些加密相关的需要。
在2017年乃至2018年,CAFFE 某种程度上依然在生产中作为比较流行的推理库。但是一旦所需要的算子较为复杂,则开发成本非常的高。所以再后来,推理库变为更加多样化,如tensorflow作为主流训练工具的团队,则往往倾向于使用tensorflow serving,而pytorch作为主流训练工具的团队,则有一定的挣扎,不过目前也大致有onnxruntime这种方案。
Multithreading 多线程
使用多线程/多进程的手段,可以一定程度改善OCR流程中的逻辑代码速度。OCR系统,乃至一般而言的计算机视觉任务中,有不少可并行的环节。例如通用物体检测之后,可能需要裁切若干个感兴趣区域做后续处理,这时候可以进行多线程/多进程的透视变换。
Model Compression 模型压缩加速
为整个OCR系统加速,最最根本的环节,则是加速模型推理。模型加速压缩是一个大的课题,发展也非常迅速,例如:
- 张量分解 (SVD/CPD/Tucker/BTD/等)
- 剪枝(非结构化剪枝/结构化剪枝)
- 量化(float16/int8/等)
- 知识蒸馏(大模型蒸馏小模型/自蒸馏/等)
由于课题宏大,以后独立成文再做展开。一般而言,如果要把一个模型真正落地,第一步是进行推理库选型调研,例如模型所使用的算子推理库是否支持(特别地,调研是否存在算子仅支持CPU计算不支持GPU计算,若有,推理过程往往变得极其缓慢,因为张量需要进行CPU和GPU的来回拷贝),第二部则是找到模型的速度瓶颈并分析其优化空间,例如卷积核较多的情况可以进行结构话剪枝,最后一步则是检查模型在整体系统中的占比,考虑其耗时是否配得上其重要性,考虑是否有系统优化的空间。
Structured Output 结构化输出
Rule based 规则方法
结构话输出使用规则方法,一般就是使用正则匹配的方式,在数字,英文,特定模式的字符串等场合有高效且准确的表现。
Template based 模版匹配方法
TODO