使用Theano与PyMC3共享变量

时间:2015-05-24 17:21:23

标签: python theano pymc3

我的可观察数据非常大,其似然函数非常复杂,因此我在GPU中加载所有可观察数据,然后使用theano函数根据我想要估算的参数来获取它们的可能性。

def create_function(data_values):
    X = theano.shared(np.asarray(data_values,
                dtype=theano.config.floatX),
                 borrow=borrow)
    def logp(B,sigma_r,sigma_u):
        P = complexTheanoFunction(X)        
        return T.sum(T.log(P))
    return logp

with mc.Model() as model:
    data_values = load_data()
    logp = create_function(data_values)

    sigma_r = mc.Uniform('sigma_r',0,1,testval=0.5,dtype='float32')
    sigma_u = mc.Uniform('sigma_u',0,1,testval=0.5,dtype='float32')
    B = mc.Uniform('B',0,1,testval=np.array([0.5,0.5,.5,.5],dtype=np.float32),shape=4,dtype='float32')

    get_logp = theano.function(
        inputs = [B,sigma_r,sigma_u],
        outputs = logp,
    )

    obs = mc.DensityDist('observations',get_logp)    
    start = mc.find_MAP()
    step = mc.NUTS(state=start)

    trace = mc.sample(5000,step,start=start)
    mc.traceplot(trace, )

我不知道这是否是正确的做法。我收到了错误:

  obs = mc.DensityDist('observations',get_logp)    
  File "/usr/local/lib/python2.7/dist-packages/pymc3/distributions/distribution.py", line 19, in __new__
    return model.Var(name, dist, data)
  File "/usr/local/lib/python2.7/dist-packages/pymc3/model.py", line 143, in Var
    var = FreeRV(name=name, distribution=dist, model=self)
  File "/usr/local/lib/python2.7/dist-packages/pymc3/model.py", line 322, in __init__
    self.logp_elemwiset = distribution.logp(self)
  File "/usr/local/lib/python2.7/dist-packages/theano/compile/function_module.py", line 517, in __call__
    allow_downcast=s.allow_downcast)
  File "/usr/local/lib/python2.7/dist-packages/theano/tensor/type.py", line 77, in filter
    'Expected an array-like object, but found a Variable: '
TypeError: ('Bad input argument to theano function with name "/home/joao/Dropbox/physological/Juggler/SaliencyExp/mc3tryExp.py:64"  at index 0(0-based)', 'Expected an array-like object, but found a Variable: maybe you are trying to call a function on a (possibly shared) variable instead of a numeric array?')

---------- // ----------- 我试图用John Salvatier给出的例子做一个简单的例子: 附:这个模型没有任何意义..我只想弄清楚Theano如何与pymc3一起工作

with mc.Model() as model:
    data_values = np.random.rand(200,3)
    X = theano.shared(np.asarray(data_values,
        dtype=theano.config.floatX),
         borrow=True)

    B = mc.Uniform('B',0,1,testval=np.array([.5,.5,.5],dtype=np.float32),shape=3,dtype='float32')

    def logp(x,B):
        P = x.dot(B)
        P = P/T.sum(P)        
        return T.sum(T.log(P))

    obs = mc.DensityDist('observations',logp, observed=X)    
    start = mc.find_MAP()
    step = mc.NUTS(state=start)

我收到了这个错误:

Traceback (most recent call last):
  File "/home/joao/test.py.py", line 27, in <module>
    obs = mc.DensityDist('observations',logp, observed=X)    
  File "/usr/local/lib/python2.7/dist-packages/pymc3/distributions/distribution.py", line 19, in __new__
    return model.Var(name, dist, data)
  File "/usr/local/lib/python2.7/dist-packages/pymc3/model.py", line 146, in Var
    var = ObservedRV(name=name, data=data, distribution=dist, model=self)
  File "/usr/local/lib/python2.7/dist-packages/pymc3/model.py", line 348, in __init__
    args = [t.constant(args[0], name=name)]
  File "/usr/local/lib/python2.7/dist-packages/theano/tensor/basic.py", line 416, in constant
    dtype=dtype)
  File "/usr/local/lib/python2.7/dist-packages/theano/tensor/basic.py", line 411, in constant_or_value
    raise TypeError("Could not convert %s to TensorType" % x, type(x))
TypeError: ('Could not convert <CudaNdarrayType(float32, matrix)> to TensorType', <class 'theano.sandbox.cuda.var.CudaNdarraySharedVariable'>)

1 个答案:

答案 0 :(得分:2)

您得到的错误是因为您正在将logp函数编译为get_logp,然后将其传递给DensityDist,而DensityDist实际上需要一个返回theano变量的函数,而不是编译的theano函数。

我想你想要这样的东西:

with mc.Model() as model:
    data_values = load_data()
    X = theano.shared(np.asarray(data_values,
        dtype=theano.config.floatX),
         borrow=borrow)

    sigma_r = mc.Uniform('sigma_r',0,1,testval=0.5,dtype='float32')
    sigma_u = mc.Uniform('sigma_u',0,1,testval=0.5,dtype='float32')
    B = mc.Uniform('B',0,1,testval=np.array([0.5,0.5,.5,.5],dtype=np.float32),shape=4,dtype='float32')

    def logp(x):
        #need to pass B sigma r/u to the function
        P = complexTheanoFunction(x, B, sigma_r, sigma_u)        
        return T.sum(T.log(P))

    obs = mc.DensityDist('observations',logp, observed=X)    
    start = mc.find_MAP()
    step = mc.NUTS(state=start)