【问题标题】:R doesn't reset the seed when "L'Ecuyer-CMRG" RNG is used?使用“L'Ecuyer-CMRG”RNG 时,R 不会重置种子?
【发布时间】:2013-02-10 19:08:51
【问题描述】:

我在 R 中进行了一些并行模拟,我注意到种子 使用“L'Ecuyer-CMRG”rng 时不会更改。我在读 “Parallel R”一书,选项 mc.set.seed = TRUE 应该给出 每次调用 mclapply() 时,每个工人都有一个新种子。

这是我的代码:

library(parallel)
RNGkind("L'Ecuyer-CMRG")

mclapply(1:2, function(n) rnorm(n), mc.set.seed = TRUE)
[[1]]
[1] -0.7125037

[[2]]
[1] -0.9013552  0.3445190

mclapply(1:2, function(n) rnorm(n), mc.set.seed = TRUE)
[[1]]
[1] -0.7125037

[[2]]
[1] -0.9013552  0.3445190

编辑:我的台式机和笔记本电脑(都是 Ubuntu 12.04 LTS)上都会发生同样的事情。

【问题讨论】:

  • 您使用的是 Windows 还是 UNIX?看起来这个选项在 Windows 上被忽略了。
  • 在带有multicore 包的mac 上对我来说很好。
  • 这适用于我在 Windows 7 和 R-2.15-2 中。我每次都得到不同的值。
  • 我使用的是 Ubuntu 12.04 LTS,只有当我使用 RNGkind("L'Ecuyer-CMRG") 其他 rng 工作正常时才会出现这个问题。

标签: r parallel-processing prng


【解决方案1】:

在我看来,如果您想保证在 R 会话中对 mclapply 的后续调用获得不同的随机数,您需要使用不同的值调用 set.seed,删除全局变量“.Random.seed” ,或者在再次调用 mclapply 之前在该 R 会话中生成至少一个随机数。

这种行为的原因是 mclapply(例如与 mcparallel 不同)在内部调用 mc.reset.stream。这会将隐藏在“parallel”包中的种子重置为“.Random.seed”的值,因此如果再次调用 mclapply 时“.Random.seed”没有更改,则由 mclapply 启动的工作人员将获得与以前相同的随机数。

请注意,对于 clusterApply 和 parLapply 等函数,情况并非如此,因为它们使用持久性工作者,因此会继续从其 RNG 流中提取随机数。但是每次调用 mclapply 时都会派生新的工作人员,这可能会使这种行为变得更加困难。

这是一个使用 mclapply 将种子设置为不同值以获取不同随机数的示例:

RNGkind("L'Ecuyer-CMRG")
set.seed(100)
mclapply(1:2, function(i) rnorm(2))
set.seed(101)
mclapply(1:2, function(i) rnorm(2))

以下是删除“.Random.seed”的示例:

RNGkind("L'Ecuyer-CMRG")
mclapply(1:2, function(i) rnorm(2))
rm(.Random.seed)
mclapply(1:2, function(i) rnorm(2))

下面是一个在master上生成随机数的例子:

RNGkind("L'Ecuyer-CMRG")
mclapply(1:2, function(i) rnorm(2))
rnorm(1)
mclapply(1:2, function(i) rnorm(2))

我不确定哪个是最好的方法,但这可能取决于你想要做什么。

虽然看起来简单地多次调用 mclapply 而不更改“.Random.seed”会产生可重现的结果,但我不知道这是否得到保证。为了保证可重现的结果,我认为您需要调用 set.seed:

RNGkind("L'Ecuyer-CMRG")
set.seed(1234)
mclapply(1:2, function(i) rnorm(2))
set.seed(1234)
mclapply(1:2, function(i) rnorm(2))

【讨论】:

  • 感谢史蒂夫的回答! (不能投票,因为我没有足够的声誉)。看起来很奇怪的是,这种行为应该发生在不同的平台上,而我的问题中的代码看起来在@Andrie Windows 7 上的每个 mclapply() 调用上给出了不同的结果。
  • 奇怪的是我没想到parallel在Windows上提供了mclapply功能。
  • 这也是真的!除了 RNG,在我的系统中还有许多其他奇怪的事情发生:1)如果我使用 mclapply 并且经常加载“调试”包 R 冻结,我必须杀死它和它的工作人员 2)选项(核心 = 检测核心()) 根本不起作用,我总是必须在 mclapply 中手动选择核心数。
  • 他们将选项名称从“cores”更改为“mc.cores”,因此您必须使用 options(mc.cores=detectCores()) 才能使用 mclapply 的并行版本。
  • @SteveWeston,感谢您的回答。它帮助我解决了我正在努力解决的问题。但是,我担心这种方法可能会导致一些难以调试的副作用。是否可以快速浏览一下这个问题:stackoverflow.com/q/68638116/5252007?我很感激。
