对于我正在编写的某些PyMC3代码,我定义了一个DensityDist,并使用自定义函数来评估点x处的概率密度。
此自定义函数是用Cython编写的,因为它可以将速度提高100倍。但是,当我尝试运行代码时,我看到了令人恐惧的...
TypeError: must be real number, not TensorVariable
我制作了该功能的非Cython版本(可以很好地与PyMC3配合使用),但它大约是Cython版本的1/100。
简而言之,我希望函数的运行速度不低于Cython速度的50%。完全不能接受以Cython速度的1%运行。
我已经在Google上搜索了“带有pymc3的cython”,但发现有用的材料很少。我不确定如何实现这种速度提升。请帮忙。
以下是相关功能的Cython实现:
cdef double singlePrecompVcdfe(double x, double h, int n, double *data_array, double *lambdaArray):
cdef double tmp
cdef double sumTerm = 0.
for k in range(n):
x_k = data_array[k]
tmp = (x - x_k) / (h * lambdaArray[k])
sumTerm += 0.5 * erfc(-tmp * M_SQRT1_2);
# Compute F_Hat
cdef double F_Hat = (1. / (<double>n)) * sumTerm
# Return F_Hat
return(F_Hat)
这是该函数的Python实现:
def singlePrecompVcdfe(self, x, h, data_list, lambdaList):
n = len(data_list)
sumTerm = 0.
for k in range(n):
x_k = data_list[k]
tmp = (x - x_k) / (h * lambdaList[k])
# erfc = 1 - erf
sumTerm += 0.5 * (1. - pymc3.math.erf(-tmp * self.sqrt1_2))
# Compute F_Hat
F_Hat = (1. / float(n)) * sumTerm
# Return F_Hat
return(F_Hat)
该函数的用法如下...
def helperFunc(X):
h = 0.5
data = <DATA>
lambdas = <LAMBDAS>
return(myObj.singlePrecompVcdfe(X, h, data, lambdas))
with pymc3.Model() as model:
# Create likelihood
like = pymc3.DensityDist('X', helperFunc, shape=1)
# Make samples
step = pymc3.NUTS()
trace = pymc3.sample(2000, tune=1000, init=None, step=step, cores=2)
以下是某些情况下的错误:
File "vkde.pyx", line 635, in vkde.vkdEstimator.VCDFE
return(singlePrecompVcdfe(x, self.__h, self.__n, myCopy(self.__data_list),
TypeError: must be real number, not TensorVariable
如果不清楚,我正在运行Python3(3.7.2)。