【发布时间】:2016-08-18 17:31:16
【问题描述】:
我正在做一些 pymc3 并且我想创建自定义随机指标,但是似乎没有很多关于它是如何完成的文档。我知道如何使用as_op way,但显然这使得无法使用 NUTS 采样器,在这种情况下,我看不出 pymc3 优于 pymc。
教程中提到可以通过继承theano.Op来完成。但是谁能告诉我这将如何工作(我仍然开始使用theano)?我有两个要定义的随机指标。
第一个应该更简单,它是一个 N 维向量 F,只有常量父变量:
with myModel:
F = DensityDist('F', lambda value: pymc.skew_normal_like(value, F_mu_array, F_std_array, F_a_array), shape = N)
我想要一个偏态正态分布,在pymc3中似乎还没有实现,我只是导入了pymc2版本。不幸的是,F_mu_array, F_std_array, F_a_array and F 都是 N 维向量,而 lambda 的东西似乎不适用于 N 维列表value。
首先,有没有办法让 lambda 输入一个 N 维数组?如果没有,我想我需要直接定义 Stochastic F,这就是我认为我需要 theano.Op 使其工作的地方。
第二个例子是其他随机指标的一个更复杂的函数。这里我想如何定义它(目前不正确):
with myModel:
ln2_var = Uniform('ln2_var', lower=-10, upper=4)
sigma = Deterministic('sigma', exp(0.5*ln2_var))
A = Uniform('A', lower=-10, upper=10, shape=5)
C = Uniform('C', lower=0.0, upper=2.0, shape=5)
sw = Normal('sw', mu=5.5, sd=0.5, shape=5)
# F from before
F = DensityDist('F', lambda value: skew_normal_like(value, F_mu_array, F_std_array, F_a_array), shape = N)
M = Normal('M', mu=M_obs_array, sd=M_stdev, shape=N)
# Radius forward-model (THIS IS THE STOCHASTIC IN QUESTION)
R = Normal('R', mu = R_forward(F, M, A, C, sw, N), sd=sigma, shape=N)
函数R_forward(F,M,A,C,sw,N)被天真地定义为:
from theano.tensor import lt, le, eq, gt, ge
def R_forward(Flux, Mass, A, C, sw, num):
for i in range(num):
if lt(Mass[i], 0.2):
if lt(Flux[i], sw[0]):
muR = C[0]
else:
muR = A[0]*log10(Flux[i]) + C[0] - A[0]*log10(sw[0])
elif (le(0.2, Mass[i]) or le(Mass[i], 0.5)):
if lt(Flux[i], sw[1]):
muR = C[1]
else:
muR = A[1]*log10(Flux[i]) + C[1] - A[1]*log10(sw[1])
elif (le(0.5, Mass[i]) or le(Mass[i], 1.5)):
if lt(Flux[i], sw[2]):
muR = C[2]
else:
muR = A[2]*log10(Flux[i]) + C[2] - A[2]*log10(sw[2])
elif (le(1.5, Mass[i]) or le(Mass[i], 3.5)):
if lt(Flux[i], sw[3]):
muR = C[3]
else:
muR = A[3]*log10(Flux[i]) + C[3] - A[3]*log10(sw[3])
else:
if lt(Flux[i], sw[4]):
muR = C[4]
else:
muR = A[4]*log10(Flux[i]) + C[4] - A[4]*log10(sw[4])
return muR
这当然是行不通的。我可以看到我将如何使用as_op,但我想保留 NUTS 采样。
【问题讨论】: