Почему nnet дает различный вывод при увеличении maxit и как оптимизировать значение maxit? - PullRequest
0 голосов
/ 16 января 2019

Я использую пакет caret с методом nnet. Я получаю разные результаты, когда меняю параметр maxit с 300 на 500. Насколько я понимаю, если maxit увеличивается, модель будет проходить максимум «n» итераций, чтобы найти локальные минимумы.

В моем случае я получаю хороший результат, когда я устанавливаю maxit равным 300, а не когда он равен 500.

Примечание: начальное значение, tune_grid, количество сгибов одинаково в обеих моделях.

1) Я получаю разные результаты, потому что много локальных минимумов в оптимизации NN?

2) Чем выше максимум, тем лучше модель - True или False? (исходное предположение: если модель не сходится с 300 итерациями, она будет сходиться при увеличении итерации)

3) Как настроить параметр maxit?

1 Ответ

0 голосов
/ 17 января 2019

В методе nnet, который вы указали, используется итерационная оптимизация (метод BFGS из функции optim() в базе R) для оценки параметров модели [1]. Оптимизация должна остановиться, когда она сходится. Если maxit установлено слишком низко, модель не сможет сходиться.

Метод BFGS не гарантированно сходится для всех задач оптимизации. Тем не менее это считается хорошим методом оптимизации. Поверхность оптимизации зависит от данных, поэтому я не буду комментировать количество или характер минимумов для вашего случая. Возможно, вы достигли локального минимума за 300 итераций, но в функции nnet() (установка случайных весов) есть некоторая стохастичность, поэтому последующие прогоны могут отличаться, даже если все параметры nnet() идентичны. Обратите внимание на разницу между двумя последующими nnet() прогонами с одинаковыми параметрами - 4.115351 против 2.112400 при 100 итерациях.

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

Обратите внимание, "сходятся" в выводе выше.

К сожалению, невозможно настроить параметр maxit с помощью опции tune_grid для функции caret train. Вероятно, разумно установить высокое значение для maxit в вызове train, но я не буду рекомендовать значение, потому что опять-таки оно зависит от данных. Для данных радужной оболочки я бы попробовал значение, которое на порядок или два больше, чем наибольшее число сходящихся итераций. В качестве альтернативы вы можете зациклить значения для maxit:

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, но не учитывает перенастройку. Лучшим подходом было бы использовать функцию caret train() с текущими настройками tune_grid и перекрестной проверки. Вы также должны проверить вывод функции caret train() на сходимость.

Кроме того, у пакета caret и других пакетов могут возникнуть неожиданные проблемы с воспроизводимостью с помощью set.seed (): R: set.seed () результаты не совпадают, если загружен пакет caret

Наконец, это вряд ли поможет, но может быть интересно взглянуть на параметр seeds для функции trainControl(). Как говорят в документации, это, вероятно, полезно только при выполнении параллельных заданий.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...