【问题标题】:Define a custom float8 in python-numpy and convert from/to float16?在 python-numpy 中定义一个自定义 float8 并从/转换为 float16?
【发布时间】:2019-07-10 00:51:11
【问题描述】:

我正在尝试定义一个自定义的 8 位浮点格式,如下所示:

  • 1 个符号位
  • 2位尾数
  • 5 位表示指数

是否可以将其定义为 numpy 数据类型? 如果没有,将 dtype float16 的 numpy 数组转换为这种格式(用于存储)并将其转换回(用于 float16 中的计算)的最简单方法是什么,也许使用 numpy 的位操作?

原因:

我正在尝试优化自定义硬件 (FPGA) 上的神经网络。为此,我正在玩各种浮动表示。我已经用 numpy 为我的神经网络构建了一个前向传递框架,因此上面的内容将通过将值存储在我的自定义数据类型中来帮助我检查准确性的降低。

【问题讨论】:

  • 您要转换的数组/数据集的大小是多少?
  • @Deepstop 400x400x3 之类的东西。

标签: python numpy floating-point user-defined-data-types


【解决方案1】:

我绝不是 numpy 方面的专家,但我喜欢思考 FP 表示问题。您的数组的大小并不大,因此任何合理有效的方法都应该没问题。看起来好像没有 8 位 FP 表示,我猜是因为精度不太好。

要转换为字节数组,每个字节包含一个 8 位 FP 值,对于一维数组,您只需要

float16 = np.array([6.3, 2.557])           # Here's some data in an array
float8s = array.tobytes()[1::2]
print(float8s)
>>> b'FAAF'

这只是通过去掉低位部分从 16 位浮点数中取出高位字节,给出 1 位符号、5 位指数和 2 位有效数。在 little-endian 机器上,高位字节始终是每对的第二个字节。我已经在 2D 数组上尝试过它,它的工作原理是一样的。这会截断。以十进制四舍五入将是另一回事。

回到 16 位只是插入零。我通过实验发现了这种方法,毫无疑问有更好的方法,但这会将字节数组读取为 8 位整数并将新的字节数组写入 16 位整数,然后将其转换回浮点数组。请注意转换回字节的大端表示,因为我们希望 8 位值是整数的高位字节。

float16 = np.frombuffer(np.array(np.frombuffer(float8s, dtype='u1'), dtype='>u2').tobytes(), dtype='f2')
print(float16)
>>> array([6. , 2.5, 2.5, 6. ], dtype=float16)

您绝对可以看到精度的损失!我希望这有帮助。如果这足够了,请告诉我。如果没有,我会更深入地研究它。

【讨论】:

  • 这太棒了!我会尽快试一试。你能告诉我 dtype='f2', '>u2' 和 'u1' 做什么吗?我以前从未见过他们
  • 我有这个关于浮点的问题,我正在寻找过去几个月的解释。你能看一下吗?提前致谢!! stackoverflow.com/questions/57016843/…
  • dtype = f2 只是 dtype=float16 的缩写。 >u2 是大端无符号 16 位(即 2 字节)整数,u1 是 8 位无符号整数。它们列在docs.scipy.org/doc/numpy/reference/arrays.dtypes.html
  • 关于您其他涉及我不熟悉的硬件主题的问题。那里的答案比我对 CPU 设计和 FPGA 的了解要深得多。我只是一名前汇编语言程序员,尽管我已经做了一个小设备,实际上在芯片内部没有任何接口。顺便说一句,如果您想要的翻译不仅仅是删除所有其他字节以截断低位,并且输入的数量要高一两个数量级,我会很想构建一个 2^16长度转换表并切换到从 Python 调用的 C 函数。
  • 太棒了!我正在考虑编写一个 C 函数并从 python 调用它。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2017-07-27
  • 2023-03-11
  • 2012-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-04
相关资源
最近更新 更多