Wie schreibe ich eine benutzerdefinierte Deterministik oder Stochastik in pymc3 mit theano.op?

Ich mache pymc3 und würde gerne benutzerdefinierte Stochastiken erstellen, aber es scheint nicht viel Dokumentation darüber zu geben, wie es gemacht wird. Ich kann das @ benutzas_op way, jedoch ist es anscheinend unmöglich, den NUTS-Sampler zu verwenden. In diesem Fall sehe ich den Vorteil von pymc3 nicht gegenüber pymc.

Das Tutorial erwähnt, dass dies durch Erben von theano.Op erfolgen kann. Aber kann mir jemand zeigen, wie das funktionieren würde? Ich habe zwei Stochastiken, die ich definieren möchte.

Der erste sollte einfacher sein, es ist ein N-dimensionaler VektorF das hat nur konstante Elternvariablen:

with myModel:
    F = DensityDist('F', lambda value: pymc.skew_normal_like(value, F_mu_array, F_std_array, F_a_array), shape = N)

Ich möchte eine normale Versatzdistribution, die in pymc3 noch nicht implementiert zu sein scheint. Ich habe gerade die pymc2-Version importiert. Unglücklicherweise,F_mu_array, F_std_array, F_a_array and F sind alle N-dimensionalen Vektoren und das Lambda-Ding scheint nicht mit einer N-dimensionalen Liste zu funktionierenvalue.

Zunächst, gibt es eine Möglichkeit, die Lambda-Eingabe zu einem N-dimensionalen Array zu machen? Wenn nicht, müsste ich wohl das Stochastic @ definierF direkt, und hier nehme ich an, ich brauche theano.Op, damit es funktioniert.

Das zweite Beispiel ist eine kompliziertere Funktion anderer Stochastiken. Hier, wie ich es definieren möchte (im Moment falsch):

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)

Wo ist die FunktionR_forward(F,M,A,C,sw,N) ist naiv definiert als:

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

Dies wird vermutlich natürlich nicht funktionieren. Ich kann sehen, wie ich @ verwenden würas_op, aber ich möchte die NUTS-Abtastung beibehalten.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage