在这篇文章中,我们将带您了解我们如何为[【移动文档扫描仪】构建最先进的光学字符识别(OCR)管道的幕后故事。我们使用了计算机视觉和深度学习的进步,如双向长短期记忆(LSTM),连接主义时间分类(CTC),卷积神经网络(CNN)等。此外,我们还将深入研究如何实际使我们的 OCR 管道在 Dropbox 规模上做好生产准备。
文档扫描仪可以使用手机拍照并[“扫描”]收据和发票等项目。我们的移动文档扫描仪仅输出图像 - 就计算机而言,图像中的任何文本都只是一组像素,无法复制粘贴,搜索或您可以对文本执行的任何其他操作。
因此,需要应用光学字符识别或OCR。此过程从我们的文档扫描图像中提取实际文本。运行 OCR 后,我们可以为 Dropbox Business 用户启用以下功能:
提取扫描文档中的所有文本并为其编制索引,以便以后可以搜索
创建隐藏的叠加层,以便可以从另存为 PDF 的扫描件中复制和粘贴文本
当我们构建移动文档扫描仪的第一个版本时,我们使用了一个商用现成的 OCR 库,以便在深入创建我们自己的基于机器学习的 OCR 系统之前进行产品验证。这意味着将商业系统集成到我们的扫描管道中,为我们的业务用户提供上述两种功能,以查看他们是否从OCR中找到了足够的用途。一旦我们确认用户对移动文档扫描仪和OCR的需求确实很强烈,我们决定构建自己的内部OCR系统,原因有几个。
首先,有一个成本考虑:拥有自己的OCR系统将为我们节省大量资金,因为许可的商业OCR SDK根据扫描次数向我们收费。其次,商业系统针对平板扫描仪图像的传统OCR世界进行了调整,而我们的操作场景要困难得多,因为手机照片更加不受约束,具有褶皱或弯曲的文档,阴影和不均匀的照明,模糊和反射高光等。因此,我们可能有机会提高识别准确性。
事实上,计算机视觉世界发生了翻天覆地的变化,这给了我们一个独特的机会。传统上,OCR系统是大量流水线的,手工构建和高度调整的模块利用了各种条件,它们可以假设使用平板扫描仪捕获的图像是正确的。例如,一个模块可能查找文本行,然后下一个模块将查找单词和段字母,然后另一个模块可能会对字符的每个部分应用不同的技术来找出字符是什么,依此类推。大多数方法都依赖于输入图像的二值化作为早期阶段,这可能很脆弱,并丢弃了重要的线索。构建这些 OCR 系统的过程非常专业且劳动密集型,系统通常只能处理来自平板扫描仪的相当有限的影像。
在过去的几年中,深度学习成功地应用于计算机视觉中的许多问题,这些问题为我们提供了强大的新工具来处理OCR,而不必复制过去复杂的处理管道,而是依靠大量数据让系统自动学习如何执行许多以前手动设计的步骤。
也许构建我们自己的系统的最重要原因是,它将让我们更好地控制自己的命运,并允许我们在未来开发更多创新功能。
在本博客文章的其余部分,我们将带您了解我们如何以 Dropbox 规模构建此管道的幕后故事。大多数商业机器学习项目遵循三个主要步骤:
研究和原型设计,看看是否有可能
为实际最终用户生产模型
在现实世界中完善系统
我们将依次引导您完成这些步骤中的每一个。
研究和原型设计
我们最初的任务是看看我们是否可以构建一个最先进的OCR系统。
我们首先收集了一组具有代表性的捐赠文档图像,这些图像与用户可能上传的内容相匹配,例如收据,发票,信件等。为了收集这一组,我们询问了一小部分用户,他们是否会捐赠一些图像文件供我们改进算法。在Dropbox,我们非常重视用户隐私,因此明确表示这是完全可选的,如果捐赠,文件将保持私密和安全。我们对此类用户捐赠的数据使用各种安全预防措施,包括从不将捐赠的数据保存在本地计算机上的永久存储中,维护广泛的审计,需要强大的身份验证才能访问其中任何数据,等等。
对于用户捐赠的数据,另一个重要的、特定于机器学习的组件是如何标记它。大多数当前的机器学习技术都是受到严格监督的,这意味着它们需要显式手动标记输入数据,以便算法可以学习自己进行预测。传统上,这种标签是由外部工人完成的,通常使用微工作平台,如亚马逊的Mechanical Turk(MTurk)。但是,使用MTurk的缺点是每个项目都可能被不同的工作人员看到和标记,我们当然不希望像这样在野外公开用户捐赠的数据!
因此,我们在Dropbox的团队创建了我们自己的数据注释平台,名为DropTurk。DropTurk可以向MTurk(如果我们处理公共非用户数据)或一小群雇用的承包商提交标签作业,以获取用户捐赠的数据。这些承包商遵守严格的保密协议(NDA),以确保他们不能保留或共享他们标记的任何数据。DropTurk包含注释任务UI模板的标准列表,我们可以针对新数据集和标记任务快速组装和自定义这些模板,这使我们能够非常快速地注释数据集。
例如,下面是一个 DropTurk UI,旨在为单个单词图像提供真实数据,包括以下选项之一供工作人员完成:
转录图像中的实际文本
标记单词的方向是否正确
标记它是否为非英语脚本
标记它是否不可读或不包含任何文本