https://blog.tensorflowcn.cn/2019/08/how-vflat-used-tflite-gpu-delegate-for-realtime-interference-scan-books.html
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgWZHu-8HmYr1hLm3JiYUeyxUBcawFDQeGfEqHKBYllmHX7iY6Dc0nXbIvsEYPR8FqO6NaksAsMYVbb0eRKAHUkI2lm32DhsuUpCs9_pDSAbCBEgP6UtQMVSvLJotHL5iwsTI3QnhGK-g/s1600/flattenedscan.jpeg
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)
这似乎适用于 GPU 代理,但在实际运行时,它会无警告地回退到 CPU。通常情况下,当这种情况发生时,TFLite 会向我们发出警告信息,例如“无法应用代理。只有前 M 个操作将在 GPU 上运行,其余 N 个将在 CPU 上运行”。因此,在使用 Lambda 层时要小心,并且始终尝试在继续之前测量实际推理时间。
结论
|
在各种 Android 设备上,GPU 上的平均推理时间与我们模型的基线 CPU 推理时间相比 |
虽然沿途遇到了几个障碍,但我们通过使用 TFLite GPU 代理将模型的推理时间减少了一半以上。我们最终能够为用户提供“实时预览”功能,其中扁平化的页面实时显示。
我们可以自信地说,使用 TFLite GPU 代理是一个绝佳的选择,强烈建议那些希望在移动设备上部署训练模型的人尝试一下。
要了解更多信息并亲身体验,请阅读 TensorFlow Lite GPU 代理。
|
vFlat 的鸟瞰图 |