停止德雷克计划使其重建之前已经建立的目标

Halting drake plan makes it rebuild targets it already had built previously

我目前正在使用 drake 到 运行 一组 >1k 的模拟。我估计 运行 完成整个集大约需要两天时间,但我也希望我的计算机在这段时间内随时崩溃,因为它确实如此。

显然,停止该计划会丢弃任何已经构建的目标,所以基本上这意味着我无法将 drake 用于其预期目的。

我想我可以创建一个函数来实际编辑指定计划的 R 文件,以便 drake 按顺序将目标添加到其缓存中,但这似乎完全是 hackish。

关于如何处理这个问题有什么想法吗?

编辑:实际问题似乎来自在我的数据生成函数中使用 set.seed。我知道 drake 已经以确保可重复性的方式为用户执行此操作,但我认为如果我只是按原样保留我的功能,它不会改变任何东西,因为 drake 会是确保我选择的随机种子最终总是相同的?猜不出来,但自从我删除了那一步后,一切都很好地缓存了,所以问题就解决了。

为了让围观的人跟上速度,我会尽量把问题说清楚。 @zipzapboing,如果我的描述偏离目标,请纠正我。

假设您有一个生成 drake plan 并执行它的脚本。

library(drake)

simulate_data <- function(seed){
  set.seed(seed)
  rnorm(100)
}

seed_grid <- data.frame(
  id = paste0("target_", 1:3),
  seed = sample.int(1e6, 3)
)

print(seed_grid)
#>         id   seed
#> 1 target_1 581687
#> 2 target_2 700363
#> 3 target_3 914982

plan <- map_plan(seed_grid, simulate_data)

print(plan)
#> # A tibble: 3 x 2
#>   target   command                      
#>   <chr>    <chr>                        
#> 1 target_1 simulate_data(seed = 581687L)
#> 2 target_2 simulate_data(seed = 700363L)
#> 3 target_3 simulate_data(seed = 914982L)

make(plan)
#> target target_1
#> target target_2
#> target target_3
make(plan)
#> All targets are already up to date.

reprex package (v0.2.1)

创建于 2018-11-12

第二个 make() 工作得很好,对吧?但是,如果您要 运行 在不同的会话中使用相同的脚本,您最终会得到不同的计划。 simulate_data() 的随机生成的 seed 参数会有所不同,因此您的所有目标都将从头开始构建。

library(drake)

simulate_data <- function(seed){
  set.seed(seed)
  rnorm(100)
}

seed_grid <- data.frame(
  id = paste0("target_", 1:3),
  seed = sample.int(1e6, 3)
)

print(seed_grid)
#>         id   seed
#> 1 target_1 654304
#> 2 target_2 252208
#> 3 target_3 781158

plan <- map_plan(seed_grid, simulate_data)

print(plan)
#> # A tibble: 3 x 2
#>   target   command                      
#>   <chr>    <chr>                        
#> 1 target_1 simulate_data(seed = 654304L)
#> 2 target_2 simulate_data(seed = 252208L)
#> 3 target_3 simulate_data(seed = 781158L)

make(plan)
#> target target_1
#> target target_2
#> target target_3

reprex package (v0.2.1)

创建于 2018-11-12

一个解决方案是格外小心地抓住同一个 plan。但是,还有一个更简单的方法:让 drake 为您设置种子。 drake 自动为每个目标提供其自己的可复制随机种子。这些目标级种子由根种子(make()seed 参数)和目标名称确定地生成。

library(digest)
library(drake)
library(magrittr) # defines %>%

simulate_data <- function(){
  mean(rnorm(100))
}

plan <- drake_plan(target = simulate_data()) %>%
  expand_plan(values = 1:3)

print(plan)
#> # A tibble: 3 x 2
#>   target   command        
#>   <chr>    <chr>          
#> 1 target_1 simulate_data()
#> 2 target_2 simulate_data()
#> 3 target_3 simulate_data()

tmp <- rnorm(1)
digest(.Random.seed) # Fingerprint of the current seed.
#> [1] "0bbddc33a4afe7cd1c1742223764661c"

make(plan)
#> target target_1
#> target target_2
#> target target_3
make(plan)
#> All targets are already up to date.

# The targets have different seeds and different values.
readd(target_1)
#> [1] -0.05530201
readd(target_2)
#> [1] 0.03698055
readd(target_3)
#> [1] 0.05990671

clean() # Destroy the targets.
tmp <- rnorm(1) # Change the global seed.
digest(.Random.seed) # The seed changed.
#> [1] "5993aa5cff4b72a0e14fa58dc5c5e3bf"

make(plan)
#> target target_1
#> target target_2
#> target target_3

# The targets were regenerated with the same values (same seeds).
readd(target_1)
#> [1] -0.05530201
readd(target_2)
#> [1] 0.03698055
readd(target_3)
#> [1] 0.05990671

# You can recover a target's seed from its metadata.
seed <- diagnose(target_1)$seed
print(seed)
#> [1] 1875584181

# And you can use that seed to reproduce
# the target's value outside make().
set.seed(seed)
mean(rnorm(100))
#> [1] -0.05530201

reprex package (v0.2.1)

创建于 2018-11-12

我真的应该在 manual 中写更多关于种子如何在 drake 中工作的内容,并突出显示此线程中提出的原始陷阱。我怀疑你是唯一遇到这个问题的人。