如何用张量流准确地四舍五入

Posted

技术标签:

【中文标题】如何用张量流准确地四舍五入【英文标题】:How to accurately round half up with tensorflow 【发布时间】:2019-02-21 21:02:48 【问题描述】:

我正在尝试将一些基于 C++ 的代码复制到 Tensorflow 的 Python API 中,但我遇到了一些浮点不准确问题,尽管我已经找到了其中一个问题。

通常,Tensorflow 似乎以round half down 的方式对小数进行四舍五入,这意味着如果我们有一个整数的小数正好等于0.5,则该小数的整数部分将向下舍入为零:

>>> import tensorflow as tf
>>> tf.Session().run(tf.math.round(2.5))
2.0

然而,我遇到的许多命令式编程语言都以round half up 的方式进行舍入。其中一些编程语言是C++ 和Python。

事实上,考虑到 Tensorflow 主要是用 C++、Python 和 Cuda C++ 编写的,他们在 API 中使用rounding half down 方法来实现他们的函数似乎是一个奇怪的约定。


问题

是否有任何巧妙的方法来实现使用rounding half up 方法而不是rounding half down 的舍入函数?

我可以实现的最简单的函数使用tf.floormod 方法:

>>> def classical_round(x): return tf.cond(tf.math.equal(tf.floormod(x, 1), tf.constant(0.5)), lambda: tf.math.ceil(x), lambda: tf.math.round(x))
...
>>> tf.Session().run(classical_round(4.5))
5.0
>>> tf.Session().run(classical_round(4.49))
4.0
>>> tf.Session().run(classical_round(4.49999999999999))
5.0
>>> tf.Session().run(classical_round(3.2))
3.0

这种方法足够准确吗?或者可以通过使用其他张量流操作来完成类似的事情吗?

研究

我只能找到与我的问题相关的this Github issue,我想他们最终添加了tf.math.rint,我在这个问题中找不到位置。

谢谢!

【问题讨论】:

en.cppreference.com/w/cpp/numeric/math/round @JesperJuhl 感谢您的参考,但我正在寻找与普通 C++ 轮函数等效的 tensorflow,因为我试图复制的库已经编译了 C++ 代码(我想避免修改库)。 C++" 很少是“将小数四舍五入”,而是四舍五入到最接近,与偶数相等。不要假设典型的 C++ FP 舍入模式为 round()。IOWs,目标“使用向上舍入方法而不是向下舍入来实现舍入函数的巧妙方法”可能会被误导,因为目标更可能应该是“使用 C++ 中的舍入实现舍入函数的简洁方法”。“我'm have little floating point inaccuracy issues'比关于舍入模式的结论更复杂。发布代码和数据示例。minimal reproducible example ShellRox 您希望rounding half up(-1.5) 达到-1 还是希望rounding half way away from zero(-1.5) 达到-2? @chux 我对迟到的回复表示歉意,我说的是rounding half up,它在***en.wikipedia.org/wiki/Rounding#Round_half_up 上有定义。如果小数的小数部分正好等于 0.5,我上面介绍的代码只是将四舍五入(ceil 除法),否则它执行经典的四舍五入(如果小于 0.5,则为 floor,如果大于 0.5,则为 ceil)。 【参考方案1】:

称银行家对 c# 中发生的同样事情也没有错。你可以试试这样的:

def classical_round(x):
    return tf.math.floor(x+0.5)

sess.run(classical_round(2.5)) #3.0

更多信息在这里: https://en.wikipedia.org/wiki/Rounding#Round_half_to_even

【讨论】:

当添加 x+0.5 本身在调用函数之前会导致舍入时,此方法无法根据各种 double 进行舍入。候选包括 [2^53... 2^54] 范围内的整数值,并且 FP 值刚好小于 +/- 0,5, 1.0。

以上是关于如何用张量流准确地四舍五入的主要内容,如果未能解决你的问题,请参考以下文章

如何用 Python 四舍五入到小数点后两位?

js四舍五入问题 不准确

如何在 Torch 的 GPU 上将张量的元素限制/舍入到小数点后 4 位?

解决javascript四舍五入不准确

如何用MATLAB使矩阵中的元素保留两位小数

Linux查看准确内存容量命令