在这里,我的目标是估计由下式给出的阻尼谐振子的参数(伽马和欧米茄)
dX^2/dt^2+gamma*dX/dt+(2*pi*omega)^2*X=0。(我们可以在系统中添加高斯白噪声。)
import pymc
import numpy as np
import scipy.io as sio
import matplotlib.pyplot as plt;
from scipy.integrate import odeint
#import data
xdata = sio.loadmat('T.mat')['T'][0] #time
ydata1 = sio.loadmat('V1.mat')['V1'][0] # V2=dV1/dt, (X=V1),
ydata2 = sio.loadmat('V2.mat')['V2'][0] # dV2/dt=-(2pi*omega)^2*V1-gama*V2
#time span for solving the equations
npts= 500
dt=0.01
Tspan=5.0
time = np.linspace(0,Tspan,npts+1)
#initial condition
V0 = [1.0, 1.0]
# Priors for unknown model parameters
sigma = pymc.Uniform('sigma', 0.0, 100.0)
gama= pymc.Uniform('gama', 0.0, 20.0)
omega=pymc.Uniform('omega',0.0, 20.0)
#Solve the equations
@pymc.deterministic
def DHOS(gama=gama, omega=omega):
V1= np.zeros(npts+1)
V2= np.zeros(npts+1)
V1[0] = V0[0]
V2[0] = V0[1]
for i in range(1,npts+1):
V1[i]= V1[i-1] + dt*V2[i-1];
V2[i] = V2[i-1] + dt*(-((2*np.pi*omega)**2)*V1[i-1]-gama*V2[i-1]);
return [V1, V2]
#or we can use odeint
#@pymc.deterministic
#def DHS( gama=gama, omega=omega):
# def DOS_func(y, time):
# V1, V2 = y[0], y[1]
# dV1dt = V2
# dV2dt = -((2*np.pi*omega)**2)* V1 -gama*V2
# dydt = [dV1dt, dV2dt]
# return dydt
# soln = odeint(DOS_func,V0, time)
# V1, V2 = soln[:,0], soln[:,1]
# return V1, V2
# value of outcome (observations)
V1 = pymc.Lambda('V1', lambda DHOS=DHOS: DHOS[0])
V2 = pymc.Lambda('V2', lambda DHOS=DHOS: DHOS[1])
# liklihood of observations
Yobs1 = pymc.Normal('Yobs1', mu=V1, tau=1.0/sigma**2, value=ydata1, observed=True)
Yobs2 = pymc.Normal('Yobs2', mu=V2, tau=1.0/sigma**2, value=ydata2, observed=True)
通过将上面的代码保存为 DampedOscil_model.py,我们就可以如下运行 PYMC
import pymc
import DampedOscil_model
MDL = pymc.MCMC(DampedOscil_model, db='pickle')
MDL.sample(iter=1e4, burn=1e2, thin=2)
gama_trace=MDL.trace('gama')[- 1000:]
omega_trace=MDL.trace('omega')[-1000:]
gama=MDL.gama.value
omega=MDL.omega.value
而且效果很好(见下文)。
由 gama_true=2.0 和 omega_est=1.5 构造的真实信号与估计信号。估计的参数值为 gama_est=2.04 和 omega_est=1.49
现在我会将此代码转换为 PYMC3 以使用 NUTS 和 ADVI。
import matplotlib.pyplot as plt
import scipy.io as sio
import pandas as pd
import numpy as np
import pymc3 as pm
import theano.tensor as tt
import theano
from pymc3 import Model, Normal, HalfNormal, Uniform
from pymc3 import NUTS, find_MAP, sample, Slice, traceplot, summary
from pymc3 import Deterministic
from scipy.optimize import fmin_powell
#import data
xdata = sio.loadmat('T.mat')['T'][0] #time
ydata1 = sio.loadmat('V1.mat')['V1'][0] # V2=dV1/dt, (X=V1),
ydata2 = sio.loadmat('V2.mat')['V2'][0] # dV2/dt=-(2pi*omega)^2*V1-gama*V2
#time span for solving the equations
npts= 500
dt=0.01
Tspan=5.0
time = np.linspace(0,Tspan,npts+1)
niter=10000
burn=niter//2;
with pm.Model() as model:
#Priors for unknown model parameters
sigma = pm.HalfNormal('sigma', sd=1)
gama= pm.Uniform('gama', 0.0, 20.0)
omega=pm.Uniform('omega',0.0, 20.0)
#initial condition
V0 = [1.0, 1.0]
#Solve the equations
# do I need to use theano.tensor here?!
@theano.compile.ops.as_op(itypes=[tt.dscalar, tt.dscalar],otypes=[tt.dvector])
def DHOS(gama=gama, omega=omega):
V1= np.zeros(npts+1)
V2= np.zeros(npts+1)
V1[0] = V0[0]
V2[0] = V0[1]
for i in range(1,npts+1):
V1[i]= V1[i-1] + dt*V2[i-1];
V2[i] = V2[i-1] + dt*(-((2*np.pi*1)**2)*V1[i-1]-gama*V2[i-1]);
return V1,V2
V1 = pm.Deterministic('V1', DHOS[0])
V2 = pm.Deterministic('V2', DHOS[1])
start = pm.find_MAP(fmin=fmin_powell, disp=True)
step=pm.NUTS()
trace=pm.sample(niter, step, start=start, progressbar=False)
traceplot(trace);
Summary=pm.df_summary(trace[-1000:])
gama_trace = trace.get_values('gama', burn)
omega_trace = trace.get_values('omega', burn)
对于此代码,我收到以下错误: V1 = pm.Deterministic('V1', DHOS[0])
TypeError: 'FromFunctionOp' object does not support indexing
简而言之,我想知道如何将 PYMC 代码的以下部分转换为 PYMC3。
@pymc.deterministic
def DOS(gama=gama, omega=omega):
V1= np.zeros(npts+1)
V2= np.zeros(npts+1)
V1[0] = V0[0]
V2[0] = V0[1]
for i in range(1,npts+1):
V1[i]= V1[i-1] + dt*V2[i-1];
V2[i] = V2[i-1] + dt*(-((2*np.pi*omega)**2)*V1[i-1]-gama*V2[i-1]);
return [V1, V2]
V1 = pymc.Lambda('V1', lambda DOS=DOS: DOS[0])
V2 = pymc.Lambda('V2', lambda DOS=DOS: DOS[1])
问题是,第一,确定性函数的论证在 PYMC3 中与 PYMC 不同,第二,在 PYMC3 中没有 Lambda 函数。
感谢您帮助解决 PYMC3 中的 ODE 以解决生物系统中的参数估计任务(从数据中估计方程参数)。
非常感谢您的帮助。
亲切的问候,
梅萨姆