如何在 TensorFlow 中模拟降低精度的浮点数?

How to simulate reduced precision floats in TensorFlow?

我想要一种方法来将 TensorFlow 中的浮点数精度(大约:截断尾数)降低到定义的完整范围内的任意位数。我不需要完全以降低精度编写代码(如 tf.float16),而是想出一系列操作来降低张量的精度,同时保留其原始类型(例如 tf.float32)。

例如,如果全范围是0到1,精度是8位,那么0.1234就会变成round(0.1234 * 256) / 256 = 0.125。这使用简单的舍入。

我还想进行统计舍入,其中在每个方向上舍入的概率与值与该值的距离成正比。例如,0.1234 * 256 = 31.5904,在 59% 的时间内向上舍入为 32/256,在 41% 的时间内向上舍入为 31/256。

附加问题:如何获取现有图形并对其进行修改以在每次卷积后添加舍入?

唯一棘手的部分是为舍入操作提供梯度。已经实现的 tf.round 没有实现渐变。但是您可以实现自己的舍入操作(统计或简单舍入都有效),如下所示:

哪里可以简单地使用:

grad(round(T)) = round(grad(T))

现在,一旦您有了个性化的 round 转移梯度的操作,您就可以简单地执行以下操作:

def reduce_precision(tensor, precision_bits=8):
    N = 2**precision_bits
    return round(N * tensor)/N

对于随机舍入,您可以创建一个简单的 numpy 函数,例如

def stochastic_round(x):
    r,f = np.modf(x)
    return r + np.random.binomial(1,r)

然后按

所示对其进行 tensoflow 化处理

在这里你可以将它的梯度操作定义为

def grad_stochastic_round(op, grad):
    return stochastic_round(grad)