实战|TF Lite 让树莓派记下你的美丽笑颜

点击我爱计算机视觉标星,更快获取CVML新技术


文 / Lucia Li 实习生,TensorFlow Lite

Smart Photo Booth 应用实时运行图示

我们很高兴展示借助 TensorFlow Lite 在 Raspberry Pi 上构建 Smart Photo Booth 应用的经验(我们尚未开放源代码)。该应用可以捕捉笑脸并自动进行记录。此外,您还可以使用语音命令进行交互。简而言之,借助 Tensorflow Lite 框架,我们构建出可实时轻松处理笑脸检测和识别语音命令的应用。

  • Tensorflow Lite
    https://tensorflow.google.cn/lite

为什么选择 Raspberry Pi?

Raspberry Pi 不仅是使用广泛的嵌入式平台,且有体积小、价格便宜的优势。我们选择 TensorFlow Lite 是因为它专为移动端和 IoT 设备而设计,因此非常适合 Raspberry Pi。

构建 Photo Booth 应用需准备什么?

我们已在 Raspberry Pi 3B+ 上实现 Photo Booth 应用,其搭载 1GB RAM,并装有 32 位 ARMv7 操作系统。我们的应用具有图像输入和音频输入功能,因此我们还需要摄像头和麦克风。除此之外,我们还需要显示器来显示内容。总成本不到 100 美元。详情如下所列:

  • 一台 Raspberry Pi(35 美元)

    • 配置:
      » 主频为 1.4GHz 的四核 64 位处理器
      » 1GB LPDDR2 SRAM

  • 一部用于捕获图像的摄像头(约 15 美元)

  • 一个采集音频数据的麦克风(约 5 美元)

  • 一台 7 英寸的显示器(约 20 美元)

Photo Booth 应用涉及到两个关键技术:

  1. 我们需要从相机的图像输入中检测是否有笑脸;

  2. 我们需要从麦克风的音频输入中识别出是否存在“是”或“否”的语音命令。

如何检测笑脸?

我们很难在使用单个模型检测人脸并预测笑脸得分结果的同时保证高精度和低延迟。因此,我们通过以下三个步骤来检测笑脸:

  1. 应用人脸检测模型来检测给定的图像中是否存在人脸。

  2. 如果存在,则将其从原始图像中裁剪出来。

  3. 对裁剪后的人脸图像应用人脸属性分类模型,以测量其是否为笑脸。

笑脸检测工作流

我们尝试了如下几种方法来降低笑脸检测的延迟时间:

  1. 为减少内存占用并加速执行进程,我们使用了 TensorFlow 模型优化工具包中的训练后量化 (Post Training Quantization) 技术。在本教程中,针对您自己的 TensorFlow Lite 模型,您会发现该技术将非常易于使用。

  2. 对从摄像头中捕获的原始图像进行大小调整,并固定其长宽比。压缩率根据原始图像大小采用 4 或 2。尽量让图像尺寸小于 160x160(原设计尺寸为 320x320)。输入尺寸较小的图像可以大大减少推理时间,如下表所示。在我们的应用中,从相机中捕获的原始图像尺寸为 640x480,所以我们将图像尺寸调整为 160x120。

  3. 我们并未使用原始图像进行面部属性分类,而是弃用背景并使用裁剪出的标准人脸。如此可在保留有用信息的同时减小输入图像的尺寸。

  4. 使用多线程开展推理

  • 训练后量化
    https://tensorflow.google.cn/model_optimization/guide/quantization

  • 教程
    https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/g3doc/performance/post_training_integer_quant.ipynb

下表显示我们所用策略所带来的效果。我们使用 Tensorflow Lite 模型性能测试工具对人脸检测模型在 Raspberry Pi 上的表现进行性能评估。

  • Tensorflow Lite 模型性能测试工具
    https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/tools/benchmark

人脸检测延迟时间对比

检测笑脸的整个流程(包括我们之前提到的三个步骤)平均耗时 48.1ms 并只使用一个线程,这意味着我们能够实现实时笑脸检测。

人脸检测

我们的人脸检测模型由定制的 8 位 MobileNet v1 模型和深度乘数为 0.25 的 SSD-Lite 模型所构成。其大小略大于 200KB。为什么这个模型这么小?第一,基于 Flatbuffer 的 TensorFlow Lite 模型大小比基于 Protobuf 的 TensorFlow 模型小。第二,我们采用 8 位量化模型。第三,我们的 MobileNet v1 经过改良,通道比原来更少。


与大多数人脸检测模型类似,模型会输出边界框和 6 个面部关键特征点(包括左眼、右眼、鼻尖、嘴部中心、左耳屏点和右耳屏点)的坐标。我们还应用了非极大值抑制 (Non-Maximum Suppression) 来过滤重复的人脸。人脸检测 TensorFlow Lite 模型的推理时间约为 30 毫秒。这意味着模型可以在 Raspberry Pi 上实现实时检测人脸。

边界框和 6 个面部关键特征点示例

人脸裁剪工具

