tensorflow中的浮点精度

tensorflow中的浮点精度,tensorflow,precision,Tensorflow,Precision,在使用tensorflow(1.4版)时,调试代码时遇到了一些问题。Tensorflow存在严重的精度误差故障。我在这里展示了一个例子。有没有办法在tensorflow中处理此类问题 >>> a = [18.00146484] >>> b= [[18.00146484]] >>> c = [[[18.00146484]]] >>> d = [[18.00146484],[12.83231735]] >>>

在使用tensorflow(1.4版)时,调试代码时遇到了一些问题。Tensorflow存在严重的精度误差故障。我在这里展示了一个例子。有没有办法在tensorflow中处理此类问题

>>> a = [18.00146484]
>>> b= [[18.00146484]]
>>> c = [[[18.00146484]]]
>>> d = [[18.00146484],[12.83231735]]
>>> e = [[[18.00146484],[12.83231735]]]
>>> q = tf.nn.sigmoid()
KeyboardInterrupt
>>> q = tf.nn.sigmoid(a)
>>> w = tf.nn.sigmoid(b)
>>> e = tf.nn.sigmoid(c)
>>> r = tf.nn.sigmoid(d)
>>> z = [[[18.00146484],[12.83231735]]]
>>> t = tf.nn.sigmoid(z)
>>> init = tf.global_variables_initializer()
>>> sess = tf.Session()
2017-12-12 15:41:53.766287: I tensorflow/core/platform/cpu_feature_guard.cc:137] Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.1 SSE4.2 AVX
>>> qq,ww,ee,rr,tt = sess.run([q,w,e,r,t])
>>> qq,ww,ee,rr,tt
(array([ 1.], dtype=float32), array([[ 1.]], dtype=float32), array([[[ 1.]]], dtype=float32), array([[ 1.        ],
       [ 0.99999738]], dtype=float32), array([[[ 1.        ],
        [ 0.99999738]]], dtype=float32))
>>> qq
array([ 1.], dtype=float32)
>>> ww
array([[ 1.]], dtype=float32)
>>> ee
array([[[ 1.]]], dtype=float32)
>>> rrr
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'rrr' is not defined
>>> rr
array([[ 1.        ],
       [ 0.99999738]], dtype=float32)
>>> tt
array([[[ 1.        ],
        [ 0.99999738]]], dtype=float32)
>>> from math import exp
>>> a = 18.00146484
>>> b = (1/(1+exp(-a)))
>>> b
0.9999999847923136
>>> 
>a=[18.00146484]
>>>b=[[18.00146484]]
>>>c=[[18.00146484]]
>>>d=[[18.00146484],[12.83231735]]
>>>e=[[18.00146484],[12.83231735]]
>>>q=tf.nn.sigmoid()
键盘中断
>>>q=tf.nn.sigmoid(a)
>>>w=tf.nn.sigmoid(b)
>>>e=tf.nn.sigmoid(c)
>>>r=tf.nn.sigmoid(d)
>>>z=[[18.00146484],[12.83231735]]
>>>t=tf.nn.sigmoid(z)
>>>init=tf.global_variables_initializer()
>>>sess=tf.Session()
2017-12-12 15:41:53.766287:I tensorflow/core/platform/cpu_feature_guard.cc:137]您的cpu支持该tensorflow二进制文件未编译为使用的指令:SSE4.1 SSE4.2 AVX
>>>qq,ww,ee,rr,tt=sess.run([q,w,e,r,t])
>>>qq,ww,ee,rr,tt
(数组([1.],dtype=float32),数组([[1.]],dtype=float32),数组([[1.]]],dtype=float32),数组([[1.]],
[0.9999738]],dtype=float32),数组([[1.],
[0.99999738]],数据类型=float32)
>>>qq
数组([1.],dtype=float32)
>>>ww
数组([[1.]],dtype=float32)
>>>ee
数组([[1.]],dtype=float32)
>>>存款准备金率
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
NameError:未定义名称“rrr”
>>>rr
数组([[1.],
[0.9999738]],数据类型=float32)
>>>tt
数组([[1.],
[0.9999738]],数据类型=float32)
>>>从数学导入exp
>>>a=18.00146484
>>>b=(1/(1+exp(-a)))
>>>b
0.9999999847923136
>>> 

首先,看看你有多少次试验,也许你觉得tensorflow对相同的初始值给出了不同的结果。情况似乎并非如此
sigmoid(18.00146484)
始终为1,
sigmoid(12.83231735)
始终为0.999738

