NumPy在执行点乘时的精度问题

6
我正在使用Theano / NumPy做一些深度学习的事情。我发现一个非常令人烦恼的问题。我有一个权重矩阵A(应该是50 * 2048),和一个特征向量b(2048维)。
A是用以下方式初始化的:
self.alpha = np.random.random((50, 2048)).astype(np.float32) * 2 - 1.0

b是一个来自Theano的2048维numpy.ndarrary。
问题是:
X = numpy.dot(A, b)
Y = [numpy.dot(A[i], b) for i in xrange(50)]

X和Y的某些行并不完全相等。我进行了比较,发现差异在1e-6到1e-7之间。

目前我更喜欢使用第二个计算点积,因为似乎它可以学习更好的权重。但是第一个要快得多。所以我想知道为什么会有这么大的差异。是由于dot(matrix, vector)和dot(vector, vector)的不同实现引起的吗?非常感谢!

--编辑 正如uhoh提到的那样,以下是可以重现此问题的代码。

import numpy as np

test_time = 1000
vector_size = 100
matrix_size = (100, 100)

for i in xrange(test_time):
    a = np.random.random(matrix_size).astype(np.float32) * 2 - 1.0
    b = np.random.random(vector_size).astype(np.float32)
    x = np.dot(a, b)
    y = [np.dot(a[i], b) for i in xrange(a.shape[0])]
    for k in xrange(len(y)):
        epsilon = x[k] - y[k]
        if abs(epsilon) > 1e-7:
            print('Diff: {0}\t{1}\t{2}'.format(x[k], y[k], epsilon))

我可以使用任何数组大小复制该问题... - Julien
1
@uhoh 我发布了能够重现问题的代码。 - magic282
3
非随机示例:x = np.ones((2, 100), dtype=np.float32)/100; y = np.ones(100, dtype=np.float32)。比较np.dot(x, y)[0]np.dot(x[0], y) - Warren Weckesser
1
显然,dot函数在第一个参数是1D或2D时会遵循不同的代码路径,而不同的路径会导致略微不同的数值误差。 - Warren Weckesser
3
如果你正在进行“深度学习”的工作,那么请不要再担心这个级别的错误了。 - eickenberg
显示剩余6条评论
1个回答

2
通常,性能和精度之间存在权衡。您可能需要在其中一个方面进行补偿。尽管我个人认为在大多数应用程序中,0.0000001的差异并不重要。如果您寻求更高的精度,最好使用float64,但请注意,float64操作在GPU上非常缓慢,特别是在NVIDIA 9xx系列GPU上。
我可以指出,所提到的问题似乎也取决于您的硬件设置,因为在我的机器上我没有遇到这样的问题。
您还可以使用np.allclose(x, y)来查看差异是否明显。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接