首页 > 解决方案 > 为什么当我增加 maxit 时 nnet 会给出不同的输出以及如何优化 maxit 值?

问题描述

我正在使用带有 nnet 方法的 caret 包。当我将 maxit 参数从 300 更改为 500 时,我得到不同的结果。我的理解是,如果 maxit 增加,模型将经历最大的“n”次迭代以找到局部最小值。

就我而言,当我将 maxit 设置为 300 而不是 500 时,我得到了很好的结果。

注意:种子值、tune_grid、折叠数在两个模型中都相同。

1)我得到不同的结果,因为神经网络优化中有许多局部最小值?

2) maxit 越高,模型越好——对还是错?(基本假设是,如果模型在 300 次迭代中不收敛,则在增加迭代时会收敛)

3)如何调整maxit参数?

标签: rr-caretnnet

解决方案


nnet您指定的方法是使用迭代优化(optim()基础 R 中的函数的 BFGS 方法)来估计模型 [1] 的参数。优化应该在收敛时停止。如果maxit设置得太低,则模型将无法收敛。

BFGS 方法不能保证对所有优化问题都收敛。尽管如此,它被认为是一种很好的优化方法。优化表面取决于数据,因此我不会就您的案例评论最小值的数量或性质。您可能在 300 次迭代时达到了局部最小值,但nnet()函数中存在一些随机性(设置随机权重),因此即使所有nnet()参数相同,后续运行也可能会有所不同。请注意具有相同参数的两个后续运行之间的差异nnet()- 100 次迭代时为 4.115351 与 2.112400。

library(nnet)
data(iris)
set.seed(42)

nnet(Species ~ ., data=iris, size=10)
# weights:  83
initial  value 262.654300
iter  10 value 72.296066
iter  20 value 10.287034
iter  30 value 6.341659
iter  40 value 5.814649
iter  50 value 5.187836
iter  60 value 4.199448
iter  70 value 4.150082
iter  80 value 4.122058
iter  90 value 4.117969
iter 100 value 4.115351
final  value 4.115351
stopped after 100 iterations
a 4-10-3 network with 83 weights
inputs: Sepal.Length Sepal.Width Petal.Length Petal.Width
output(s): Species
options were - softmax modelling

# Deliberately not setting seed value before second nnet run
nnet(Species ~ ., data=iris, size=10)
# weights:  83
initial  value 201.869745
iter  10 value 67.631035
iter  20 value 11.863275
iter  30 value 6.542750
iter  40 value 5.758701
iter  50 value 5.355368
iter  60 value 3.970210
iter  70 value 2.835171
iter  80 value 2.414463
iter  90 value 2.226375
iter 100 value 2.112400
final  value 2.112400
stopped after 100 iterations
a 4-10-3 network with 83 weights
inputs: Sepal.Length Sepal.Width Petal.Length Petal.Width
output(s): Species
options were - softmax modelling

另请注意,上述nnet()运行均未收敛。这是一个融合模型的示例:

set.seed(42)
nnet(Species ~ ., data=iris, size=10, maxit=500)
# weights:  83
initial  value 262.654300
iter  10 value 72.296066
iter  20 value 10.287034
# I've truncated the output here
iter 360 value 0.000277
iter 370 value 0.000117
final  value 0.000097
converged
a 4-10-3 network with 83 weights
inputs: Sepal.Length Sepal.Width Petal.Length Petal.Width
output(s): Species
options were - softmax modelling

注意,上面输出中的“converged”。

不幸的是,无法使用插入符号函数的选项来调整maxit参数。在调用中设置一个较高的值可能是合理的,但我不会推荐一个值,因为它再次依赖于数据。对于 iris 数据,我会尝试一个数量级或两个数量级的值,该数量级高于收敛的最大迭代次数。或者,您可以遍历以下值:tune_gridtrainmaxittrainmaxit

num.it <- 500 # max number of training iterations     
fit.dat <- matrix(ncol=1, nrow=num.it) # fitting criterion values

for(i in 1:num.it) {

    # to monitor progress
    cat(i,'\n') 
    flush.console()

    # to ensure same set of random starting weights are used each time
    set.seed(42)

    # temporary nnet model
    mod.tmp <- nnet(Species ~ ., data=iris, size=10, maxit=i, trace=F)

    # append fitting criterion value
    fit.dat[i,] <- mod.tmp$value             
}

# extract convergence values
which.min(fit.dat)
[1] 375
fit.dat[which.min(fit.dat)]
[1] 9.654717e-05

# plot fitting values
plot(fit.dat, type='l')

上面的循环调整maxit但没有考虑过拟合。更好的方法是将插入符号train()函数与您的当前tune_grid和交叉验证设置一起使用。您还必须检查插入符号train()函数输出是否收敛。

此外,插入符号和其他包可能与 set.seed() 存在令人惊讶的可重复性问题:R:如果加载了插入符号包,则 set.seed() 结果不匹配

最后,它不太可能有帮助,但看看插入符号功能的seeds选项可能会很有趣。trainControl()正如文档所说,它可能仅在运行并行作业时才有用。

[1] https://cran.r-project.org/web/packages/nnet/nnet.pdf


推荐阅读