我正在处理tensorflow
中的小数字,这有时会导致数字不稳定。
我想提高结果的精确度,或者至少确定结果的界限。
以下代码显示了数字错误的具体示例(它输出nan
而不是0.0
,因为float64
不够精确,无法处理1+eps/2
):
import numpy as np
import tensorflow as tf
# setup
eps=np.finfo(np.float64).eps
v=eps/2
x_init=np.array([v,1.0,-1.0],dtype=np.float64)
x=tf.get_variable("x", initializer=tf.constant(x_init))
square=tf.reduce_sum(x)
root=tf.sqrt(square-v)
# run
with tf.Session() as session:
init = tf.global_variables_initializer()
session.run(init)
ret=session.run(root)
print(ret)
我假设没有办法增加tensorflow中值的精度。但也许可以设置舍入模式,就像在C ++中使用std::fesetround(FE_UPWARD)
一样?然后,我可以强制张量流总是向上舍入,这将确保我采用非负数的平方根。
我尝试了什么:我试图按照this question概述如何设置python / numpy的舍入模式。但是,这似乎不起作用,因为以下代码仍会打印nan
:
import numpy as np
import tensorflow as tf
import ctypes
FE_TONEAREST = 0x0000 # these constants may be system-specific
FE_DOWNWARD = 0x0400
FE_UPWARD = 0x0800
FE_TOWARDZERO = 0x0c00
libc = ctypes.CDLL('libm.so.6') # may need 'libc.dylib' on some systems
libc.fesetround(FE_UPWARD)
# setup
eps=np.finfo(np.float64).eps
v=eps/2
x_init=np.array([v,1.0,-1.0],dtype=np.float64)
x=tf.get_variable("x", initializer=tf.constant(x_init))
square=tf.reduce_sum(x)
root=tf.sqrt(square-v)
# run
with tf.Session() as session:
init = tf.global_variables_initializer()
session.run(init)
ret=session.run(root)
print(ret)
答案 0 :(得分:0)
替换
ret=session.run(root)
与
ret = tf.where(tf.is_nan(root), tf.zeros_like(root), root).eval()
参考tf.where