2016-09-02 3 views
0

나는 복잡한 맞춤형 확률 함수를 pymc3을 사용하여 정의하려고합니다. 우도 함수는 많은 반복을 필요로하므로 theano의 scan 메소드를 사용하여 theano 내에서 직접 반복을 정의하려고합니다. 여기 내가 직면하고있는 도전을 보여주는 매우 단순한 예가 있습니다. 내가 정의하려고하는 가짜 확률 함수는 단순히 두 개의 pymc3 확률 변수 p와 theta의 합입니다. 물론, 간단히 p + theta를 반환 할 수는 있지만 실제로 쓰려고하는 함수는 더 복잡합니다. itano.scan은 반복이 많이 필요하므로 사용해야합니다.pymc3 theano 함수 사용법

나는 문제가 라인 결과에서 발생하는 이해
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, 세타)

p와 세타이기 때문에 :이 프로그램을 실행할 때

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) 

, 나는 오류 pymc3.TransformedRV 유형을 사용하고 theano 함수에 대한 입력은 간단한 numpy 배열의 스칼라 숫자 여야합니다. 그러나, pymc3 TransformedRV는 랜덤 변수 자체의 현재 값을 얻는 분명한 방법이없는 것처럼 보입니다.

입력으로 pymc3 확률 변수를 취하는 theano 함수를 사용하는 로그 우도 함수를 정의 할 수 있습니까?

+0

이미 [PyMC3 저장소] (https://github.com/pymc-devs/pymc3/search?q=scan&type=Code&utf8=%E2%9C%93)에서 예제를 검색 했습니까? – aloctavodia

답변

0

문제점은 th.function get_ll이 숫자 배열을 입력으로받는 컴파일 된 theano 함수라는 점입니다. 대신, pymc3은 기호 변수 (theano tensor)를 보내고 있습니다. 그래서 오류가 발생합니다.

당신의 솔루션에 관해서는 p + 세타를 반환하는 것이 최선의 방법이라고 말하면됩니다. 당신이 당신의 logp에서 스캔과 그 밖의 것들을 가지고 있다면, 관심있는 스캔 변수를 반환 할 것입니다; 여기서 theano 함수를 컴파일 할 필요는 없습니다. 당신이 (비실용적 장난감 예와 같은) 벡터의 각 요소에 1을 추가하고 싶었 예를 들어, 당신은 할 것 :

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

즉 말했다되고, 당신은 그라디언트를 필요로하는 경우, 당신은 당신의 the_sum을 계산해야 변수와 함께 grad() 메서드를 제공합니다 (대답은 here에 장난감 예제가 있습니다). 그래디언트가 필요 없다면, 파이썬 (또는 C, numba, cython, 성능 향상)을 사용하고 as_op 데코레이터를 사용하는 것이 좋습니다.

관련 문제