【问题标题】:pymc3 theano function usagepymc3 theano函数用法
【发布时间】:2016-09-02 17:19:11
【问题描述】:

我正在尝试使用 pymc3 定义一个复杂的自定义似然函数。似然函数涉及大量迭代,因此我尝试使用 theano 的 scan 方法直接在 theano 中定义迭代。这是一个非常简化的示例,说明了我面临的挑战。我试图定义的(假)似然函数只是两个 pymc3 随机变量 p 和 theta 的总和。当然,我可以简单地返回 p+theta,但我要编写的实际似然函数更复杂,而且我认为我需要使用 theano.scan,因为它涉及大量迭代。

import pymc3 as pm
from pymc3 import Model, Uniform, DensityDist
import theano.tensor as T
import theano
import numpy as np


### theano test
theano.config.compute_test_value = 'raise'

X = np.asarray([[1.0,2.0,3.0],[1.0,2.0,3.0]])
### pymc3 implementation
with Model() as bg_model:

    p = pm.Uniform('p', lower = 0, upper = 1)
    theta = pm.Uniform('theta', lower = 0, upper = .2)

    def logp(X):
        f = p+theta
        print("f",f)
        get_ll = theano.function(name='get_ll',inputs = [p, theta], outputs = f)
        print("p keys ",p.__dict__.keys())
        print("theta keys ",theta.__dict__.keys())
        print("p name ",p.name,"p.type ",p.type,"type(p)",type(p),"p.tag",p.tag)
        result=get_ll(p, theta)
        print("result",result)
        return result

    y = pm.DensityDist('y', logp, observed = X) # Nx4 y = f(f,x,tx,n | p, theta)

当我运行它时,我得到了错误:

TypeError: ('Bad input argument to theano function with name "get_ll"  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?')

我了解问题发生在一行中 结果=get_ll(p, theta)

因为 p 和 theta 是 pymc3.TransformedRV 类型,并且 theano 函数的输入需要是简单 numpy 数组的标量数。但是,pymc3 TransformedRV 似乎没有任何明显的方法来获取随机变量本身的当前值。

是否可以定义一个对数似然函数,该函数涉及使用将 pymc3 随机变量作为输入的 theano 函数?

【问题讨论】:

标签: theano pymc3


【解决方案1】:

问题是你的 th.function get_ll 是一个编译的 theano 函数,它以数字数组作为输入。相反,pymc3 向它发送一个符号变量(theano 张量)。这就是您收到错误的原因。

至于您的解决方案,您说得对,只返回 p+theta 是可行的方法。如果您的 logp 中有扫描等,那么您将返回感兴趣的扫描变量;这里不需要编译theano函数。例如,如果您想为向量的每个元素加 1(作为一个不切实际的玩具示例),您可以这样做:

def logp(X):
    the_sum, the_sum_upd = th.scan(lambda x: x+1, sequences=[X])
    return the_sum

话虽如此,如果你需要渐变,你需要在 theano Op 中计算你的 the_sum 变量并提供一个 grad() 方法(你可以在答案here 上看到一个玩具示例) .如果您不需要渐变,最好在 python(或 C、numba、cython,以提高性能)中执行所有操作并使用 as_op 装饰器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-22
    • 1970-01-01
    • 2015-10-24
    • 1970-01-01
    相关资源
    最近更新 更多