假设我将在R中进行caret
训练,但我希望将此训练分成两个运行会话。
library(mlbench)data(Sonar)library(caret)set.seed(998)inTraining <- createDataPartition(Sonar$Class, p = .75, list = FALSE)training <- Sonar[ inTraining,]testing <- Sonar[-inTraining,]# 第一次运行会话nn.partial <- train(Class ~ ., data = training, method = "nnet", max.turns.of.iteration=5) # 不存在的参数。但代表我的目标
假设我只有一个部分对象(即nn.partial
),它包含到第5次迭代的训练信息,而不是完整的nn
对象。因此,在未来,我可以运行下面的代码来完成训练任务:
library(mlbench)data(Sonar)library(caret)set.seed(998)inTraining <- createDataPartition(Sonar$Class, p = .75, list = FALSE)training <- Sonar[ inTraining,]testing <- Sonar[-inTraining,]nn <- train(Class ~ ., data = training, method = "nnet", previous.training=nn.partial) # 不存在的参数。但代表我的目标
我知道train
函数中既没有max.turns.of.iteration
也没有previous.training
这两个参数。我只是尽力用代码表示如果这些参数已经在train
函数中实现了,我理想中的目标是什么。然而,由于这些参数不存在,有没有办法通过某种方式欺骗函数来实现这个目标(即在多个运行中进行caret训练)?
我尝试过使用trainControl
函数,但没有成功。
t.control <- trainControl(repeats=5)nn <- train(Class ~ ., data = training, method = "nnet",trControl = t.control)
通过这种方式,迭代次数仍然远高于我希望在示例中得到的5次。
回答:
我几乎可以肯定,这在caret当前的基础设施中实现起来非常复杂。然而,我将向你展示如何在mlr3中实现这种功能。
示例所需的包
library(mlr3)library(mlr3tuning)library(paradox)
获取示例任务并定义要调整的学习器:
task_sonar <- tsk('sonar')learner <- lrn('classif.rpart', predict_type = 'prob')
定义要调整的超参数:
ps <- ParamSet$new(list( ParamDbl$new("cp", lower = 0.001, upper = 0.1), ParamInt$new("minsplit", lower = 1, upper = 10)))
定义调整器和重采样策略
tuner <- tnr("random_search")cv3 <- rsmp("cv", folds = 3)
定义调整实例
instance <- TuningInstance$new( task = task_sonar, learner = learner, resampling = cv3, measures = msr("classif.auc"), param_set = ps, terminator = term("evals", n_evals = 100) #可以组合多个终止器,例如时钟时间、评估次数、提前停止(停滞)、达到的性能 - ?Terminator)
调整:
tuner$tune(instance)
现在在一秒后按停止以在Rstudio中停止任务
instance$archive() nr batch_nr resample_result task_id learner_id resampling_id iters params tune_x warnings errors classif.auc 1: 1 1 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.7105586 2: 2 2 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.7372720 3: 3 3 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.7335368 4: 4 4 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.7335368 5: 5 5 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.7276246 6: 6 6 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.7111217 7: 7 7 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.6915560 8: 8 8 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.7452875 9: 9 9 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.737272010: 10 10 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.7172328
在我这里,它完成了10次随机搜索的迭代。你现在可以例如调用
save.image()
关闭RStudio并重新打开同一个项目
或者对你希望保留的对象使用saveRDS
/readRDS
saveRDS(instance, "i.rds")instance <- readRDS("i.rds")
在加载所需的包后,继续训练
tuner$tune(instance)
几秒钟后再次停止它:
在我这里,它又完成了额外的12次迭代:
instance$archive() nr batch_nr resample_result task_id learner_id resampling_id iters params tune_x warnings errors classif.auc 1: 1 1 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.7105586 2: 2 2 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.7372720 3: 3 3 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.7335368 4: 4 4 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.7335368 5: 5 5 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.7276246 6: 6 6 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.7111217 7: 7 7 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.6915560 8: 8 8 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.7452875 9: 9 9 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.737272010: 10 10 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.717232811: 11 11 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.732528912: 12 12 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.710558613: 13 13 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.721513314: 14 14 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.691556015: 15 15 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.691556016: 16 16 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.733536817: 17 17 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.727624618: 18 18 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.711121719: 19 19 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.717232820: 20 20 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.727624621: 21 21 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.710558622: 22 22 <ResampleResult> sonar classif.rpart cv 3 <list> <list> 0 0 0.7276246
再次运行它而不按停止
tuner$tune(instance)
它将完成100次评估
限制:上述示例将调整(超参数的评估)分成了多个会话。然而,它没有将一个训练实例分成多个会话 – 在R中很少有包支持这种功能 – 我知道的只有keras/tensorflow支持这种功能。
然而,无论一个算法的训练实例的长度如何,该算法的调整(超参数的评估)需要更多的时间,因此能够像上述示例中那样暂停/恢复调整是更有利的。
如果你觉得这很有趣,这里有一些学习mlr3的资源
https://mlr3book.mlr-org.com/
https://mlr3gallery.mlr-org.com/
也请看一下mlr3pipelines – https://mlr3pipelines.mlr-org.com/articles/introduction.html