Ich konnte eine Methode, die zu einer Instanz einer Klasse gehört, nicht als Deterministic-Funktion mit PyMc3 anpassen. Kannst du mir zeigen, wie das geht?Wie passe ich eine Methode an, die zu einer Instanz mit pymc3 gehört?
Der Einfachheit halber ist mein Fall unten mit einem einfachen Beispiel zusammengefasst. In Wirklichkeit ist meine Einschränkung, dass alles über eine GUI gemacht wird und Aktionen wie "find_MAP" innerhalb von Methoden sein sollten, die mit pyqt-Buttons verknüpft sind.
Ich möchte die Funktion 'FunctionIWantToFit' über die Datenpunkte passen. Problem: Der folgende Code:
import numpy as np
import pymc3 as pm3
from scipy.interpolate import interp1d
import theano.tensor as tt
import theano.compile
class cprofile:
def __init__(self):
self.observed_x = np.array([0.3,1.4,3.1,5,6.8,9,13.4,17.1])
self.observations = np.array([6.25,2.75,1.25,1.25,1.5,1.75,1.5,1])
self.x = np.arange(0,18,0.5)
@theano.compile.ops.as_op(itypes=[tt.dscalar,tt.dscalar,tt.dscalar],
otypes=[tt.dvector])
def FunctionIWantToFit(self,t,y,z):
# can be complicated but simple in this example
# among other things, this FunctionIWantToFit depends on a bunch of
# variables and methods that belong to this instance of the class cprofile,
# so it cannot simply be put outside the class ! (like in the following example)
val=t+y*self.x+z*self.x**2
interp_values = interp1d(self.x,val)
return interp_values(self.observed_x)
def doMAP(self):
model = pm3.Model()
with model:
t = pm3.Uniform("t",0,5)
y = pm3.Uniform("y",0,5)
z = pm3.Uniform("z",0,5)
MyModel = pm3.Deterministic('MyModel',self.FunctionIWantToFit(t,y,z))
obs = pm3.Normal('obs',mu=MyModel,sd=0.1,observed=self.observations)
start = pm3.find_MAP()
print('start: ',start)
test=cprofile()
test.doMAP()
gibt den folgenden Fehler:
Traceback (most recent call last):
File "<ipython-input-15-3dfb7aa09f84>", line 1, in <module>
runfile('/Users/steph/work/profiles/GUI/pymc3/so.py', wdir='/Users/steph/work/profiles/GUI/pymc3')
File "/Users/steph/anaconda/lib/python3.5/site-packages/spyder/utils/site/sitecustomize.py", line 866, in runfile
execfile(filename, namespace)
File "/Users/steph/anaconda/lib/python3.5/site-packages/spyder/utils/site/sitecustomize.py", line 102, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)
File "/Users/steph/work/profiles/GUI/pymc3/so.py", line 44, in <module>
test.doMAP()
File "/Users/steph/work/profiles/GUI/pymc3/so.py", line 38, in doMAP
MyModel = pm3.Deterministic('MyModel',self.FunctionIWantToFit(x,y,z))
File "/Users/steph/anaconda/lib/python3.5/site-packages/theano/gof/op.py", line 668, in __call__
required = thunk()
File "/Users/steph/anaconda/lib/python3.5/site-packages/theano/gof/op.py", line 912, in rval
r = p(n, [x[0] for x in i], o)
File "/Users/steph/anaconda/lib/python3.5/site-packages/theano/compile/ops.py", line 522, in perform
outs = self.__fn(*inputs)
TypeError: FunctionIWantToFit() missing 1 required positional argument: 'z'
Was ist los?
Bemerkung 1: Ich bekomme systematisch eine Fehlermeldung bezüglich des letzten Parameters von 'FunctionIWantToFit'. hier ist es "z", aber wenn ich z aus der Signatur entferne, betrifft die Fehlermeldung "y" (identisch mit Ausnahme des Namens der Variablen). Wenn ich in der Signatur eine vierte Variable 'w' hinzufüge, betrifft die Fehlermeldung 'w' (identisch mit Ausnahme des Namens der Variablen).
rk2: es sieht so aus, als hätte ich etwas sehr Einfaches in 'theano' oder 'pymc3' verpasst, denn wenn ich 'FunctionIWantToFit' außerhalb der Klasse platziere, funktioniert es. Siehe das folgende Beispiel.
class cprofile:
def __init__(self):
self.observations = np.array([6.25,2.75,1.25,1.25,1.5,1.75,1.5,1])
def doMAP(self):
model = pm3.Model()
with model:
t = pm3.Uniform("t",0,5)
y = pm3.Uniform("y",0,5)
z = pm3.Uniform("z",0,5)
MyModel = pm3.Deterministic('MyModel',FunctionIWantToFit(t,y,z))
obs = pm3.Normal('obs',mu=MyModel,sd=0.1,observed=self.observations)
start = pm3.find_MAP()
print('start: ',start)
@theano.compile.ops.as_op(itypes=[tt.dscalar,tt.dscalar,tt.dscalar],
otypes=[tt.dvector])
def FunctionIWantToFit(t,y,z):
observed_x = np.array([0.3,1.4,3.1,5,6.8,9,13.4,17.1])
x = np.arange(0,18,0.5)
val=t+y*x+z*x**2
interp_values = interp1d(x,val)
return interp_values(observed_x)
test=cprofile()
test.doMAP()
gibt:
Warning: gradient not available.(E.g. vars contains discrete variables). MAP estimates may not be accurate for the default parameters. Defaulting to non-gradient minimization fmin_powell.
WARNING:pymc3:Warning: gradient not available.(E.g. vars contains discrete variables). MAP estimates may not be accurate for the default parameters. Defaulting to non-gradient minimization fmin_powell.
Optimization terminated successfully.
Current function value: 1070.673818
Iterations: 4
Function evaluations: 179
start: {'t_interval_': array(-0.27924150484602733), 'y_interval_': array(-9.940000425802811), 'z_interval_': array(-12.524909223913992)}
Abgesehen davon, dass ich weiß nicht, wie das in mehrere Module ohne großen Änderungen zu tun, da die wirkliche ‚FunctionIWantToFit‘ auf eine Reihe von Variablen und Methoden abhängt, gehören zu dieser Instanz des Klassenprofils.
Tatsächlich weiß ich nicht einmal, wie ich das machen soll, da 'FunctionIWantToFit' dann Objekte in Argumenten haben sollte (die ich derzeit über self
benutze) und ich bin mir nicht sicher, wie das mit dem Theano Decorator geht .
Also würde ich diese Lösung lieber vermeiden ... wenn nicht notwendig. dann brauche ich Erklärungen, wie es zu implementieren ...
am 9. April aufgenommen, 2017:
Auch ohne die Interpolation Frage, funktioniert es nicht, weil ich etwas offensichtlich mit Theano verpasst haben müssen und/oder pymc3. Bitte können Sie das Problem erklären? Ich möchte nur Modell und Daten vergleichen. Erstens ist es so eine Schande, an pymc2 hängen zu bleiben. ; Zweitens bin ich mir sicher, dass ich nicht der einzige bin, der ein so grundlegendes Problem hat.
Zum Beispiel Betrachten wir Variationen dieses sehr grundlegenden Code:
import numpy as np
import theano
import pymc3
theano.config.compute_test_value = 'ignore'
theano.config.on_unused_input = 'ignore'
class testclass:
x = np.arange(0,18,0.5)
observed_x = np.array([0.3,1.4,3.1,5,6.8,9,13.4,17.1])
observations = np.array([6.25,2.75,1.25,1.25,1.5,1.75,1.5,1])
def testfunc(self,t,y,z):
t2 = theano.tensor.dscalar('t2')
y2 = theano.tensor.dscalar('y2')
z2 = theano.tensor.dscalar('z2')
val = t2 + y2 * self.observed_x + z2 * self.observed_x**2
f = theano.function([t2,y2,z2],val)
return f
test=testclass()
model = pymc3.Model()
with model:
t = pymc3.Uniform("t",0,5)
y = pymc3.Uniform("y",0,5)
z = pymc3.Uniform("z",0,5)
with model:
MyModel = pymc3.Deterministic('MyModel',test.testfunc(t,y,z))
with model:
obs = pymc3.Normal('obs',mu=MyModel,sd=0.1,observed=test.observations)
dieser Code mit der Fehlermeldung in der letzten Zeile nicht: TypeError: unsupported operand type(s) for -: 'TensorConstant' and 'Function'
wenn ich ‚testfunc‘ ändern in:
def testfunc(self,t,y,z):
t2 = theano.tensor.dscalar('t2')
y2 = theano.tensor.dscalar('y2')
z2 = theano.tensor.dscalar('z2')
val = t2 + y2 * self.observed_x + z2 * self.observed_x**2
f = theano.function([t2,y2,z2],val)
fval = f(t,y,z,self.observed_x)
return fval
der Code nicht auf der 'MyModel =' Linie mit Fehler TypeError: ('Bad input argument to theano function with name "/Users/steph/work/profiles/GUI/pymc3/theanotest170409.py:32" 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?')
, wenn ich auf den ursprünglich ‚testfunc‘ zurückgehen, aber die letzte ‚mit Modell‘ Linien mit ändern:
with model:
fval = test.testfunc(t,y,z)
obs = pymc3.Normal('obs',mu=fval,sd=0.1,observed=test.observations)
dem Fehler ist das gleiche wie die ersten.
Ich präsentierte hier nur 3 Versuche, aber ich möchte unterstreichen, dass ich viele viele Kombinationen, einfacher und einfacher bis diese, während der Stunden ausprobiert habe. Ich habe das Gefühl, Pymc3 zeigt eine große Veränderung der Geist, im Vergleich zu Pymc2, die ich nicht bekommen habe und schlecht dokumentiert ist ...
danke für Ihre Antwort. Ich war weg und werde es jetzt versuchen. –
Entschuldigung, aber es bleibt mir unklar. Ich habe viele Kombinationen aus einer hausgemachten Theano-Op mit pymc3 ausprobiert, aber nichts funktioniert und die Docs sind schmerzhaft verschwommen ... Könnten Sie ein Beispiel für Code geben? –
Wenn Sie Ihre eigene Interpolationsfunktion mit Theano schreiben, sollten Sie keinen Op benötigen. Die 1D-Interpolation sollte einfach sein. –