检测到的人脸朝向和尺寸大小各不相同,为了统一并更好地进行分类,我们会旋转、裁剪和缩放原始图像。我们将从人脸检测模型中获得的 6 个面部关键特征点的坐标输入函数。通过这 6 个面部关键特征点,我们便可以计算出旋转角度和缩放比例。经过上述流程后,我们便可得到 128x128 的标准人脸图片。下图示例展示我们面部裁剪工具的功能。蓝色边界框是人脸检测模型的输出结果,而红色边界框是我们经计算得出的裁剪边界框。我们会复制图像外部的像素边界线。

人脸裁剪工具图示

人脸属性分类

我们的人脸属性分类模型也是 8 位量化 MobileNet 模型。将 128x128 的标准人脸输入该模型,其会输出介于 0 到 1 的浮点型变量用于预测微笑的概率。该模型也会输出 90 维向量来预测年龄,范围在 0 到 90 之间。其在 Raspberry Pi 上的推理时间可以达到 30 毫秒左右。

如何识别语音命令?

实时语音命令识别也可以分为三个步骤:

  1. 预处理:我们使用滑动窗口来储存最新的 1 秒音频数据,以及音频所对应的 512 帧图像。

  2. 推理:通过输入的 1 秒音频,我们可以应用语音命令模型来获得出现以下四种类别的概率(“是”/“否”/“无声”/“未知”)。

  3. 后期处理:我们通过当前的推理结果与先前的结果计算出平均值。当一个词语的平均出现概率高于某个阈值时,我们便判断已检测到语音命令。

我会在下文详细解释这三个步骤。

预处理

我们使用 PortAudio(一个开源代码库)获取来自麦克风的音频数据。下图展示我们如何储存音频数据。

  • PortAudio
    http://www.portaudio.com/

音频流处理

由于我们的模型使用采样率为 16kHz 的 1 秒音频数据进行训练,因此数据缓冲区的大小为 16,000 字节。数据缓冲区亦作为循环缓冲区使用,我们每次会更新对应的 512 帧。此外,我们还会记录偏移量,用于指明上次更新的结束位置。当缓冲区尾部已满时,我们会从缓冲区的头部继续操作。在我们想要获取音频数据来展开推理时,我们会从偏移处开始读取,然后在偏移结束对应的帧结束。

语音命令识别

您可在许多公开的 TensorFlow 示例中找到我们使用的语音命令识别模型。该模型由 audio_spectrogram、MFCC、2 个卷积层和 1 个全连接层组成。这个模型的输入内容为采样率为 16kHz 的 1 秒音频数据。数据集支持公开访问,或者您也可自行训练。此数据集包含 30 种语音命令数据。由于我们只需要“是”和“否”类别,所以我们将其他标记归类为“未知”。

  • 语音命令识别模型
    https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/speech_commands


此外,我们也采用了其他方法来缩短延迟时间:

  1. 我们去除半数通道。压缩后的TensorFlow Lite 模型大小约为 1.9 MB。

  2. 与通常情况下使用最后一个全连接层的 12 个输出通道有所不同,由于我们只需要 4 种类别,所以我们使用了其中 4 个输出通道。

  3. 我们使用多线程来进行推理。

在训练中,我们将背景音量设置成 0.3,以提高模型的抗噪能力。我们还将“无声”和“未知”类别的比例各设置成 25%,以平衡训练集。

后期处理

音频流后期处理

由于我们获取的音频数据可能仅截取到一半命令,所以单个预测结果并不准确。我们储存先前结果(之前的记录时间不长于 1.5s),以取得平均预测结果。这可以大大提高关键字检测的实时性能。我们能够保存的先前结果的数量,在很大程度上取决于我们的推理时间。例如,我们模型在 Raspberry Pi 上的推理时间约为 160 毫秒,这意味着我们最多可以保存 9 个先前结果。

后续行动

我们希望在 TensorFlow Lite Github 代码库中尽快开放这个示例的源代码。如要了解关于如何上手使用 TensorFlow Lite 的更多详情,请参阅此处,并在此处查看其他参考示例。

  • 参阅此处
    https://tensorflow.google.cn/lite/guide

  • 此处
    https://tensorflow.google.cn/lite/examples/


欢迎留言分享您的 TensorFlow Lite 用例。

致谢

感谢 Lucia Li、Renjie Liu、Tiezhen Wang、Shuangfeng Li、Lawrence Chan、Daniel Situnayake、Pete Warden。


模型压缩与应用部署交流群

关注最新最前沿的网络压缩、知识蒸馏、剪枝、量化、应用部署技术,扫码添加CV君拉你入群,(如已为CV君其他账号好友请直接私信)

(请务必注明:部署)

喜欢在QQ交流的童鞋,可以加52CV官方QQ群:805388940。

(不会时时在线,如果没能及时通过验证还请见谅)


长按关注我爱计算机视觉

