我一直在使用numpy.linalg.solve(A,B)
来求解线性方程。就我而言:A
约为10,000x10,000,而B
约为10,000x5。如果我使用以下方法随机初始化A
和B
:
A = numpy.random.rand(10000,10000)
B = numpy.random.rand(10000,5)
则计算时间为<3秒。但是,在需要求解该方程的程序中,计算时间始终约为14秒。这段代码是在一个循环中迭代的,因此加速将近5倍非常重要。 linalg.solve()
的解对于常数大小的数组应该不是大致恒定的吗?
两个实现都使用float64
。而且肯定有足够的内存(128 GB)。我尝试更新计算机上的blas库(Ubuntu 16.04-安装了conda的numpy),它显示了随机生成的数据对解决方案的改进,但不适用于程序中的数据。
如果有人在寻找有关该代码的更多详细信息,请访问[1]中.py文件的第27行。该程序正在注册点云。
任何想法或帮助将不胜感激。
[1] https://github.com/siavashk/pycpd/blob/master/pycpd/deformable_registration.py
编辑: 为了使它更具可重复性,我生成了一些代码来尝试将我带到可疑的np.linalg.solve()行:
import numpy as np
import time
def gaussian_kernel(Y, beta):
diff = Y[None,:,:] - Y[:,None,:]
diff = diff**2
diff = np.sum(diff, axis=2)
return np.exp(-diff / (2 * beta**2))
def initialize_sigma2(X, Y):
diff = X[None,:,:] - Y[:,None,:]
err = diff**2
return np.sum(err) / (X.shape[0] * Y.shape[0] * X.shape[1])
alpha = 0.1
beta = 3
X = np.random.rand(10000,5) * 100
Y = X + X*0.1
N, D = X.shape
M, _ = Y.shape
G = gaussian_kernel(Y, beta)
sigma2 = initialize_sigma2(X,Y)
TY = Y + np.random.rand(10000,5)
P = np.sum((X[None,:,:] - TY[:,None,:])**2, axis=2)
P /= np.sum(P,axis=0)
P1 = np.sum(P, axis=1)
Np = np.sum(P1)
A = np.dot(np.diag(P1), G) + alpha * sigma2 * np.eye(M)
B = np.dot(P, X) - np.dot(np.diag(P1), Y)
%time W = np.linalg.solve(A,B)
但是,此代码不会产生时间滞后。除了X和Y数组的实际创建之外,所有内容都与当前脚本中的所有内容相同。这些应该是在3D空间中彼此接近的两个点云-这就是为什么我基于另一个创建了一个点云的原因。