Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于python的图像最大似然分割算法_Python_Algorithm_Performance_Numpy - Fatal编程技术网

基于python的图像最大似然分割算法

基于python的图像最大似然分割算法,python,algorithm,performance,numpy,Python,Algorithm,Performance,Numpy,我想使用python中实现的最大似然算法执行图像分割。 类的平均向量和协方差矩阵是已知的,通过迭代图像(非常大…5100X7020),我们可以计算每个像素成为给定类一部分的概率 简单地用Python编写 import numpy as np from numpy.linalg import inv from numpy.linalg import det ... probImage1 = [] probImage1Vector = [] norm = 1.0 / (np.power((2*n

我想使用python中实现的最大似然算法执行图像分割。 类的平均向量和协方差矩阵是已知的,通过迭代图像(非常大…5100X7020),我们可以计算每个像素成为给定类一部分的概率

简单地用Python编写

import numpy as np
from numpy.linalg import inv
from numpy.linalg import det
...

probImage1 = []
probImage1Vector = []

norm = 1.0 / (np.power((2*np.pi), i/2) * np.sqrt(np.linalg.det(covMatrixClass1)))
covMatrixInverz = np.linalg.inv(covMatrixClass1)
for x in xrange(x_img):
    for y in xrange(y_img):
        X = realImage[x,y]
        pixelValueDifference = X - meanVectorClass1
        mult1 = np.multiply(-0.5,np.transpose(pixelValueDifference))
        mult2 = np.dot(covMatrixInverz,pixelValueDifference)
        multMult = np.dot(mult1,mult2)
        expo = np.exp(multMult)     
        probImage1Vector.append(np.multiply(norm,expo))
    probImage1.append(probImage1Vector)
    probImage1Vector = []
这个代码在大图像上执行时非常慢的问题。。。 向量减法和乘法之类的计算耗费大量时间,即使它们只是1X3个向量


你能给我一个提示如何加速这个代码吗?我将非常感激。对不起,如果我不清楚的话,我仍然是python的初学者

仔细看看:

mult1 = np.multiply(-0.5,np.transpose(pixelValueDifference))
mult2 = np.dot(covMatrixInverz,pixelValueDifference)
multMult = np.dot(mult1,mult2)
我们看到,这一行动基本上是:

A.T (d) C (d) A         # where `(d)` is the dot-product
这三个步骤可以很容易地用一个字符串表示,如下所示-

np.einsum('k,lk,l->',pA,covMatrixInverz,-0.5*pA)
在迭代器
i(=x)
j(=y)
中执行此操作,我们将得到一个完全矢量化的表达式-

np.einsum('ijk,lk,ijl->ij',pA,covMatrixInverz,-0.5*pA))
或者,我们可以使用
np.tensordot
-

mult2_vectorized = np.tensordot(pA, covMatrixInverz, axes=([2],[1]))
output = np.einsum('ijk,ijk->ij',-0.5*pA, mult2_vectorized)

标杆管理 将所有方法列为函数-

# Original code posted by OP to return array
def org_app(meanVectorClass1, realImage, covMatrixInverz, norm):
    probImage1 = []
    probImage1Vector = []
    x_img, y_img = realImage.shape[:2]
    for x in xrange(x_img):
        for y in xrange(y_img):
            X = realImage[x,y]
            pixelValueDifference = X - meanVectorClass1
            mult1 = np.multiply(-0.5,np.transpose(pixelValueDifference))
            mult2 = np.dot(covMatrixInverz,pixelValueDifference)
            multMult = np.dot(mult1,mult2)
            expo = np.exp(multMult)     
            probImage1Vector.append(np.multiply(norm,expo))
            probImage1.append(probImage1Vector)
            probImage1Vector = []
    return np.asarray(probImage1).reshape(x_img,y_img)
    
def vectorized(meanVectorClass1, realImage, covMatrixInverz, norm):
    pA = realImage - meanVectorClass1
    mult2_vectorized = np.tensordot(pA, covMatrixInverz, axes=([2],[1]))
    return np.exp(np.einsum('ijk,ijk->ij',-0.5*pA, mult2_vectorized))*norm
    
def vectorized2(meanVectorClass1, realImage, covMatrixInverz, norm):
    pA = realImage - meanVectorClass1
    return np.exp(np.einsum('ijk,lk,ijl->ij',pA,covMatrixInverz,-0.5*pA))*norm
时间安排-

In [19]: # Setup inputs
    ...: meanVectorClass1 = np.array([23.96000000, 58.159999, 61.5399])
    ...: 
    ...: covMatrixClass1 = np.array([[ 514.20040404,  461.68323232,  364.35515152],
    ...:        [ 461.68323232,  519.63070707,  446.48848485],
    ...:        [ 364.35515152,  446.48848485,  476.37212121]])
    ...: covMatrixInverz = np.linalg.inv(covMatrixClass1)
    ...: 
    ...: norm = 0.234 # Random float number
    ...: realImage = np.random.rand(1000,2000,3)
    ...: 

In [20]: out1 = org_app(meanVectorClass1, realImage, covMatrixInverz, norm )
    ...: out2 = vectorized(meanVectorClass1, realImage, covMatrixInverz, norm )
    ...: out3 = vectorized2(meanVectorClass1, realImage, covMatrixInverz, norm )
    ...: print np.allclose(out1, out2)
    ...: print np.allclose(out1, out3)
    ...: 
True
True

In [21]: %timeit org_app(meanVectorClass1, realImage, covMatrixInverz, norm )
1 loops, best of 3: 27.8 s per loop

In [22]: %timeit vectorized(meanVectorClass1, realImage, covMatrixInverz, norm )
1 loops, best of 3: 182 ms per loop

In [23]: %timeit vectorized2(meanVectorClass1, realImage, covMatrixInverz, norm )
1 loops, best of 3: 275 ms per loop
看起来完全矢量化的
einsum+tensordot
混合解决方案做得很好


为了进一步提高性能,还可以研究如何在大型阵列上加速指数计算。

作为第一步,我将消除不必要的函数调用,如转置、点和乘法。这些都是简单的计算,你应该在线进行。当您能够真正看到自己在做什么时,就可以更容易地理解性能问题,而不是将内容隐藏在函数中

这里的基本问题是,这似乎至少是一个四次复杂度的操作。您可能希望简单地乘以您在所有循环中执行的操作数。是5亿,20亿,3500亿?有多少


要控制性能,您需要了解您正在执行的指令数量。一台现代计算机每秒可以执行约10亿条指令,但如果涉及内存移动,速度可能会大大降低。

谢谢,非常感谢!我要试试看@user2955708运气好吗?请看下面我的评论@user2955708在您的实际用例中,
meanVectorClass1
realImage
covMatrixInverz
的形状是什么?请查找这些形状!('meanVectorClass1',(3L,)('covMatrixClass1',(3L,3L))('realImage',(7020L,5100L,3L))