2015-11-14 45 views
2

我是新来的向量化代码,我真的很高兴一切都快多少,但我无法从这段代码中获得高速...向量化数组的函数向量化

这里是住宅类...

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是灰度图像的N×N的矩阵):

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

其他数组涉及的维度是什么? 'self.mixing_coefficients','self.variances'和'self.means'? (“自我”来自哪里?) – user2357112

+0

我会编辑答案,以包括昏暗,但整体类是巨大的......我会尽力获得重要的东西 – bordeo

+0

在你的第二个版本中,你似乎只是使用图像矩阵中的左上角元素('self.image_matrix [0,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,你可以第一个版本快得多,但没有那么快的错误代码。所述log内的sum仅仅需要指定的相应轴:

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是大事情。

+0

不,这是在复制过程中的错误...我纠正了它......但我认为该轴将工作 - 谢谢你! – bordeo

+0

和...这是很好的了解矢量化...从改变轴的速度增加正是我所期待的。再次感谢 – bordeo