具有收敛测试的并行 RJAGS
Parallel RJAGS with convergence testing
我正在使用 RJAGS 修改现有模型。我想 运行 并行链,偶尔检查 Gelman-Rubin 收敛诊断以查看是否需要保持 运行ning。问题是,如果我需要根据诊断值恢复 运行ning,重新编译的链会从第一个初始化的先验值而不是链停止的参数 space 中的位置重新开始。如果我不重新编译模型,RJAGS 会抱怨。有没有办法在链条停止时存储链条的位置,以便我可以从我离开的地方重新初始化?在这里,我将举一个非常简单的例子。
example1.bug:
model {
for (i in 1:N) {
x[i] ~ dnorm(mu,tau)
}
mu ~ dnorm(0,0.0001)
tau <- pow(sigma,-2)
sigma ~ dunif(0,100)
}
parallel_test.R:
#Make some fake data
N <- 1000
x <- rnorm(N,0,5)
write.table(x,
file='example1.data',
row.names=FALSE,
col.names=FALSE)
library('rjags')
library('doParallel')
library('random')
nchains <- 4
c1 <- makeCluster(nchains)
registerDoParallel(c1)
jags=list()
for (i in 1:getDoParWorkers()){
jags[[i]] <- jags.model('example1.bug',
data=list('x'=x,'N'=N))
}
# Function to combine multiple mcmc lists into a single one
mcmc.combine <- function( ... ){
return( as.mcmc.list( sapply( list( ... ),mcmc ) ) )
}
#Start with some burn-in
jags.parsamples <- foreach( i=1:getDoParWorkers(),
.inorder=FALSE,
.packages=c('rjags','random'),
.combine='mcmc.combine',
.multicombine=TRUE) %dopar%
{
jags[[i]]$recompile()
update(jags[[i]],100)
jags.samples <- coda.samples(jags[[i]],c('mu','tau'),100)
return(jags.samples)
}
#Check the diagnostic output
print(gelman.diag(jags.parsamples[,'mu']))
counter <- 0
#my model doesn't converge so quickly, so let's simulate doing
#this updating 5 times:
#while(gelman.diag(jags.parsamples[,'mu'])[[1]][[2]] > 1.04)
while(counter < 5)
{
counter <- counter + 1
jags.parsamples <- foreach(i=1:getDoParWorkers(),
.inorder=FALSE,
.packages=c('rjags','random'),
.combine='mcmc.combine',
.multicombine=TRUE) %dopar%
{
#Here I lose the progress I've made
jags[[i]]$recompile()
jags.samples <- coda.samples(jags[[i]],c('mu','tau'),100)
return(jags.samples)
}
}
print(gelman.diag(jags.parsamples[,'mu']))
print(summary(jags.parsamples))
stopCluster(c1)
在输出中,我看到:
Iterations = 1001:2000
我知道应该有 > 5000 次迭代。
(交叉发布到 stats.stackexchange.com,这可能是更合适的地点)
每次您的 JAGS 模型在工作节点上运行时,coda 样本都会被 returned,但模型的状态会丢失。所以下次它重新编译时,它会从头开始,如您所见。要解决此问题,您需要获取并 return 函数中的模型状态(在工作节点上),如下所示:
endstate <- jags[[i]]$state(internal=TRUE)
然后您需要将其传递回工作节点并使用 jags.model() 和 inits=endstate(对于适当的链)在工作函数中重新生成模型。
我实际上建议您查看为您完成所有这些工作的 runjags 包。例如:
library('runjags')
parsamples <- run.jags('example1.bug', data=list('x'=x,'N'=N), monitor=c('mu','tau'), sample=100, method='rjparallel')
summary(parsamples)
newparsamples <- extend.jags(parsamples, sample=100)
summary(parsamples)
# etc
甚至:
parsamples <- autorun.jags('example1.bug', data=list('x'=x,'N'=N), monitor=c('mu','tau'), method='rjparallel')
runjags 的第 2 版有望很快上传到 CRAN,但现在您可以从以下位置下载二进制文件:https://sourceforge.net/projects/runjags/files/runjags/
马特
我正在使用 RJAGS 修改现有模型。我想 运行 并行链,偶尔检查 Gelman-Rubin 收敛诊断以查看是否需要保持 运行ning。问题是,如果我需要根据诊断值恢复 运行ning,重新编译的链会从第一个初始化的先验值而不是链停止的参数 space 中的位置重新开始。如果我不重新编译模型,RJAGS 会抱怨。有没有办法在链条停止时存储链条的位置,以便我可以从我离开的地方重新初始化?在这里,我将举一个非常简单的例子。
example1.bug:
model {
for (i in 1:N) {
x[i] ~ dnorm(mu,tau)
}
mu ~ dnorm(0,0.0001)
tau <- pow(sigma,-2)
sigma ~ dunif(0,100)
}
parallel_test.R:
#Make some fake data
N <- 1000
x <- rnorm(N,0,5)
write.table(x,
file='example1.data',
row.names=FALSE,
col.names=FALSE)
library('rjags')
library('doParallel')
library('random')
nchains <- 4
c1 <- makeCluster(nchains)
registerDoParallel(c1)
jags=list()
for (i in 1:getDoParWorkers()){
jags[[i]] <- jags.model('example1.bug',
data=list('x'=x,'N'=N))
}
# Function to combine multiple mcmc lists into a single one
mcmc.combine <- function( ... ){
return( as.mcmc.list( sapply( list( ... ),mcmc ) ) )
}
#Start with some burn-in
jags.parsamples <- foreach( i=1:getDoParWorkers(),
.inorder=FALSE,
.packages=c('rjags','random'),
.combine='mcmc.combine',
.multicombine=TRUE) %dopar%
{
jags[[i]]$recompile()
update(jags[[i]],100)
jags.samples <- coda.samples(jags[[i]],c('mu','tau'),100)
return(jags.samples)
}
#Check the diagnostic output
print(gelman.diag(jags.parsamples[,'mu']))
counter <- 0
#my model doesn't converge so quickly, so let's simulate doing
#this updating 5 times:
#while(gelman.diag(jags.parsamples[,'mu'])[[1]][[2]] > 1.04)
while(counter < 5)
{
counter <- counter + 1
jags.parsamples <- foreach(i=1:getDoParWorkers(),
.inorder=FALSE,
.packages=c('rjags','random'),
.combine='mcmc.combine',
.multicombine=TRUE) %dopar%
{
#Here I lose the progress I've made
jags[[i]]$recompile()
jags.samples <- coda.samples(jags[[i]],c('mu','tau'),100)
return(jags.samples)
}
}
print(gelman.diag(jags.parsamples[,'mu']))
print(summary(jags.parsamples))
stopCluster(c1)
在输出中,我看到:
Iterations = 1001:2000
我知道应该有 > 5000 次迭代。 (交叉发布到 stats.stackexchange.com,这可能是更合适的地点)
每次您的 JAGS 模型在工作节点上运行时,coda 样本都会被 returned,但模型的状态会丢失。所以下次它重新编译时,它会从头开始,如您所见。要解决此问题,您需要获取并 return 函数中的模型状态(在工作节点上),如下所示:
endstate <- jags[[i]]$state(internal=TRUE)
然后您需要将其传递回工作节点并使用 jags.model() 和 inits=endstate(对于适当的链)在工作函数中重新生成模型。
我实际上建议您查看为您完成所有这些工作的 runjags 包。例如:
library('runjags')
parsamples <- run.jags('example1.bug', data=list('x'=x,'N'=N), monitor=c('mu','tau'), sample=100, method='rjparallel')
summary(parsamples)
newparsamples <- extend.jags(parsamples, sample=100)
summary(parsamples)
# etc
甚至:
parsamples <- autorun.jags('example1.bug', data=list('x'=x,'N'=N), monitor=c('mu','tau'), method='rjparallel')
runjags 的第 2 版有望很快上传到 CRAN,但现在您可以从以下位置下载二进制文件:https://sourceforge.net/projects/runjags/files/runjags/
马特