边缘计算 | 在移动设备上部署深度学习模型的思路与注意点 ⛵

💡 作者:韩信子@ShowMeAI
📘 深度学习◉技能提升系列https://www.showmeai.tech/tutorials/35
📘 深度学习实战系列https://www.showmeai.tech/tutorials/42
📘 本文地址https://www.showmeai.tech/article-detail/306
📢 声明:版权所有,转载请联系平台与作者并注明出处
📢 收藏ShowMeAI查看更多精彩内容

大家在新闻当中见到越来越多的令人振奋的人工智能相关的应用新闻。

  • 『人工智能在围棋中击败了人类!』
  • 『基于神经网络的精准天气预报』
  • 『会写作创作的AI』
  • 『会说话的蒙娜丽莎绘画』
  • 『绘画艺术创作以假乱真的AI』

尽管新闻很炫酷甚至令人惊叹不已,但 AI 的应用与现实世界还有一些差距,核心的原因之一是它们的规模。为了取得更好的效果,现代AI神经网络模型会使用更大数据集、更多的模型参数,但这样一方面训练它们变得让普通人遥不可及(需要特定的昂贵物理资源和大量的电力资源等),另外一方面使得实际推理应用也变得复杂(无法在小型设备上部署,且推理时间很长)。

如果要让 AI 能覆盖现实生活中的场景问题,我们希望可以在资源有限的设备上运行的更小的模型。另外一方面,随着广受关注的安全和隐私问题,我们也希望模型可以部署安装在本地设备上,而不是向服务器传输任何数据进行请求。

接下来 ShowMeAI 给大家介绍和总结使 AI 模型能适用于小型本地设备上的方法技术,实现思路包括:压缩模型参数量设计更小的模型结构知识蒸馏调整数据格式数据复用等。我们还会介绍到移动小处理设备的类型,适用移动设备的模型框架等。

💡 模型压缩&加速方法

深度学习模型需要内存和计算资源,移动设备上这些都是紧缺的。最直接的处理方式是,通过降低深度学习模型的空间复杂性(参数数量)来适配移动设备,从而在保持精度不太变的同时减少计算量。模型空间复杂度降低大体有5类方法:

  • 减少模型参数数量(例如剪枝和参数共享)
  • 通过量化减小模型大小
  • 知识蒸馏
  • 设计更小结构的模型
  • 输入数据转换

📌 剪枝

剪枝的基本思想是筛选并删除一些对模型精度影响不大的冗余参数,然后重新训练模型以维持模型性能。基于神经网络的结构,我们可以修剪单个权重参数、模型层或模型层块:

  • 非结构化修剪:无论神经元出现在哪,只要它不是显著权重,就进行删减剔除,通过模型的精度效果可以维持得很好,但这种方法导致稀疏矩阵运算,实际运算很难加速。
  • 结构化剪枝:利用模型在不同尺度上的结构稀疏性(包括滤波器稀疏性、核稀疏性和特征映射稀疏性),直接移除一组参数(例如,整个卷积滤波器),这样结构依旧是完整的,GPU等密集矩阵运算很方便,它的挑战是在修剪的同时维持模型精度效果。

神经网络的剪枝裁剪压缩,通常是迭代进行的。在每次迭代中,会修剪相对不重要的filter并重新训练修剪后的模型(以恢复精度效果),直至修剪后的模型不能达到所需的最小精度时,剪枝迭代结束。

更详细的内容介绍,大家可以在论文 📘Pruning and Quantization for Deep Neural Network Acceleration: ASurvey 中查看。

📌 参数共享

另外一种处理思路是参数共享:我们不一定要裁剪和丢弃权重,而是当边权重基本相似时,我们可以在多个边上共享它们。

例如,对于都具有 N 个节点的两个全连接层,我们需要存储 N² 个权重。 但是,如果权重基本相似,先对其进行聚类,聚类到不同的簇,然后我们只存储簇质心。

📌 网络量化

神经网络中使用的默认类型是 32 位浮点数,高精度浮点数使得模型在训练阶段可以准确地梯度传播,得到更好的效果。但是在推理过程中就没有这个必要了。

网络量化的关键思想是减少每个权重参数的存储位数。例如从 32 位浮点压缩到 16 位浮点、16 位定点、位定点等。

量化方面的大部分研究都集中在从较大范围的数字映射到小得多的数字的舍入技术(rounding techniques)上——均匀/非均匀、对称/不对称量化。

有两种主要的方法来实现量化:

  • 训练后量化:这是最直接的方法——训练后的模型权重被直接映射到较低的精度,之后无需额外的微调。但这种方法会降低模型的效果。
  • 量化感知训练: 需要使用量化重新训练模型以匹配原始模型的准确性。量化网络通常在与原始模型相同的数据集上重新训练。为了保留梯度传播的精准度,梯度不会被量化。

