我使用的模型的平均响应取决于ODE的解决方案。我正在尝试使用pymc3来拟合这个模型,但在将ODE求解器连接到模型时遇到问题(与缺少测试值有关)。
模型
y_t是对数正态分布的平均值mu_t和标准差sigma。
mu_t是时间t的一组ODE的解决方案。
问题
Theano / pymc3给出错误,因为用于求解ODE的theano张量变量没有测试值。请参阅下面的错误副本。我试过设置
th.config.compute_test_value = 'ignore'
但我认为pymc3会将其更改为需要测试值。我对theano和pymc3相当新,所以如果我遗漏了一些明显的东西,我会道歉。
代码
进口
import pymc3 as pm
import theano as th
import theano.tensor as tt
from FormatData import *
import pandas as pd
解决ODE的功能
# Runge Kutta integrator
def rungekuttastep(h, y, fprime, *args):
k1 = h*fprime(y, *args)
k2 = h*fprime(y + 0.5*k1, *args)
k3 = h*fprime(y + 0.5*k2, *args)
k4 = h*fprime(y + k3, *args)
y_np1 = y + (1./6.)*k1 + (1./3.)*k2 + (1./3.)*k3 + (1./6.)*k4
return y_np1
# ODE equations for my model
def ODE(y, *args):
alpha = args
yprime = tt.zeros_like(y)
yprime = tt.set_subtensor(yprime[0], alpha[0]*y[1] - alpha[1]*y[0])
yprime = tt.set_subtensor(yprime[1], -alpha[2]*y[0]*y[1])
return yprime
# Function to return ODE values given parameters
def calcFittedTitreVals(alpha, niter, hsize, inits):
y0 = tt.vector('y0')
h = tt.scalar('h')
i = tt.iscalar('i')
alpha0 = tt.scalar('alpha0')
alpha1 = tt.scalar('alpha1')
alpha2 = tt.scalar('alpha2')
result, updates = th.scan(fn=lambda y0, h: rungekuttastep(h, y0, ODE, alpha0, alpha1, alpha2),
outputs_info=[{'initial': y0}], non_sequences=h, n_steps=i)
odeint = th.function(inputs=[h, y0, i, alpha0, alpha1, alpha2], outputs=result, updates=updates)
z1 = odeint(h=hsize, # size of the interval
y0=inits, # starting values
i=niter, # number of iterations
alpha0=alpha[0], alpha1=alpha[1], alpha2=alpha[2])
C = z1[:, 0]
A = z1[:, 1]
return C, A
生成数据
t = np.arange(0, 45, 0.1) # times at which to solve ODE
alpha = np.array([2, 0.4, 0.0001]) # true paramter values ODE
C, A = calcFittedTitreVals(alpha, niter=450, hsize=0.1, inits=[0, 1200])
td = np.arange(0, 45, 1) # times at which I observe data
sigma = 0.1
indices = np.array(np.searchsorted(t, td)).flatten()
DATA = pd.DataFrame(
data={'observed': np.random.lognormal(np.log(C[indices]), sigma),
'true': C[indices], 'time': td})
pymc3模型功能
def titreLogNormal(Y, hsize, inits, times):
Y = th.shared(Y)
inits = th.shared(inits)
timesG = np.arange(0, 45, step=hsize)
indices = np.array(np.searchsorted(timesG, times)).flatten()
nTsteps = th.shared(timesG.shape[0])
hsize = th.shared(hsize)
y0 = tt.vector('y0')
h = tt.scalar('h')
i = tt.iscalar('i')
alpha0 = tt.scalar('alpha0')
alpha1 = tt.scalar('alpha1')
alpha2 = tt.scalar('alpha2')
result, updates = th.scan(fn=lambda y0, h: rungekuttastep(h, y0, ODE, alpha0, alpha1, alpha2),
outputs_info=[{'initial': y0}], non_sequences=h, n_steps=i)
odeint = th.function(inputs=[h, y0, i, alpha0, alpha1, alpha2], outputs=result, updates=updates)
model = pm.Model()
with model:
alpha = pm.Gamma('alpha', 0., 10., shape=3, testval=[2, 0.4, 0.001])
sigma = pm.Gamma('sigma', 0.1, 0.1, testval=0.1)
res = odeint(h=hsize, y=inits, i=nTsteps, alpha0=alpha[0], alpha1=alpha[1], alpha2=alpha[2])
mu = pm.Deterministic("mu", res[indices, 0])
y = pm.Lognormal('y', mu, sigma, observed=Y)
return model
使用数据创建模型
model = titreLogNormal(
Y=np.array(DATA[['observed']]).flatten(),
hsize=0.1, inits={'a': 0, 'p': 1200},
times=np.array(DATA[['time']]).flatten())
错误
Traceback (most recent call last):
File "/home/millerp/.local/lib/python3.5/site-packages/theano/gof/op.py", line 625, in __call__
storage_map[ins] = [self._get_test_value(ins)]
File "/home/millerp/.local/lib/python3.5/site-packages/theano/gof/op.py", line 581, in _get_test_value
raise AttributeError('%s has no test value %s' % (v, detailed_err_msg))
AttributeError: y0 has no test value
Backtrace when that variable is created:
File "/home/millerp/pycharm/pycharm-edu-3.5.1/helpers/pydev/_pydev_bundle/pydev_console_utils.py", line 251, in add_exec
more = self.do_add_exec(code_fragment)
File "/home/millerp/pycharm/pycharm-edu-3.5.1/helpers/pydev/_pydev_bundle/pydev_ipython_console.py", line 41, in do_add_exec
res = bool(self.interpreter.add_exec(codeFragment.text))
File "/home/millerp/pycharm/pycharm-edu-3.5.1/helpers/pydev/_pydev_bundle/pydev_ipython_console_011.py", line 455, in add_exec
self.ipython.run_cell(line, store_history=True)
File "/usr/local/lib/python3.5/dist-packages/IPython/core/interactiveshell.py", line 2717, in run_cell
interactivity=interactivity, compiler=compiler, result=result)
File "/usr/local/lib/python3.5/dist-packages/IPython/core/interactiveshell.py", line 2821, in run_ast_nodes
if self.run_code(code, result):
File "/usr/local/lib/python3.5/dist-packages/IPython/core/interactiveshell.py", line 2881, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-2-54c976fefe1e>", line 99, in <module>
times=np.array(DATA[['time']]).flatten()
File "<ipython-input-2-54c976fefe1e>", line 71, in titreLogNormal
y0 = tt.vector('y0')
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/IPython/core/interactiveshell.py", line 2881, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-2-54c976fefe1e>", line 99, in <module>
times=np.array(DATA[['time']]).flatten()
File "<ipython-input-2-54c976fefe1e>", line 86, in titreLogNormal
outputs_info=[{'initial': y0}], non_sequences=h, n_steps=i)
File "/home/millerp/.local/lib/python3.5/site-packages/theano/scan_module/scan.py", line 660, in scan
tensor.shape_padleft(actual_arg), 0),
File "/home/millerp/.local/lib/python3.5/site-packages/theano/tensor/basic.py", line 4429, in shape_padleft
return DimShuffle(_t.broadcastable, pattern)(_t)
File "/home/millerp/.local/lib/python3.5/site-packages/theano/gof/op.py", line 639, in __call__
(i, ins, node, detailed_err_msg))
ValueError: Cannot compute test value: input 0 (y0) of Op InplaceDimShuffle{x,0}(y0) missing default value.
Backtrace when that variable is created:
File "/home/millerp/pycharm/pycharm-edu-3.5.1/helpers/pydev/_pydev_bundle/pydev_console_utils.py", line 251, in add_exec
more = self.do_add_exec(code_fragment)
File "/home/millerp/pycharm/pycharm-edu-3.5.1/helpers/pydev/_pydev_bundle/pydev_ipython_console.py", line 41, in do_add_exec
res = bool(self.interpreter.add_exec(codeFragment.text))
File "/home/millerp/pycharm/pycharm-edu-3.5.1/helpers/pydev/_pydev_bundle/pydev_ipython_console_011.py", line 455, in add_exec
self.ipython.run_cell(line, store_history=True)
File "/usr/local/lib/python3.5/dist-packages/IPython/core/interactiveshell.py", line 2717, in run_cell
interactivity=interactivity, compiler=compiler, result=result)
File "/usr/local/lib/python3.5/dist-packages/IPython/core/interactiveshell.py", line 2821, in run_ast_nodes
if self.run_code(code, result):
File "/usr/local/lib/python3.5/dist-packages/IPython/core/interactiveshell.py", line 2881, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-2-54c976fefe1e>", line 99, in <module>
times=np.array(DATA[['time']]).flatten()
File "<ipython-input-2-54c976fefe1e>", line 71, in titreLogNormal
y0 = tt.vector('y0')