Мне не удалось установить метод, принадлежащий экземпляру класса, в качестве детерминированной функции, с помощью PyMc3. Можете ли вы показать мне, как это сделать?Как подобрать метод, принадлежащий экземпляру с pymc3?
Для простоты мой случай кратко изложен ниже с помощью простого примера. На самом деле мое ограничение состоит в том, что все сделано с помощью графического интерфейса, и действия, подобные «find_MAP», должны быть внутри методов, связанных с кнопками pyqt.
Я хочу установить функцию «FunctionIWantToFit» над точками данных. Проблема, следующий код:
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()
дает следующее сообщение об ошибке:
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'
Что случилось?
примечание 1: Я систематически получаю сообщение об ошибке, касающееся последнего параметра «FunctionIWantToFit». здесь это 'z', но если я удалю z из подписи, сообщение об ошибке касается «y» (идентично, кроме имени переменной). если я добавлю 4-ю переменную 'w' в подпись, сообщение об ошибке относится к 'w' (идентично, кроме имени переменной).
rk2: похоже, я пропустил что-то очень основное в 'anano' или 'pymc3', потому что, когда я кладу 'FunctionIWantToFit' вне класса, он работает. См. Следующий пример.
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()
дает:
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)}
Кроме того, что я не знаю, как сделать это без больших изменений в нескольких модулях, так как реальный «FunctionIWantToFit» зависит от кучи переменных и методов, которые принадлежат к этому экземпляру профиля класса.
На самом деле я даже не уверен, что знаю, как это сделать, поскольку «FunctionIWantToFit» должен иметь объекты в аргументах (которые я использую в настоящее время через self
), и я не уверен, как это сделать с помощью декоратора theano ,
Поэтому я бы предпочел избежать этого решения ... если это необходимо. то мне нужно объяснений о том, как реализовать ...
добавил на 9 апреля 2017 года:
Даже без интерполяции вопрос, он не работает, потому что я должен пропустить что-то очевидное с Теано и/или pymc3. Пожалуйста, объясните проблему? Я просто хочу сравнить модель и данные. Во-первых, такой стыд застрял в pymc2. ; во-вторых, я уверен, что я не единственный, у кого такая основная проблема.
Например, давайте рассмотрим варианты вокруг этого очень простой код:
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)
этот код не в последней строке с сообщением об ошибке: TypeError: unsupported operand type(s) for -: 'TensorConstant' and 'Function'
, если я изменю «testfunc» в:
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
код не в строке 'MyModel =' с ошибкой 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?')
если я вернусь к оригинальному «testfunc», но изменить последний «с моделью» линии с:
with model:
fval = test.testfunc(t,y,z)
obs = pymc3.Normal('obs',mu=fval,sd=0.1,observed=test.observations)
погрешность такой же, как и первый.
Я представил здесь только 3 попытки, но я хотел бы подчеркнуть, что я пробовал много разных комбинаций, проще и проще до тех пор, пока они не будут в течение нескольких часов. У меня есть чувство, что pymc3 показывает огромную смену духа по сравнению с pymc2, что я не получил и плохо документирован ...
Благодарим вас за ответ. Я был в отъезде и попробую это сейчас. –
извините, но мне остается неясным. Я пробовал много комбинаций самодельного anano op с pymc3, но ничего не работает, и документы сильно размыты ... Не могли бы вы привести пример кода? –
Если вы пишете свою собственную функцию интерполяции с помощью Theano, вам не нужно использовать op. Интерполяция 1D должна быть простой. –