2016-09-02 5 views
0

Я пытаюсь определить сложную пользовательскую функцию правдоподобия с помощью pymc3. Функция правдоподобия включает в себя много итераций, и поэтому я пытаюсь использовать метод сканирования anano для определения итерации непосредственно внутри theano. Вот очень упрощенный пример, иллюстрирующий вызов, с которым я сталкиваюсь. Функция (fake) правдоподобия, которую я пытаюсь определить, - это просто сумма двух случайных величин pymc3, p и theta. Конечно, я могу просто вернуть p + тета, но реальная функция правдоподобия, которую я пытаюсь написать, сложнее, и я считаю, что мне нужно использовать theano.scan, поскольку она включает в себя много итераций.использование функции использования функции pymc3

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 (р, тета)

потому, что р и тета являются типа pymc3.TransformedRV и что вход в функцию anano должен быть скалярным числом простого массива numpy. Однако у pymc3 TransformedRV нет никакого очевидного способа получить текущее значение самой случайной величины.

Можно ли определить функцию правдоподобия журнала, которая включает в себя использование функции anano, которая принимает в качестве входной переменной случайную переменную pymc3?

+0

Вы уже искали примеры в [репозитории PyMC3] (https://github.com/pymc-devs/pymc3/search?q=scan&type=Code&utf8=%E2%9C%93)? – aloctavodia

ответ

0

Проблема в том, что ваша th.function get_ll является скомпилированной функцией anano, которая принимает в качестве входных числовых массивов. Вместо этого pymc3 отправляет ему символическую переменную (тензор anano). Вот почему вы получаете ошибку.

Что касается вашего решения, вы правы, говоря, что просто возвращение p + theta - это путь. Если у вас есть сканирование и еще что-то в логе, вы должны вернуть интересующую переменную сканирования; здесь нет необходимости составлять здесь функцию анано. Например, если вы хотите добавить 1 к каждому элементу вектора (как непрактичным, например игрушечный), вы могли бы сделать:

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

При этом, если вам нужны градиенты, вам необходимо рассчитать the_sum переменную в anano Op и предоставить метод grad() вместе с ним (вы можете увидеть игрушечный пример этого ответа here). Если вам не нужны градиенты, вам может быть лучше делать все в python (или C, numba, cython, для производительности) и использовать декоратор as_op.