我正在尝试如下定义自定义的8位浮点格式:
是否可以将其定义为numpy数据类型? 如果不是,将dtype float16的numpy数组转换为这种格式(用于存储)并将其转换回(用于float16中的计算)的最简单方法是什么,也许使用numpy的位操作?
原因:
我正在尝试优化自定义硬件(FPGA)上的神经网络。为此,我在玩各种浮动表示形式。我已经使用numpy为我的神经网络建立了一个前向通过框架,因此上面类似的内容将通过将值存储在自定义数据类型中来帮助我检查准确性的降低。
答案 0 :(得分: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位整数,然后将其转换回浮点数组。请注意,big-endian表示会转换回字节,因为我们希望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)
您肯定可以看到精度的损失!我希望这有帮助。如果足够,请告诉我。如果没有的话,我愿意深入了解它。