Я делаю несколько pymc3, и я хотел бы создать пользовательский Stochastics, однако, похоже, нет много документации о том, как это делается. Я знаю, как использовать as_op way, однако, по-видимому, это делает невозможным использование пробоотборника NUTS, и в этом случае я не вижу преимущества pymc3 над pymc.Как написать пользовательский детерминированный или стохастический в pymc3 с theano.op?
В учебнике упоминается, что это можно сделать, наследуя от theano.Op. Но может ли кто-нибудь показать мне, как это будет работать (я все еще начинаю на анано)? У меня есть два Стохастика, которые я хочу определить.
Первый должен быть легче, что это вектор размерности 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-мерные векторы, и предмет лямбда, похоже, не работает с N-мерным списком value
.
Во-первых, есть ли способ сделать лямбда-вход 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.
thx для вашего примера. Я лично начинаю работать с pymc3 и не могу использовать его для некоторых задач. Итак, я код для pymc2 ... такой позор ... Пожалуйста, можете посмотреть на мое дело http://stackoverflow.com/questions/42205123/how-to-fit-a-method-belonging-to-an-instance- с-pymc3, чтобы узнать, можете ли вы помочь? Я видел ваш пример некоторое время назад, но я нашел его сложным, и я еще не применил его к моему делу, потому что я надеялся, что кто-то предложит что-нибудь более простое. Мне было бы неловко, не будет ли pymc3 практическим ответом ... Мне кажется, что я, скорее всего, пропущу что-то очевидное. –
Даже более недавние попытки избежать использования theano.op, следующих комментариев, являются сбоями. Механики остаются таинственными ... –
Я ответил на http://stackoverflow.com/a/43449084/7132951 –