我有以下简单代码:
a = tf.constant([7, 6, 7, 4, 5, 4], dtype=tf.float32)
e = tf.constant(5.2, dtype = tf.float32)
with tf.Session() as sess:
print(sess.run(a - e))
此减法的结果是
[ 1.8000002 0.8000002 1.8000002 -1.1999998 -0.19999981 -1.1999998 ]
代替
[ 1.8 0.8 1.8 -1.2 -0.2 -1.2 ]
那很奇怪。可能是什么问题?
答案 0 :(得分:0)
以一种简单的方式可以证明5.2没有终结的二进制表示形式。因此,如果您知道1/3
用十进制表示,那么请想象一下5.2
中的相同情况。永远记住以下几点:
如果和,则十进制数将具有终止的二进制表示形式 仅当以其最简单的分数形式写成的小数 分母,是
2
的幂。
如果想到5.2
,则它是52/10
或26/5
,而5
不是2
的幂。现在在float32(双精度算术)中,只有32位表示它。因此,当然,它最终代表了一个非常接近5.2
但不完全相同的数字。
因此,TensorFlow在计算减法时会给您带来细微的差别。
但是,如果您将数字转换为tf.float64
,尽管表示形式仍然不正确,但您会发现错误消失了。这只是Print
函数的真正努力,使您的生活更简单。它没有向您显示完整视图。这是因为在64-bit
算术中,真实值和内部表示的值之间的差远小于32-bit
算术。因此,Print
函数会看到连续的零流,它会被截断。
但是,如果使用Print('%.60f'% <YOUR RESULT>)
之类的内容,您会看到
with tf.Session() as sess:
...: for i in range(10):
...: c = sess.run(a - e)
...:
2018-09-09 18:50:42.209402: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1471] Adding visible gpu devices: 0
2018-09-09 18:50:42.209464: I tensorflow/core/common_runtime/gpu/gpu_device.cc:952] Device interconnect StreamExecutor with strength 1 edge matrix:
2018-09-09 18:50:42.209475: I tensorflow/core/common_runtime/gpu/gpu_device.cc:958] 0
2018-09-09 18:50:42.209484: I tensorflow/core/common_runtime/gpu/gpu_device.cc:971] 0: N
2018-09-09 18:50:42.209635: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1084] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 10397 MB memory) -> physical GPU (device: 0, name: GeForce GTX 1080 Ti, pci bus id: 0000:02:00.0, compute capability: 6.1)
for item in c:
...: print('%.60f' % item)
...:
1.780000000000000248689957516035065054893493652343750000000000
0.780000000000000248689957516035065054893493652343750000000000
1.780000000000000248689957516035065054893493652343750000000000
-1.219999999999999751310042483964934945106506347656250000000000
-0.219999999999999751310042483964934945106506347656250000000000
-1.219999999999999751310042483964934945106506347656250000000000