【解决方案2】:

您是否考虑过使用clusterApply 而不是mclapply? 我认为使用这个框架更容易保证可重现的示例。我附上一个例子。

library(parallel)

#---- creating local cluster ----

clust <- makeCluster(detectCores())

#---- seed ----

RNGkind(kind = "L'Ecuyer-CMRG")
set.seed(1234)
s <- .Random.seed
clusterSetRNGStream(cl = clust, iseed = s)

#---- generating random numbers ----

clusterApply(cl = clust, x = 1:2, fun = function(i) rnorm(2))
#> [[1]]
#> [1] -0.0514128  0.7344781
#> 
#> [[2]]
#> [1]  0.3946233 -0.6649782
clusterApply(cl = clust, x = 1:2, fun = function(i) rnorm(2))
#> [[1]]
#> [1] -1.57875323 -0.07533176
#> 
#> [[2]]
#> [1] -0.3698359 -0.1564795

#---- repeating the process ----

set.seed(1234)
s <- .Random.seed
clusterSetRNGStream(cl = clust, iseed = s)

clusterApply(cl = clust, x = 1:2, fun = function(i) rnorm(2))
#> [[1]]
#> [1] -0.0514128  0.7344781
#> 
#> [[2]]
#> [1]  0.3946233 -0.6649782
clusterApply(cl = clust, x = 1:2, fun = function(i) rnorm(2))
#> [[1]]
#> [1] -1.57875323 -0.07533176
#> 
#> [[2]]
#> [1] -0.3698359 -0.1564795

# same result

reprex package (v0.2.1) 于 2019 年 3 月 4 日创建

devtools::session_info()
#> Session info -------------------------------------------------------------
#>  setting  value                       
#>  version  R version 3.5.1 (2018-07-02)
#>  system   x86_64, linux-gnu           
#>  ui       X11                         
#>  language (EN)                        
#>  collate  en_US.UTF-8                 
#>  tz       America/Sao_Paulo           
#>  date     2019-03-04
#> Packages -----------------------------------------------------------------
#>  package   * version date       source         
#>  backports   1.1.2   2017-12-13 CRAN (R 3.5.0) 
#>  base      * 3.5.1   2018-07-03 local          
#>  compiler    3.5.1   2018-07-03 local          
#>  datasets  * 3.5.1   2018-07-03 local          
#>  devtools    1.13.6  2018-06-27 CRAN (R 3.5.0) 
#>  digest      0.6.17  2018-09-12 cran (@0.6.17) 
#>  evaluate    0.11    2018-07-17 cran (@0.11)   
#>  graphics  * 3.5.1   2018-07-03 local          
#>  grDevices * 3.5.1   2018-07-03 local          
#>  htmltools   0.3.6   2017-04-28 CRAN (R 3.5.0) 
#>  knitr       1.20    2018-02-20 CRAN (R 3.5.0) 
#>  magrittr    1.5     2014-11-22 cran (@1.5)    
#>  memoise     1.1.0   2017-04-21 CRAN (R 3.5.0) 
#>  methods   * 3.5.1   2018-07-03 local          
#>  parallel  * 3.5.1   2018-07-03 local          
#>  Rcpp        0.12.18 2018-07-23 cran (@0.12.18)
#>  rmarkdown   1.10    2018-06-11 CRAN (R 3.5.1) 
#>  rprojroot   1.3-2   2018-01-03 CRAN (R 3.5.0) 
#>  stats     * 3.5.1   2018-07-03 local          
#>  stringi     1.2.4   2018-07-20 cran (@1.2.4)  
#>  stringr     1.3.1   2018-05-10 CRAN (R 3.5.0) 
#>  tools       3.5.1   2018-07-03 local          
#>  utils     * 3.5.1   2018-07-03 local          
#>  withr       2.1.2   2018-03-15 CRAN (R 3.5.0) 
#>  yaml        2.2.0   2018-07-25 cran (@2.2.0)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-11
    • 1970-01-01
    • 2013-01-01
    • 2020-04-25
    • 1970-01-01
    • 2013-12-09
    • 2011-01-04
    • 1970-01-01
    相关资源
    最近更新 更多