我正在对tensorflow进行优化,其中矩阵乘法与手动计算相比给出了不同的值。这个差别只有小数点后6位,我知道它非常小,但是随着时间的推移,我得到的肘关节值会有很大的不同。
下面是一个小例子:
import tensorflow as tf
import numpy as np
a = np.array([[0.2751678 , 0.00671141, 0.39597315, 0.4966443 , 0.17449665,
0.00671141, 0.32214764, 0.02013423, 1. , 0.40939596,
0. , 0.9597315 , 0.4161074 , 0. , 0.2147651 ,
0.22147651, 0.5771812 , 0.70469797, 0.44966444, 0.36241612]],dtype=np.float32)
b = np.array([[2.6560298e-04, 0.0000000e+00, 7.9084152e-01, 8.2393251e-03,
0.0000000e+00, 9.8140877e-01, 6.5296537e-01, 2.6107374e-01,
1.2936005e-03, 5.2952105e-01, 2.2449312e-01, 9.9892569e-01,
8.4370503e-04, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00,
0.0000000e+00, 0.0000000e+00, 9.5679509e-03, 0.0000000e+00]],dtype=np.float32)
a_t = tf.constant(a)
b_t = tf.constant(b.T)
矩阵乘法
tf.matmul(a_t,b_t)
<tf.Tensor: shape=(1, 1), dtype=float32, numpy=array([[1.7209427]], dtype=float32)>
<<p>手动计算/strong>tf.reduce_sum(tf.transpose(a_t)*b_t)
<tf.Tensor: shape=(), dtype=float32, numpy=1.7209429>
这种差异的原因是什么?有解决办法吗?
您正在比较依赖浮点运算的不同算法的结果。在最后一位小数上得到不同的结果是完全正常的。事实上,这是最好的情况。有时差异甚至更大。
例如,您可以在以下代码中尝试n
的不同值:
from numpy import random as np_random
from numpy import matmul as np_matmul
from numpy import multiply as np_multiply
from numpy import transpose as np_transpose
from numpy import sum as np_sum
n = 10
for i in range(10000):
a = np_random.rand(1,n).astype('float32')
b = np_random.rand(n,1).astype('float32')
c = np_matmul(a,b)
d = np_sum(np_multiply(a,np_transpose(b)),axis=1)
e = c-d
if abs(e) > 0:
print("%.16f" % c)
print("%.16f" % d)
print("%e" % e)
break
无论如何,单精度浮点格式(float32)提供6到9位有效十进制数字的精度。如果你需要更高的精度,你仍然有双精度(float64)。
更多信息可以在《浮点算术:Python文档中的问题和限制》中找到。