簡體   English   中英

在R中使用並行package時如何設置種子

[英]How to set seeds when using parallel package in R

我目前在 R 中使用parallel package,我正試圖通過設置種子來使工作可重現。

但是,如果您在創建集群並並行執行您想要的任務之前設置種子,出於某種原因,它不會使其可重現。 我想我需要在創建集群時為每個核心設置種子。

我在這里做了一個小例子來說明我的問題:

library(parallel)

# function to generate 2 uniform random numbers
runif_parallel <- function() {
  # make cluster of two cores
  cl <- parallel::makeCluster(2)

  # sample uniform random numbers
  samples <- parallel::parLapplyLB(cl, X = 1:2, fun = function(i) runif(1))

  # close cluster
  parallel::stopCluster(cl)

  return(unlist(samples))
}

set.seed(41)
test1 <- runif_parallel()

set.seed(41)
test2 <- runif_parallel()

# they should be the same since they have the same seed
identical(test1, test2)

在此示例中, test1test2應該相同,因為它們具有相同的種子,但返回不同的結果。

請問我哪里出錯了?

請注意,我編寫此示例的方式必須模仿我現在的使用方式 - 可能有更簡潔的方法來並行生成兩個隨機統一數。

您需要在每個作業中運行set.seed 這是一個可重現的隨機生成:

cl <- parallel::makeCluster(2)

# sample uniform random numbers
parallel::clusterEvalQ(cl, set.seed(41));

samples <- parallel::parLapplyLB(cl, X = 1:2, fun = function(i){set.seed(i);runif(1)})
samples

# [[1]]
# [1] 0.2655087
# 
# [[2]]
# [1] 0.1848823

samples <- parallel::parLapplyLB(cl, X = 1:2, fun = function(i){set.seed(i);runif(1)})
samples

# [[1]]
# [1] 0.2655087
# 
# [[2]]
# [1] 0.1848823

parallel::stopCluster(cl)

如果可能有幫助,一種為每個核心設置單獨種子的快速方法

# Set number of cores, here to n-1
nCores <- parallel::detectCores()-1

# Parallelization, n-1 cores
parallel::setDefaultCluster(cl = (cl <- parallel::makeCluster(nCores)))

thisSeed <- 1
# Set different seeds in each cluster; here set to 1 for the cluster, 2 for the second, etc. 
# Do something in each cluster
(parRes <- do.call(c, parallel::clusterApply(x = 1:nCores+thisSeed-1, fun = function(x) {
  set.seed(x)
  runif(1)
  })))

# Stop cluster
stopCluster(cl = cl)

# Same thing, not in parallel
singleRes <- do.call(c, lapply(1:nCores+thisSeed-1, function(x) {
  set.seed(x)
  runif(1)
}))

# Verify that the results are the same
all(parRes == singleRes)

我們可以使用parallel::clusterSetRNGStream()

library(parallel)

CL <- makeCluster(detectCores() - 1)


clusterSetRNGStream(CL, 42)  ## set seed

t(parSapply(CL, 1:3, \(i) runif(1)))
#           [,1]      [,2]     [,3]
# [1,] 0.1738456 0.5004388 0.127589


clusterSetRNGStream(CL, 42)  ## set same seed again

t(parSapply(CL, 1:3, \(i) runif(1)))
#           [,1]      [,2]     [,3]
# [1,] 0.1738456 0.5004388 0.127589


stopCluster(CL)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM