我正在尝试建立一个Langevin方程特定结果的似然函数模型(谐波势中的布朗粒子):
这是我在pymc2中的模型似乎有效: https://github.com/hstrey/BayesianAnalysis/blob/master/Langevin%20simulation.ipynb
#define the model/function to be fitted.
def model(x):
t = pm.Uniform('t', 0.1, 20, value=2.0)
A = pm.Uniform('A', 0.1, 10, value=1.0)
@pm.deterministic(plot=False)
def S(t=t):
return 1-np.exp(-4*delta_t/t)
@pm.deterministic(plot=False)
def s(t=t):
return np.exp(-2*delta_t/t)
path = np.empty(N, dtype=object)
path[0]=pm.Normal('path_0',mu=0, tau=1/A, value=x[0], observed=True)
for i in range(1,N):
path[i] = pm.Normal('path_%i' % i,
mu=path[i-1]*s,
tau=1/A/S,
value=x[i],
observed=True)
return locals()
mcmc = pm.MCMC( model(x) )
mcmc.sample( 20000, 2000, 10 )
基本思想是每个点都取决于链中的前一点(马尔可夫链)。顺便说一句,x是数据数组,N是其长度,delta_t是时间步长= 0.01。知道如何在pymc3中实现这个吗?我试过了:
# define the model/function for diffusion in a harmonic potential
DHP_model = pm.Model()
with DHP_model:
t = pm.Uniform('t', 0.1, 20)
A = pm.Uniform('A', 0.1, 10)
S=1-pm.exp(-4*delta_t/t)
s=pm.exp(-2*delta_t/t)
path = np.empty(N, dtype=object)
path[0]=pm.Normal('path_0',mu=0, tau=1/A, observed=x[0])
for i in range(1,N):
path[i] = pm.Normal('path_%i' % i,
mu=path[i-1]*s,
tau=1/A/S,
observed=x[i])
不幸的是,一旦我尝试运行它,模型就会崩溃。我在我的机器上尝试了一些pymc3示例(教程),这是有效的。
提前致谢。我真的希望pymc3中的新采样器能帮助我使用这个模型。我试图将贝叶斯方法应用于单分子实验。
答案 0 :(得分:1)
不是在循环中创建许多单独的正态分布的1-D变量,而是可以进行自定义分布(通过扩展Continuous
),该分布知道用于计算整个路径的对数可能性的公式。您可以从pymc3已知的正态似然公式中引导此可能性公式。有关示例,请参阅the built-in AR1 class。
由于你的粒子遵循马尔可夫属性,你的可能性似乎是
import theano.tensor as T
def logp(path):
now = path[1:]
prev = path[:-1]
loglik_first = pm.Normal.dist(mu=0., tau=1./A).logp(path[0])
loglik_rest = T.sum(pm.Normal.dist(mu=prev*ss, tau=1./A/S).logp(now))
loglik_final = loglik_first + loglik_rest
return loglik_final
我猜你想在每个时间步都为ss
绘制一个值,在这种情况下你应该确保指定ss = pm.exp(..., shape=len(x)-1)
,以便块中的prev*ss
上面的内容被解释为逐元素乘法。
然后你可以用
指定你的观察结果path = MyLangevin('path', ..., observed=x)
这应该更快地运行很多。
答案 1 :(得分:0)
由于我没有看到我的问题的答案,让我自己回答。我提出了以下解决方案:
# now lets model this data using pymc
# define the model/function for diffusion in a harmonic potential
DHP_model = pm.Model()
with DHP_model:
D = pm.Gamma('D',mu=mu_D,sd=sd_D)
A = pm.Gamma('A',mu=mu_A,sd=sd_A)
S=1.0-pm.exp(-2.0*delta_t*D/A)
ss=pm.exp(-delta_t*D/A)
path=pm.Normal('path_0',mu=0.0, tau=1/A, observed=x[0])
for i in range(1,N):
path = pm.Normal('path_%i' % i,
mu=path*ss,
tau=1.0/A/S,
observed=x[i])
start = pm.find_MAP()
print(start)
trace = pm.sample(100000, start=start)
不幸的是,这段代码在6到2天之间的N = 50处进行编译。我正在运行Ubuntu的相当快的PC(24Gb RAM)上运行。我尝试使用GPU,但运行速度稍慢。我怀疑是内存问题,因为它在运行时使用了99.8%的内存。我和Stan一起尝试了相同的计算,只需要2分钟就可以运行。