我试图实现一个自定义Op,我得到了“theano function的错误输入参数”错误。这是代码。我理解的问题是:如何将PyMC3变量转换为可理解的类型?
import numpy as np
import theano
import theano.tensor as t
from theano import config
config.compute_test_value = 'off'
#true_Data = [1,2]
#values=[]
class trial_Op(theano.Op):
__props__ = ()
itypes = [t.dmatrix, t.dmatrix, t.dmatrix]
otypes = [t.dmatrix]
def perform(self,node,inputs,output_storage):
x0 = inputs[0]
x1 = inputs[1]
x2 = inputs[2]
z = output_storage[0]
z[0] = np.add(x0,x1)
z[0] = np.add(z[0],x2)
def grad(self,inputs,output_grads):
return output_grads[0]
Trial_Op = trial_Op()
x1 = t.dmatrix()
x2 = t.dmatrix()
x3 = t.dmatrix()
f = theano.function( [x1,x2,x3], trial_Op()(x1,x2,x3) )
# the Op works for the
#inp1 = np.random.rand(3,1) # a 2d matrix
#inp2 = np.random.rand(3,1) # a 2d matrix
#inp3 = np.array([[-40]]) # a constant
#print("Op application gives = ", f(inp1,inp2,inp3))
import pymc3 as pm
true_Data = [[1]]
with pm.Model() as model:
x1 = pm.Normal('x1', mu = 0, sd = 0.1)
x2 = pm.Normal('x2', mu = 3, sd = 0.5)
x3 = np.asarray([[4]], dtype='float64')
# x1 = x1.reshape(1,1)
# x2 = x2.reshape(1,1)
sum_of_x1_x2_x3 = f(x1,x2,x3)
z = pm.Normal('z', sum_of_x1_x2_x3, observed = true_Data)
start = {'x1':[[0.1]], 'x2':[[0.1]]}
step = pm.Metropolis()
trace = pm.sample(100, step, start)
pm.traceplot(trace)
答案 0 :(得分:0)
我想我可以回答你的问题。
首先,您不应该使用f = theano.function( [x1,x2,x3], trial_Op()(x1,x2,x3) )
。定义后,f
将数值作为参数。但是,在pymc3模型中,x1
和x2
定义为Normal
不是数字而是符号。所以它会抛出你刚遇到的错误。如果您熟悉本教程中记录的 @as_op
方法,则解决方案很简单:将sum_of_x1_x2_x3 = f(x1,x2,x3)
更改为sum_of_x1_x2_x3 = Trial_Op(x1,x2,x3)
;
其次,在您的代码中,似乎不需要dmatrix
类型。所以我修改了以下代码:
N = 20 #data array length
class Trial_Op(theano.Op):
__props__ = ()
itypes = [t.dscalar, t.dscalar]
otypes = [t.dvector] #if the data has multiple values i.e. data array
def perform(self,node,inputs,output_storage):
x0 = inputs[0]
x1 = inputs[1]
f = np.add(x0,x1)
out = np.empty(N)
out[:] = f
z = output_storage[0]
z[0] = out
trial_Op = Trial_Op()
import pymc3 as pm
true_Data = np.random.normal(2,1,N)
with pm.Model() as model:
x1 = pm.Normal('x1', mu = 0, sd = 0.1)
x2 = pm.Normal('x2', mu = 3, sd = 0.5)
mu = trial_Op(x1, x2)
z = pm.Normal('z', mu = mu, sd = 1., observed = true_Data)
step = pm.Metropolis()
trace = pm.sample(10000, step)
pm.traceplot(trace)
请注意,在自定义函数中,otypes
为dvector
以满足mu
中的z = pm.Normal('z', mu = mu, sd = 1., observed = true_Data)
。样本编号扩展为10000.结果图像显示:
但是,我不知道如何在自定义theano函数中定义 grad()
方法。也许以后某人或我可以解决它以在模型中启用NUTS采样方法:)。