Еще одна вещь: я не знаю, эффективен ли мой приведенный выше пример или его можно упростить. В частности, у меня создается впечатление, что экземпляр testcp дважды копируется в память. Другие комментарии / ответы приветствуются.

смог приспособить метод, принадлежащий экземпляру класса, как детерминированную функцию, к 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» (идентично, кроме имени переменной). если я добавлю четвертую переменную "w" в подпись, сообщение об ошибке будет относиться к "w" (идентично, кроме как из имени переменной).

rk2: похоже, я пропустил что-то очень простое в «theano» или «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:

Даже без вопроса об интерполяции это не работает, потому что я, должно быть, пропустил что-то очевидное с theano и / или 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» с помощью:

with model:
   fval = test.testfunc(t,y,z)
   obs = pymc3.Normal('obs',mu=fval,sd=0.1,observed=test.observations)

ошибка такая же, как и первая.

Я представил здесь только 3 попытки, но я хотел бы подчеркнуть, что я пробовал много разных комбинаций, все проще и проще, до этих, в течение нескольких часов. У меня такое чувство, что pymc3 показывает огромное изменение духа по сравнению с pymc2, которого я не получил и плохо документирован ...

Ответы на вопрос(3)

Ваш ответ на вопрос