在边缘进行实时推理的深度学习部署是许多应用领域的关键。它在网络带宽、网络延迟和功耗方面显著降低了与云的通信成本。
然而,边缘设备的内存、计算资源和能力有限。这意味着深度学习网络必须针对嵌入式部署进行优化。
int8量化已经成为一种流行的优化方法,不仅适用于TensorFlow和PyTorch这样的机器学习框架,也适用于NVIDIA这样的硬件工具链®TensorRT和Xilinx®dnndk主要是因为int8使用8位整数代替浮点数,使用整数数学代替浮点数学,减少了内存和计算需求。
这些要求可能是相当大的。例如,相对简单的网络如AlexNet超过200 MB,而大型网络如vg -16超过500 MB的[1]。这种规模的网络不适合低功耗微控制器和更小的fpga。
在本文中,我们将仔细研究使用8位表示数字的含义,并了解用整数表示数字的int8量化是如何减少75%的内存和带宽使用的。
int8表示
我们从一个简单的例子开始,使用VGG16网络,它由几个卷积层和ReLU层以及几个完全连接的最大池层组成。首先,让我们看看如何用整数表示一个真实世界的数字(在本例中是一个卷积层中的权重)。这个函数fi
在MATLAB®为我们提供了使用8位字长度的权重的最佳精度缩放。这意味着我们以2^-12的比例因子获得最佳精度,并将其存储为表示整数110的位模式01101110。
\[Real\_number = stored\_integer * scaling\_factor\]
\ [0.0269 = 110 * 2 ^ {-12} \]
脚本如下:
现在让我们考虑这层的所有权值。使用fi
同样,我们发现,对于卷积层中所有权值来说,能给出最佳精度的比例因子是2^-8。我们在直方图中可视化权值的动态范围的分布。从直方图可以看出,大部分权重分布在2^-3和2^-9之间(图1)。这也说明了权重分布的对称性。
这个例子展示了一种量化和用8位整数表示的方法。还有一些其他的选择:
通过对精度的权衡来选择不同的比例因子.因为我们选择了2^-8的比例因子,将近22%的权重低于精度。如果我们选择2^-10的比例因子,只有6%的权重会低于精度,但0.1%的权重会超出范围。错误分布和最大绝对错误(图2)也说明了这种折衷。我们可以选择16位整数,但这样就会使用两倍的位。另一方面,使用4位会导致显著的精度损失或溢出。
指定调用时的偏置fi
,根据权重的分布。
\[Real\_number = stored\_integer * scaling\_factor + bias\]
您可以对任何网络(例如ResNet50或yolo)进行类似的分析,并确定可以在一定公差内表示权重和偏差的整数数据类型或缩放因子。
使用int8将数据表示为整数有两个主要好处:
- 您可以将数据存储需求减少4倍,因为单精度浮点数需要32位来表示一个数字。其结果是用于存储所有权值和偏差的内存减少,以及传输所有数据所消耗的能量减少,因为能量消耗主要由内存访问决定。
- 您可以通过使用整数计算而不是浮点数学来获得进一步的加速,这取决于目标硬件。例如,您可能能够在NVIDIA gpu上使用半精度浮点。大多数cpu都不支持本机半计算。金宝app但是,所有目标都支持整数数学,有些还提供特定金宝app于目标的特性,例如SIMD支持,在使用整数进行底层计算时,这些特性可以提供显著的加速。
将一个网络量化为int8
量化背后的核心思想是神经网络对噪声的弹性;特别是深层神经网络,它被训练来提取关键模式,忽略噪声。这意味着网络可以应对量化误差导致的网络权值和偏差的小变化——而且有越来越多的工作表明量化对整个网络的准确性影响最小。再加上内存占用、功耗的显著降低和计算速度的提高[1,2],量化成为将神经网络部署到嵌入式硬件上的一种有效方法。
我们将把上面讨论的思想应用到网络中。为了简单起见,我们将使用一个简单的网络来进行由两层组成的MNIST数字分类。用于图像分类和目标检测的深度网络,如VGG16或ResNet,包括各种各样的层。卷积层和全连接层是最密集的存储层和计算层。
我们的网络模仿了这两层的属性。我们在Simulink中对这个网络进行建模金宝app®这样我们就可以观察信号流,并进一步了解计算的实质(图3)。
在每一层,我们将用缩放后的int8整数替换权值和偏差,然后用固定指数乘以矩阵乘法的输出来缩放。当我们在验证数据集上验证修改后的网络的预测时,混淆矩阵显示int8表示仍然保持了95.9%的准确性(图4)。
为了理解量化int8的权重和偏差带来的效率收益,让我们将这个网络部署到一个嵌入式硬件目标—在本例中,是一个ST发现板(STM32F746G).我们将分析两个关键指标:
- 内存使用情况
- 运行时执行性能
当我们尝试部署原始模型(双精度浮点)时,它甚至不适合主板,RAM溢出。最简单的解决方法是将权重和偏差转换为单一数据类型。该模型现在适用于目标硬件,但仍有改进的空间。
我们使用比例模型,它使用int8作为权重和偏差矩阵,但是计算仍然是单精度的(图5)。
生成的代码消耗的内存比预期的少4x(图6)。
但是,发现板上的执行时间显示,单精度版本的平均运行时间为14.5毫秒(约69帧每秒),而比例版本稍慢一些,平均运行时间为19.8毫秒(约50帧每秒)。这可能是因为对单个精度的强制转换的开销,因为我们仍然在单个精度中进行计算(图7)。
这个示例只涉及了在int8中量化存储权值和偏差的一个方面。通过将相同的原理应用于标准的现成网络,如AlexNet和VGG,您可以将它们的内存占用减少3x[1]。
例如,TensorFlow允许以两种形式对8位进行训练后量化——仅使用浮点内核的权值,以及权值和激活[3]的全整数量化。TensorFlow使用带有偏见的缩放因子映射到int8范围[- 128,127],NVIDIA TensorRT通过确定一个阈值来将权重编码到[- 128,127]范围,从而避免了偏见的需要,该阈值最小化信息损失,并使阈值范围[4]以上的值饱和。
为了充分利用全整数量化的好处,我们还需要将每一层的输入转换为整数类型。这需要我们为图层的输入确定正确的比例,然后在整数相乘后重新缩放。但是,int8是否是正确的数据类型,是否会出现溢出,以及网络的准确性是否可以接受?
这些问题是定点分析的本质——事实上,数字识别文档示例说明了如何使用定点数据类型[5]转换MNIST网络。按照该示例中所示的步骤,我们提出了权重的8位表示,插入精度低于1%(图8)。
生成的代码不仅是四分之一的大小;它也更快,11毫秒~ 90帧/秒(图9)。
其他量化技术
我们只讨论了正在研究和探索的用于优化深度神经网络的嵌入式部署的许多策略中的一小部分。例如,第一层的权重(大小为100x702)只有192个惟一值。其他可应用的量化技术包括:
- 通过聚类权值共享权值,利用Huffman编码减少权值[1]。
- 将权值量化到最接近2的次幂。这大大加快了计算速度,因为它用更快的算术移位操作取代了乘法运算。
- 将激活函数替换为查找表,以加快激活函数的计算,例如
双曲正切
和经验值
.例如,在图9所示的生成代码中,我们可以通过替换双曲正切
带有查找表的函数。
深度学习的应用不仅仅是网络。您还需要考虑应用程序的预处理和后处理逻辑。我们讨论的一些工具和技术已经被用于量化这类算法几十年了。它们不仅可以量化网络,而且可以量化整个应用。
您可以在MATLAB中探索所有这些优化思想。您可以探索量化到进一步限制精度的整数数据类型(如int4)的可行性和影响,或者探索浮点数据类型(如半精度)。结果令人印象深刻:Song、Huizi和william[1]使用这些技术的组合,分别将AlexNet和VGG等网络的规模缩小了35倍和49倍。