vFlat 如何使用 TFLite GPU 代理进行实时推理以扫描书籍
2019 年 8 月 13 日
Kunwoo Park,Moogung Kim,Eunsung Han 的客座文章

使用 vFlat 应用程序对弯曲的书页进行扁平化扫描
虽然有很多移动扫描应用程序可供下载,但大多数都专注于数字化平面文档,在扫描书籍的弯曲页面时会遇到困难。当扫描带有文本的弯曲表面时,一个人可能会通过拆除书籍或出版物的装订来进行破坏性扫描,或者 simply accept the input as is 并处理读取相机捕获的弯曲图像。

这就是 VoyagerX 开发 vFlat 的原因,这是一款使用深度学习解决此问题的 Android 应用程序。vFlat 应用程序旨在让用户轻松扫描书籍,无需担心弯曲的页面。它还尝试通过自动确定书页的边界来减少用户的 manual input。
左:普通移动相机拍摄的弯曲书页图像。右:使用 vFlat 扫描同一图像的版本
当用户尝试通过 OCR(光学字符识别)从书籍页面照片中提取文本时,这非常有用。从 **上面左边的图像** 中提取文本时,由于文本过于弯曲,OCR 无法正确识别某些单词和文本行。但是,将相同的技术应用于 **右边的图像** 会产生更高的成功率,并且可以提取几乎没有错误的文本。
vFlat 应用程序中图像 B 的 OCR 结果

我们如何构建 vFlat 应用程序

我们开发了一个深度学习模型,用于使弯曲的书页变平,并决定在移动设备上进行,以提供最佳的最终用户体验。在 vFlat 应用程序中,有一个“实时预览”功能,用户可以在其中实时查看扁平化的书页(超过 20 FPS)。如果用户可以使用应用程序实时预览扫描的页面作为扁平化图像,他们可以在拍照之前调整角度和框架。
vFlat 的“实时预览”功能
为了在移动应用程序中实现实时推理,我们优化了训练的模型,并利用了硬件加速的优势。我们最初的想法是用 OpenGL 自己实现推理模块,所以我们正在准备用 GLSL(OpenGL 着色语言)来实现模型的层。

幸运的是,我们发现了 TensorFlow Lite 的 GPU 支持,并决定尝试一下(在撰写本文时,‘tensorflow-lite-gpu’ 包版本已更新为 ‘org.tensorflow:tensorflow-lite-gpu:0.0.0-nightly’)。我们减少了权重和复杂操作的数量,从而得到一个轻量级的模型版本,并利用了 TFLite GPU 代理进行硬件加速。

深度神经网络非常适合 GPU,因为 GPU 比 CPU 具有更强的计算能力,并且擅长处理大量的并行工作负载。但是,使用移动 GPU 并非易事;这就是 TFLite GPU 代理的用武之地。

TFLite GPU 代理为移动 GPU 优化神经网络的图,并生成和编译异步执行的计算着色器。多亏了 TFLite GPU 代理,我们节省了数月的开发时间,因为我们不必实现自己的硬件加速推理模块。

虽然我们使用 TFLite GPU 代理节省了时间和精力,但在将我们自己的模型转换为 TFLite 模型并将其与 TFLite GPU 代理集成时遇到了问题。GPU 代理的实验版本仅 支持操作,这些操作主要用于 MobileNet,并且不支持我们原始模型中的某些操作。

为了利用 GPU 代理而不牺牲模型的性能,我们必须在保持整体网络结构不变的情况下,对某些操作进行替换。我们在转换过程中遇到了问题,并且由于源代码当时还没有公开,因此很难查明我们看到的错误的原因。(TFLite GPU 代理的代码现在已在 GitHub 上公开)

例如,由于 TFLite GPU 代理不支持 LeakyReLU 操作,因此我们必须以以下方式使用支持的 PReLU 操作:

通过更改

> tf.keras.layers.LeakyReLU(alpha=0.3)



> tf.keras.layers.PReLU(alpha_initializer=Constant(0.3), shared_axes=[1, 2], trainable=False)

但是,当我们尝试通过共享所有轴 (shared_axes=[1,2,3]) 将 PReLU 操作的参数数量减少到 1 时,我们遇到了意想不到的行为。虽然此代码在 CPU 模式下可以正常工作,但 GPU 代理因错误“线性 alpha 形状与输入通道数量不匹配”而失败。这就是我们最终只沿着轴 1 和 2 共享参数的原因。

我们遇到的另一个问题是,当我们尝试使用网络中的 Lambda 层将输入数据标准化到 -1 和 1 之间时。

> tf.keras.layers.Lambda(lambda x : (x / 127.5) — 1.0)
TFLite 转换器 转换的 Lambda 层的可视化
这似乎适用于 GPU 代理,但在实际运行时,它会无警告地回退到 CPU。通常情况下,当这种情况发生时,TFLite 会向我们发出警告信息,例如“无法应用代理。只有前 M 个操作将在 GPU 上运行,其余 N 个将在 CPU 上运行”。因此,在使用 Lambda 层时要小心,并且始终尝试在继续之前测量实际推理时间。

结论

在各种 Android 设备上,GPU 上的平均推理时间与我们模型的基线 CPU 推理时间相比
虽然沿途遇到了几个障碍,但我们通过使用 TFLite GPU 代理将模型的推理时间减少了一半以上。我们最终能够为用户提供“实时预览”功能,其中扁平化的页面实时显示。

我们可以自信地说,使用 TFLite GPU 代理是一个绝佳的选择,强烈建议那些希望在移动设备上部署训练模型的人尝试一下。

要了解更多信息并亲身体验,请阅读 TensorFlow Lite GPU 代理。
vFlat 的鸟瞰图
下一篇文章
How vFlat used the TFLite GPU delegate for real time inference to scan books

Kunwoo Park,Moogung Kim,Eunsung Han 的客座文章

虽然有很多移动扫描应用程序可供下载,但大多数都专注于数字化平面文档,在扫描书籍的弯曲页面时会遇到困难。当扫描带有文本的弯曲表面时,一个人可能会通过拆除书籍或出版物的装订来进行破坏性扫描,或者 simply accept the input as is…