4

我用一个卷积层构建了一个简单的 CNN 模型,并用 Tensorflow Lite 对其进行了转换。(对于 MNIST !!)所以现在我的模型得到 8 位整数输入,权重也是 8 位整数。

我想测试从 TFLite 获得的参数,所以我为推理步骤编写了 C 代码。

输入图像像素被赋予 0 到 255 之间的 8 位整数,权重在 -128~127 之间。(偏差是 32 位整数。)当然,卷积结果由大于 255 的数字组成。

我查看了这篇论文(https://arxiv.org/pdf/1712.05877.pdf,“用于高效整数运算的神经网络的量化和训练”),它提供了一些关于如何处理这个卷积结果的提示。它说我必须(1)缩小,(2)向下(到 uint8),以及(3)应用激活函数来生成 8 位输出。

据我了解,我需要将 2^(-n) 乘以卷积结果。所以我将卷积输出划分为 256 并将最大数量限制为 255,并使用全连接层的权重进一步计算它们。

它显示了一个很好的结果(准确度 0.96+),但没有 TFLite 评估所说的那么高。(精度 0.98+)

我认为我没有以正确的方式做到这一点,因为“256”(我将卷积输出划分为)是一个随机数。实际上,当我将其更改为 340 时,它显示出最好的结果,但仍远低于使用 TFLite Interpreter 进行的 TFLite 评估。

实现推理步骤的正确和复杂的方法是什么?如何缩小规模

4

1 回答 1

4

这是关于 TF Lite 中量化基础的一个很好的问题。您提到的论文是一个很好的参考和理解基础数学的指南。TF Lite 现在使用与上述论文略有不同的量化方案,但仍完全支持在当前方案实施之前转换的模型的方案。供您参考,您可以在此处查看新量化方案的详细信息:

https://www.tensorflow.org/lite/performance/quantization_spec

您的问题的答案同样适用于 TF Lite 中的所有量化方案。对于您的问题的细节,您希望了解如何从 32 位累加器(将所有激活 * 过滤器的乘积相加的结果)下降到量化值(uint8 或 int8)。M从论文中,您可以看到除了第 2.2 节中公式 5 中定义的实值乘法器之外,所有整数运算都可以完成矩阵乘法(它与您感兴趣的卷积情况类似) 。量化方案的目标是在仅整数算术中执行所有数学运算,因此挑战是“如何仅用整数运算乘以实值 M?”。

“诀窍”是M按照等式 6 中所做的那样表示,将 2 的乘积提高到某个负指数乘以M_0,这是一个至少为 0.5 的实数,并且从上方受 1 的约束。乍一看,这并没有出现使我们的问题更容易。但是,首先考虑2^(-n)零件。这可以在计算机上表示为一个位移(我将在稍后讨论四舍五入)。假设处理了任何舍入问题,那么仅使用整数算术就可以轻松完成该部分。现在来说说这M_0部分。通过构造,我们已经绑定M_0到一个范围,我们可以使用整数类型的定点表示(例如 int32)并将所有位用作小数位(如果您不熟悉定点表示,您可能需要参考外部信息来源)。

M_0我们称之为“量化乘法器”的 32 位定点表示。您可以在下面的链接中看到该操作的详细信息,但本质上,将累加器乘以量化乘数涉及一个标准整数乘法,得到一个 64 位数字,然后取该结果的高 32 位。

实际代码有点难以理解,因为有各种问题需要通过适当的舍入(如本文中讨论的)、溢出、值饱和、钳位等来处理。您可以通过查看参考来开始理解它在这里实现:

https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/kernels/internal/common.h#L153-L162

其中SaturatingRoundingDoublingHighMul通过量化乘法器实现定点乘法并RoundingDivideByPOT实现乘法2^(-n)

在设备上运行的实际代码中,TF Lite 使用各种优化指令来实现这种算法,但参考代码得到了相同的答案,并且更易于检查和理解。希望有帮助!

于 2020-06-23T18:59:56.033 回答