我几天前看到其他人的帖子:pymc3 likelihood math with non-theano function。即使我认为问题的核心是相同的,我想我会问一个更简单的例子:
在logp_wrap中,我对似然函数进行了一些定义。这取决于rv和观察。在这种情况下,我可以使用theano操作执行此操作,但是假设我希望此函数更复杂,因此我无法使用theano。
当我尝试根据RV和观察来定义可能性时,问题出现了。从我所看到的情况来看,如果我在'logp_wrap'中指定所有内容作为theano操作,这种格式就可以工作。
我一直在寻找解决方案,但是没有发现任何可以完全解决这个问题的方法。
我尝试这样做的问题实际上是logp_函数被正确装饰,但是logp_wrap函数只是为它的输入正确装饰,而不是它的输出,所以我得到了错误
TypeError: 'TensorVariable' object is not callable
。
如果有人有解决方案会很棒 - 不要以为我是唯一有这个问题的人。
在没有@as_op代码的情况下工作(并在函数定义中使用相同的函数)的theano版本在这里:https://pymc-devs.github.io/pymc3/notebooks/lda-advi-aevb.html?highlight=densitydist(特别是部分:“LDA文档的对数可能性”和“ LDA模型部分“)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
"""
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import pymc3 as pm
from theano import as_op
import theano.tensor as T
from scipy.stats import norm
#Some data that we observed
g_observed = [0.0, 1.0, 2.0, 3.0]
#Define a function to calculate the logp without using theano
#This as_op is where the problem is - the input is an rv but the output is a
#function.
@as_op(itypes=[T.dscalar],otypes=[T.dscalar])
def logp_wrap(rv):
#We are not using theano so we wrap the function.
@as_op(itypes=[T.dvector],otypes=[T.dscalar])
def logp_(ob):
#Some made up likelihood -
#The key here is that lp depends on the rv input and the observations
lp = np.log(norm.pdf(rv + ob))
return lp
return logp_
hb1_model = pm.Model()
with hb1_model:
I_mean = pm.Normal('I_mean', mu=0.1, sd=0.05)
xs = pm.DensityDist('x', logp_wrap(I_mean),observed = g_observed)
with hb1_model:
step = pm.Metropolis()
trace = pm.sample(1000, step)