[英]Using multiprocessing in emcee library inside a class
我嘗試使用emcee庫在一個類中實現Monte Carlo Markov Chain,並且還使多處理模塊工作,但是在運行了這樣的測試代碼之后:
import numpy as np
import emcee
import scipy.optimize as op
# Choose the "true" parameters.
m_true = -0.9594
b_true = 4.294
f_true = 0.534
# Generate some synthetic data from the model.
N = 50
x = np.sort(10*np.random.rand(N))
yerr = 0.1+0.5*np.random.rand(N)
y = m_true*x+b_true
y += np.abs(f_true*y) * np.random.randn(N)
y += yerr * np.random.randn(N)
class modelfit():
def __init__(self):
self.x=x
self.y=y
self.yerr=yerr
self.m=-0.6
self.b=2.0
self.f=0.9
def get_results(self):
def func(a):
model=a[0]*self.x+a[1]
inv_sigma2 = 1.0/(self.yerr**2 + model**2*np.exp(2*a[2]))
return 0.5*(np.sum((self.y-model)**2*inv_sigma2 + np.log(inv_sigma2)))
result = op.minimize(func, [self.m, self.b, np.log(self.f)],options={'gtol': 1e-6, 'disp': True})
m_ml, b_ml, lnf_ml = result["x"]
return result["x"]
def lnprior(self,theta):
m, b, lnf = theta
if -5.0 < m < 0.5 and 0.0 < b < 10.0 and -10.0 < lnf < 1.0:
return 0.0
return -np.inf
def lnprob(self,theta):
lp = self.lnprior(theta)
likelihood=self.lnlike(theta)
if not np.isfinite(lp):
return -np.inf
return lp + likelihood
def lnlike(self,theta):
m, b, lnf = theta
model = m * self.x + b
inv_sigma2 = 1.0/(self.yerr**2 + model**2*np.exp(2*lnf))
return -0.5*(np.sum((self.y-model)**2*inv_sigma2 - np.log(inv_sigma2)))
def run_mcmc(self,nstep):
ndim, nwalkers = 3, 100
pos = [self.get_results() + 1e-4*np.random.randn(ndim) for i in range(nwalkers)]
self.sampler = emcee.EnsembleSampler(nwalkers, ndim, self.lnprob,threads=10)
self.sampler.run_mcmc(pos, nstep)
test=modelfit()
test.x=x
test.y=y
test.yerr=yerr
test.get_results()
test.run_mcmc(5000)
我收到此錯誤消息:
File "MCMC_model.py", line 157, in run_mcmc
self.sampler.run_mcmc(theta0, nstep)
File "build/bdist.linux-x86_64/egg/emcee/sampler.py", line 157, in run_mcmc
File "build/bdist.linux-x86_64/egg/emcee/ensemble.py", line 198, in sample
File "build/bdist.linux-x86_64/egg/emcee/ensemble.py", line 382, in _get_lnprob
File "build/bdist.linux-x86_64/egg/emcee/interruptible_pool.py", line 94, in map
File "/vol/aibn84/data2/zahra/anaconda/lib/python2.7/multiprocessing/pool.py", line 558, in get
raise self._value
cPickle.PicklingError: Can't pickle <type 'instancemethod'>: attribute lookup __builtin__.instancemethod failed
我認為這與我在類中使用多重處理的方式有關,但是我無法弄清楚如何保持類的結構,同時也使用多重處理?
任何提示,我將不勝感激。
附注:如果我從上一個函數中刪除threads=10
,則代碼必須能完美工作。
有許多SO問題討論正在發生的事情:
…包括這個,這似乎是您對幾乎相同的問題的回答:
但是,這里的區別在於您不是直接使用multiprocessing
,而是emcee
。 因此, pathos.multiprocessing
解決方案(來自上面的鏈接)不適用於您。 由於emcee
使用cPickle
,因此您必須堅持pickle
知道如何序列化的內容。 您對類實例不走運。 典型的解決方法是使用copy_reg
來注冊要序列化的對象的類型,或者添加__reduce__
方法來告訴python如何對其進行序列化。 您可以從上面的鏈接中看到一些答案,它們暗示了類似的事情……但是,沒有一個使您能夠按照編寫該類的方式進行操作。
作為記錄,您現在可以創建一個pathos.multiprocessing
池,並使用pool
參數將其傳遞給emcee。 但是,請注意,除非您的計算時間特別耗時,否則多處理的開銷實際上會降低速度。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.