开箱即用的量化不太容易做,因为不同的网络部分可能需要不同的精度。因此,量化/去量化块通常被插入中间以遍灵活转化与使用。

关于网络量化的详细的讲解大家可以参考 📘论文 A Survey of Quantization Methods for EfficientNeural Network Inference

📌 知识蒸馏

在深度模型的学习权重存在显着冗余的假设下运行,我们可以通过训练一个较小的模型(学生网络)来模拟教师输出的分布,从而提取大型模型(教师网络)学习到的知识。

模型蒸馏的关键思想是不仅仅使用训练数据集中给出的『硬』标签(比如分类问题中的类别标签),而是充分使用更大模型提取的精细化知识(例如分类问题中,大模型输出的类别概率向量)。

通过网络量化和剪枝,可以在压缩达到 4 倍的情况下保持精度。而知识蒸馏通过另外一种角度,在不压缩精度的情况下,直接在小模型上学习和保持效果;实际我们可以对所有方法组合使用。

关于知识蒸馏的更多详细信息,可以查看 📘论文 Knowledge Distillation: A Survey

📌 结构优化&小型模型

深度学习算法早期蓬勃发展,大部分的研究工作都集中在构建更大的模型,保证更强的学习能力,实现更先进的准确性。这一趋势后来被一系列研究「效率-效果」权衡的论文所取代,很多论文中直接提出和设计了小结构的模型。

典型的论文有: 📘MobileNetV1、📘MobileNetV2、📘MnasNet、📘MobileNetV3

关于小型神经网络的详细知识,大家可以查看 ShowMeAI 这篇文章: 📘深度学习与CV教程(10) | 轻量化CNN架构 (SqueezeNet,ShuffleNet,MobileNet等)

📌 数据处理&转换

另外一个处理思路是数据端,我们可以减少输入数据的维度和数量来加速计算。

一个例子是将图像分解为两个低分辨率的子图像,其中一个承载高频信息,另一个包含低频信息。结合起来,实际我们保留了和原始图像相同的信息,但具有更低的维度,即更小的输入数据,网络也小一些。

更多详细信息,可以查看 📘论文Learning a Wavelet-like Auto-Encoder to Accelerate Deep Neural Networks

💡 重用中间结果

另外一种加速思路是减少运算,比如有一些场景下我们可以避免冗余的计算。

📌 多任务之间数据重用

对于具有相同输入的不同但相关任务,如果并行运行多个模型就会有冗余的计算。很典型的一种思路是,在多个模型中重复使用来自浅层的特征,而是用不同的深层结构来应对特定的任务。

📌 图像帧之间数据重用

有些场景,虽然输入数据可能不完全相同,但可能足够(例如连续视觉模型处理的相邻帧),那此时可以部分重复使用数据。

有关更多详细信息,请查看 📘论文DeepCache: Principled Cache for Mobile Deep Vision

💡 移动设备上的深度学习框架

传统深度学习库 📘PyTorch和 📘Tensorflow并不特别适合移动应用。它们相对来说比较繁重并且有第三方依赖,在移动设备上比较麻烦。最初这两个框架都面向在服务器端,强大的 GPU 上进行高效训练,部署部分也通常是在服务器上的。

不过随着AI生态的演进和发展,它们专门为移动深度学习设计了框架:📘TensorFlow Lite和 📘PytorchLite,可以很有效地进行移动设备上的训练和部署。

开发移动深度学习应用程序的另一个挑战是每个移动生产商的标准不同,有些人会在 Tensorflow 中运行他们的模型,有些人会在 Pytorch 中运行他们的模型,有些人甚至会使用自有框架。为了打破这种界线,我们可以使用 📘开放式神经网络交换ONNX 框架来完成从一个库到到另一个库的转换。

大家还可以使用 📘OpenVINO,它通过专注于部署硬件来帮助优化深度学习应用程序,以便在云和边缘设备上进行推理。

对于常用手机移动端开发的更多详细信息,大家可以查看不同手机商的 API 文档:

除了上述提到的常见移动设备部署优化方法,这些生厂商还包含针对性的模型在特定设备上更高效的特定技巧。

💡 总结

深度模型需要在资源有限的移动设备上部署应用,需要克服计算速度和内存资源等限制。我们提到了一些方法来减小模型大小和加快计算速度,包括网络端、数据端不同的思路,大家在进行移动端AI应用时可以参考和优化。

参考资料

posted @ 2022-08-26 16:43  ShowMeAI  阅读(673)  评论(0编辑  收藏  举报