我是代码矢量化的新手,我对所有内容的速度有多快感到非常兴奋,但我无法从这段代码中获得高速...
这是住房类......
class GaussianMixtureModel:
def __init__(self, image_matrix, num_components, means=None):
self.image_matrix = image_matrix
self.num_components = num_components
if(means is None):
self.means = np.zeros(num_components)
else:
self.means = np.array(means)
self.variances = np.zeros(num_components)
self.mixing_coefficients = np.zeros(num_components)
以下是我迄今为止所做的工作:
def likelihood(self):
def g2(x):
#N =~ 5
#self.mixing_coefficients = 1D, N items
#self.variances = 1D, N items
#self.means = 1D, N items
mc = self.mixing_coefficients[:,None,None]
std = self.variances[:,None,None] ** 0.5
var = self.variances[:,None,None]
mean = self.means[:,None,None]
return np.log((mc*(1.0/(std*np.sqrt(2.0*np.pi)))*(np.exp(-((x-mean)**2.0)/(2.0*var)))).sum())
f = np.vectorize(g2)
#self.image_matrix =~ 400*700 2D matrix
log_likelihood = (f(self.image_matrix)).sum()
return log_likelihood
以下是我得到的结果很奇怪(注意self.image_matrix
是灰度图像的nxn矩阵):
def likelihood(self):
def g2():
#N =~ 5
#self.mixing_coefficients = 1D, N items
#self.variances = 1D, N items
#self.means = 1D, N items
#self.image_matrix = 1D, 400x700 2D matrix
mc = self.mixing_coefficients[:,None,None]
std = self.variances[:,None,None] ** 0.5
var = self.variances[:,None,None]
mean = self.means[:,None,None]
return np.log((mc*(1.0/(std*np.sqrt(2.0*np.pi)))*(np.exp(-((self.image_matrix-mean)**2.0)/(2.0*var)))).sum())
log_likelihood = (g2()).sum()
return log_likelihood
然而,与第一个版本相比,第二个版本真的快(这需要将近10秒......而且速度在这里非常重要,因为这是收敛算法的一部分)
有没有办法复制第一个版本的结果和第二个版本的速度? (我真的不熟悉矢量化以了解为什么第二个版本不起作用)
答案 0 :(得分:2)
第二个版本速度非常快,因为它只使用self.image_matrix
的第一个单元格:
return np.log((mc*(1.0/(std*np.sqrt(2.0*np.pi)))*(np.exp(-((self.image_matrix[0,0]-mean)**2.0)/(2.0*var)))).sum())
# ^^^^^
这也是它完全错误的原因。它根本不是self.image_matrix
上的矢量化计算。不要试图将其运行时作为比较点;你总是可以比正确的代码更快地制作错误的代码。
通过消除np.vectorize
的使用,您可以使第一个版本更快,但不如错误的代码快。 sum
内的log
只需要指定适当的轴:
def likelihood(self):
def f(x):
mc = self.mixing_coefficients[:,None,None]
std = self.variances[:,None,None] ** 0.5
var = self.variances[:,None,None]
mean = self.means[:,None,None]
return np.log((mc*(1.0/(std*np.sqrt(2.0*np.pi)))*(np.exp(-((x-mean)**2.0)/(2.0*var)))).sum(axis=0))
log_likelihood = (f(self.image_matrix)).sum()
这可以通过几种方式进一步简化和优化。例如,可以消除嵌套函数,乘以1.0/whatever
比除whatever
要慢,但消除np.vectorize
是最重要的。