Реализация теплых перезапусков в SGD в R (Keras)

Я пытаюсь добавить перезапуски скорости обучения, т. е. мою собственную гораздо менее сложную версию Стохастического градиентного спуска с теплыми перезапусками Лощилова и Хаттера (https://arxiv.org/abs/1608.03983) к моей CNN-модели предиктора последовательности.
Моя идея в качестве первого эксперимента состояла в том, чтобы скорость обучения начинать с 0,3 и уменьшать вдвое в каждую эпоху. Затем в каждую 15-ю эпоху он возвращался к 0,3.

LR<-0.3
optimizer_sgd(lr=LR,nesterov = TRUE)

lr_schedule<-function(epoch) {
    model_big$optimizer$lr=LR/(2 ^ (epoch%%15))
  }

cb_lr<-callback_learning_rate_scheduler(lr_schedule)

model_big%>%
  compile(loss = 'binary_crossentropy',
          optimizer = 'sgd',metrics = 'accuracy')

history<-model_big%>%
  fit(x=list(x1,x2,x3),y=y,epochs = 31,callbacks=c(cb_lr))

Однако я получил следующую ошибку:

    Epoch 1/31
Error in py_call_impl(callable, dots$args, dots$keywords) : 
  RuntimeError: Evaluation error: unused argument (lr = 0.00999999977648258).

Detailed traceback: 
  File "/Users/d/.virtualenvs/r-tensorflow/lib/python2.7/site-packages/keras/engine/training.py", line 1712, in fit
    validation_steps=validation_steps)
  File "/Users/d/.virtualenvs/r-tensorflow/lib/python2.7/site-packages/keras/engine/training.py", line 1180, in _fit_loop
    callbacks.on_epoch_begin(epoch)
  File "/Users/d/.virtualenvs/r-tensorflow/lib/python2.7/site-packages/keras/callbacks.py", line 63, in on_epoch_begin
    callback.on_epoch_begin(epoch, logs)
  File "/Users/d/.virtualenvs/r-tensorflow/lib/python2.7/site-packages/keras/callbacks.py", line 611, in on_epoch_begin
    lr = self.schedule(epoch, lr=lr)
  File "/Library/Frameworks/R.framework/Versions/3.4/Resources/library/reticulate/python/rpytools/call.py", line 21, in python_function
    raise RuntimeError(res[kErrorKey])

Кто-нибудь может помочь, пожалуйста?


person macunaima    schedule 30.06.2018    source источник
comment
Обсуждение на github.com/rstudio/keras/issues/462   -  person Emer    schedule 16.06.2019


Ответы (1)


Как указано skeydan в GitHub Issue, Функция планировщика скорости обучения должна быть определена с двумя параметрами: один для эпохи (индексируется от 0), а другой для текущей скорости обучения. Функция также должна возвращать новое значение скорости обучения. Проверьте документацию для более подробной информации.

Мой вклад в вопрос касается вашего первоначального намерения реализовать SGD с теплыми перезапусками в R Keras. Здесь я делюсь своей реализацией с сообществом.

lr_max <- 1e-2
lr_min <- 1e-5
lr_t_0 <- 10
lr_t_mult <- 2

lr_t_i <- lr_t_0
lr_t_prev <- 0

LearningRateScheduler <- function(epoch, lr) {

  lr_t_curr <- (epoch - lr_t_prev) %% lr_t_i

  new_lr <- (lr_min
             + 1/2 * (lr_max - lr_min)
             * (1 + cos(lr_t_curr / (lr_t_i - 1) * pi)))

  if ((lr_t_curr + 1) == lr_t_i) {
    lr_t_prev <<- epoch + 1
    lr_t_i <<- lr_t_i * lr_t_mult
  }

  new_lr
}

Его можно легко проверить с помощью следующего цикла

epochs <- 150
lr <- numeric(length = epochs)
for (e in seq(1, epochs, by = 1)) {
  lr[e] <- LearningRateScheduler(e - 1, NA)
}

Результаты согласуются с цифрами в упомянутой статье.

SGD с теплыми перезапусками в R Keras

GD с теплыми перезапусками в R Keras в логарифмическом масштабе

person Emer    schedule 16.06.2019