也许您觉得
sigmoid(18.00146484)
离1足够远,不应该四舍五入到1,但事实并非如此
sigmoid(18.00146484)=0.9999999998479231364…
()并且对于浮点32精度而言,此数字太接近1。对于这种精度级别,您确实需要使用double(
tf.float64
)。这里是一个简单的C++程序,它显示了浮点和双倍的最接近的可数数字1。
#include <limits>
#include <cmath>
#include <iostream>

int main() {
  typedef std::numeric_limits< double > dbl;
  typedef std::numeric_limits< double > flt;

  double sigmoid = 0.99999998479231364;

  float x = 1.0;
  double firstSmallerThanX = std::nextafter(x, 0.0f);
  std::cout.precision(flt::max_digits10);
  std::cout << std::fixed << firstSmallerThanX << std::endl;
  std::cout << "Sigmoid is bigger than firstSmallerThanX: " << (sigmoid > firstSmallerThanX) << std::endl;

  double y = 1.0;
  double firstSmallerThanY = std::nextafter(y, 0.0);
  std::cout.precision(dbl::max_digits10);
  std::cout << std::fixed << firstSmallerThanY << std::endl;
  std::cout << "Sigmoid is smaller than firstSmallerThanY: " << (sigmoid < firstSmallerThanY) << std::endl;

  return 0;
}

首先,看看你做了多少试验,也许你觉得tensorflow对相同的初始值给出了不同的结果。情况似乎并非如此
sigmoid(18.00146484)
始终为1,
sigmoid(12.83231735)
始终为0.999738

也许您觉得
sigmoid(18.00146484)
离1足够远,不应该四舍五入到1,但事实并非如此
sigmoid(18.00146484)=0.9999999998479231364…
()并且对于浮点32精度而言,此数字太接近1。对于这种精度级别,您确实需要使用double(
tf.float64
)。这里是一个简单的C++程序,它显示了浮点和双倍的最接近的可数数字1。
#include <limits>
#include <cmath>
#include <iostream>

int main() {
  typedef std::numeric_limits< double > dbl;
  typedef std::numeric_limits< double > flt;

  double sigmoid = 0.99999998479231364;

  float x = 1.0;
  double firstSmallerThanX = std::nextafter(x, 0.0f);
  std::cout.precision(flt::max_digits10);
  std::cout << std::fixed << firstSmallerThanX << std::endl;
  std::cout << "Sigmoid is bigger than firstSmallerThanX: " << (sigmoid > firstSmallerThanX) << std::endl;

  double y = 1.0;
  double firstSmallerThanY = std::nextafter(y, 0.0);
  std::cout.precision(dbl::max_digits10);
  std::cout << std::fixed << firstSmallerThanY << std::endl;
  std::cout << "Sigmoid is smaller than firstSmallerThanY: " << (sigmoid < firstSmallerThanY) << std::endl;

  return 0;
}

是的,我知道他们更近了。我还在底部的代码中显示了它们。但是,当您使用1e-5时,1e-8的学习率不是有助于运行数千个批次吗。。?。是的,谢谢你提供的信息。我不太明白你的问题。你能澄清一下吗?我只是觉得1e-8精度有时不重要吗?我个人在实践中没有遇到过浮动64的需要,除了在一些不稳定的训练案例中。这类案件还有其他问题,高度敏感只是其中的一个标志。最新NVIDIA卡的一个主要功能是对float16的本机支持,即使在许多情况下,这种分辨率通常也足够好。话虽如此,我当然可以想象一些科学模型,在这些模型中,最终的精度是必要的。谢谢@iga分享你的想法。是的,我知道它们更接近。我还在底部的代码中显示了它们。但是,当您使用1e-5时,1e-8的学习率不是有助于运行数千个批次吗。。?。是的,谢谢你提供的信息。我不太明白你的问题。你能澄清一下吗?我只是觉得1e-8精度有时不重要吗?我个人在实践中没有遇到过浮动64的需要,除了在一些不稳定的训练案例中。这类案件还有其他问题,高度敏感只是其中的一个标志。最新NVIDIA卡的一个主要功能是对float16的本机支持,即使在许多情况下,这种分辨率通常也足够好。话虽如此,我当然可以想象一些科学模型,在这些模型中,最终的精度是必要的。谢谢@iga分享你的想法。