使用整数/定点算法时,我们如何降低神经网络中累加值的精度?

问题描述

假设我们有一个多层神经网络。假设一个简单的 MLP(多级感知器)具有 Gemm1 -> Activation1 -> Gemm2 -> Activation2。现在,假设我们正在进行推理,并使用 int8 作为数据的精度和权重。

Gemm 层涉及累积。通常,累加以 32 位进行。因此,Gemm1 的输出包含 int32 中的所有元素。现在在我们开始 Activation1 之前,我们需要将它们从 32bits 转换为 8bits。也许我们没有。那么,我们将在 32-bits 中执行 Activation1。但在某些时候,我们需要回到 8 位,比如在启动 Gemm2 之前。

我的问题是:从 int32int8 的转换是如何完成的?我想到了两件事:舍入和量化。有很多舍入方法(简单、收敛、最近等),但在这种情况下,它看起来不像舍入,因为它不像我们失去了一点精度;我们正在丢失 24 位。对于量化,我们基本上采用 int32 输出矩阵中的整个数字范围,然后将其映射到 8-bit 范围。但是我们需要知道完整的输出矩阵才能做到这一点。我们不能逐个元素地做到这一点。

我在上面的文本中使用了 int,但我认为从舍入/量化的角度来看,固定点是相同的。浮点数不同。人们喜欢 BFloat16(超过 IEEE 半精度/FP16)是有道理的,因为它与 FP32 具有相同的范围。因此,将 Gemm1 的输出从 IEEE 全精度 (FP32) 转换为 BFloat16 时,更容易。我们将一个数字从 2.46392 更改为 2.5。我们只是失去了一些精度,但转换后的结果仍接近到原来的数目。使用定点/整数,这很令人困惑,因为我们似乎正在将一个数字从 253 更改为 56,这是完全不同的比例。

我希望这是有道理的。如有不对之处请指正。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...