План остановки дракона заставляет его восстанавливать цели, которые он уже построил ранее
Я сейчас пользуюсь drake
запустить набор из>1k моделирования. Я подсчитал, что на запуск комплекта уйдет около двух дней, но я также ожидаю, что мой компьютер в любой момент в тот период выйдет из строя, потому что, ну, в общем-то, так и есть.
Очевидно, что остановка плана отменяет все цели, которые уже были построены, так что по сути это означает, что я не могу использовать drake
по прямому назначению.
Я полагаю, я мог бы сделать функцию, которая на самом деле редактирует R-файл, где указан план, чтобы сделать drake
последовательно добавлять цели в свой кеш, но это кажется совершенно хакерским.
Есть идеи как с этим бороться?
РЕДАКТИРОВАТЬ: реальная проблема, кажется, исходит от использования set.seed
внутри моих функций генерации данных. Я знал, что drake
уже делает это для пользователя таким образом, чтобы обеспечить воспроизводимость, но я решил, что если я просто оставлю свои функции такими, какими они были, это ничего не изменит, поскольку drake
будет гарантировать, что случайное семя, которое я выбрал, всегда будет одинаковым? Не думаю, но, так как я удалил этот шаг, все кэшируется нормально, поэтому проблема решена.
1 ответ
Чтобы привлечь внимание зрителей, я постараюсь разобрать проблему. @zipzapboing, пожалуйста, поправьте меня, если мое описание не соответствует цели.
Допустим, у вас есть скрипт, который генерирует drake
планировать и выполнять его.
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.
Создано в 2018-11-12 пакетом представлением (v0.2.1)
Второй make()
работал просто отлично, верно? Но если бы вы запускали один и тот же сценарий в другом сеансе, у вас был бы другой план. Случайно сгенерированный seed
аргументы simulate_data()
будет отличаться, поэтому все ваши цели будут строиться с нуля.
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
Создано в 2018-11-12 пакетом представлением (v0.2.1)
Одно из решений заключается в том, чтобы быть очень осторожным, чтобы держаться за то же самое plan
, Однако есть еще более простой способ: просто drake
установить семена для вас. drake
автоматически дает каждой цели свое собственное воспроизводимое случайное семя. Эти семена целевого уровня детерминированно генерируются корневым семенем (seed
аргумент make()
) и названия целей.
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
Создано в 2018-11-12 пакетом представлением (v0.2.1)
Я действительно должен написать больше в руководстве о том, как семена работают в drake
и выделите оригинальную ловушку, поднятую в этой теме. Я сомневаюсь, что вы единственный, кто боролся с этой проблемой.