Function Theano PyMC3的自定义操作

Function Theano PyMC3的自定义操作,function,theano,pymc3,Function,Theano,Pymc3,我试图实现一个自定义操作,在该操作中出现了“no函数的输入参数错误”错误。这是代码。我理解的问题是:如何将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):

我试图实现一个自定义操作,在该操作中出现了“no函数的输入参数错误”错误。这是代码。我理解的问题是:如何将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)

我想我能回答你的问题

首先,您不应该使用
f=theano.函数([x1,x2,x3],trial_Op()(x1,x2,x3))
。定义后,
f
将数值作为参数。然而,在pymc3模型中,定义为
Normal
x1
x2
不是数字而是符号。所以它会抛出你刚刚遇到的错误。如果您熟悉本教程中介绍的
@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
,以满足
z=pm.Normal('z',mu=mu,sd=1.,observed=true_Data)
中的
mu
。样本数扩大到10000。结果图像显示:

但是,我不知道如何在自定义theano函数中定义
grad()
方法。也许以后有人或我可以解决它,以便在模型中启用NUTS采样方法:)