<think>嗯,用户想了解如何将CycleGAN模型部署到树莓派设备上,需要教程或优化方案。首先,我应该回顾一下CycleGAN模型的基本结构,因为了解模型的结构有助于后续的优化和部署。CycleGAN主要用于图像到图像的转换,比如将马转换成斑马,它包含生成器和判别器,可能比较复杂,参数量大,这对树莓派来说可能是个挑战。 接下来,部署到树莓派需要考虑硬件限制。树莓派的计算资源有限,尤其是CPU和内存,可能没有强大的GPU支持,所以模型优化是关键。用户可能需要将模型转换成适合移动或嵌入式设备的格式,比如TensorFlow Lite。根据引用[1],生成.tflite模型可以在Android上运行,类似地,树莓派可能也需要这样的转换。 然后,我需要考虑模型压缩的方法。比如量化,可以减少模型大小和加快推理速度。根据引用[2],MobileNet和ShuffleNet通过设计高效网络结构来压缩和加速模型,或许可以借鉴这些方法对CycleGAN进行优化,比如使用深度可分离卷积减少计算量。此外,模型剪枝和知识蒸馏也是可行的优化策略。 另外,部署框架的选择也很重要。树莓派常用的框架有TensorFlow Lite、PyTorch Mobile,或者使用TVM这样的编译器优化。引用[3]提到TVM可以从高层次优化深度学习op,这可能帮助在树莓派上高效运行模型。用户可能需要将CycleGAN模型通过TVM编译优化,生成适合树莓派的代码。 还需要考虑输入输出的处理,比如图像预处理和后处理在树莓派上的实现,可能需要使用OpenCV等库。此外,性能监控和调优也是部署后的重要步骤,确保模型在资源有限的情况下稳定运行。 用户可能遇到的问题包括模型转换中的兼容性问题,比如某些层不被支持,这时候需要调整模型结构或使用自定义层。另外,推理速度可能较慢,需要进一步优化模型结构或降低输入分辨率。内存不足的问题也可能出现,这时候模型量化或减少批处理大小可能有帮助。 最后,应该推荐用户参考现有的部署案例,比如引用[2]中提到的Orange Pi AIpro部署小雅影音库的经验,虽然平台不同,但优化思路可能相似。同时,建议用户查阅TensorFlow Lite和TVM的官方文档,获取具体的转换和优化步骤。</think>### CycleGAN模型树莓派部署方案 ### 一、模型部署基础步骤 1. **模型转换与压缩** - 将PyTorch/TensorFlow模型转换为TensorFlow Lite格式(`.tflite`) ```python import tensorflow as tf converter = tf.lite.TFLiteConverter.from_keras_model(keras_model) tflite_model = converter.convert() with open('cyclegan.tflite', 'wb') as f: f.write(tflite_model) ``` [^1] - 使用TVM编译器进行跨平台优化: ```python from tvm import relay mod, params = relay.frontend.from_pytorch(torch_model, input_shapes) with tvm.transform.PassContext(opt_level=3): lib = relay.build(mod, target="llvm -mtriple=armv7l-linux-gnueabihf", params=params) ``` [^3] 2. **硬件适配优化** - 量化压缩:将FP32转换为INT8精度,模型体积减少4倍 - 输入分辨率调整:将256x256输入降为128x128 - 使用深度可分离卷积替代标准卷积[^2] ### 二、树莓派环境搭建 1. 安装必要库: ```bash sudo apt-get install python3-opencv libatlas-base-dev pip install tflite-runtime ``` 2. 部署示例代码框架: ```python import tflite_runtime.interpreter as tflite interpreter = tflite.Interpreter(model_path="cyclegan.tflite") interpreter.allocate_tensors() input_details = interpreter.get_input_details() output_details = interpreter.get_output_details() # 图像预处理 input_data = preprocess(image) interpreter.set_tensor(input_details[0]['index'], input_data) interpreter.invoke() output_data = interpreter.get_tensor(output_details[0]['index']) ``` ### 三、性能优化技巧 | 优化手段 | 效果提升 | 实现难度 | |-------------------|----------|----------| | 模型量化(FP32→INT8) | 3-4倍加速 | ★★☆☆☆ | | 多线程推理 | 20-30%提升| ★★★☆☆ | | 内存映射加载 | 启动加速50%| ★☆☆☆☆ | | 算子融合优化 | 15-20%提升| ★★★★☆ | ### 四、典型问题解决方案 1. **内存不足错误** - 降低输入分辨率 - 使用`try...except`块实现分块推理 ```python try: full_inference() except RuntimeError: segmented_inference() ``` 2. **实时性不足** - 启用NEON指令集优化: ```bash export OPENBLAS_CORETYPE=ARMV8 ``` - 使用C++重写关键路径 3. **输出质量下降** - 在量化后添加动态范围校正层 - 采用混合精度量化策略 ### 五、部署验证流程 1. 基准测试:在树莓派4B上测试128x128输入推理时间应<2秒 2. 质量评估:使用FID指标验证输出图像质量(目标值<40) 3. 稳定性测试:连续运行24小时无内存泄漏
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值