Как я могу создать расписание скорости обучения Keras, которое обновляется на основе пакетов, а не эпох - PullRequest
1 голос
/ 07 апреля 2020

Я работаю с Keras и пытаюсь создать планировщик скорости обучения, который планирует на основе количества обработанных пакетов, а не количества эпох. Для этого я вставил код планирования в метод get_updates моего "Оптимизатора". По большей части я пытался использовать обычные переменные Python для значений, которые остаются постоянными во время данного тренинга, а узлы вычислительного графа - только для параметров, которые действительно меняются.

Мои 2 вопроса:

  1. Похоже ли приведенный ниже код, что он должен вести себя должным образом, как планировщик скорости обучения, если он помещен в метод get_updates метода Keras Optimizer.

  2. Как можно встроить этот код в класс, аналогичный LearningRateScheduler, но который запланирован на основе количества пакетов, а не количества эпох?


    #Copying graph node that stores original value of learning rate
    lr = self.lr 

    # Checking whether learning rate schedule is to be used
    if self.initial_lr_decay > 0:
        # this decay mimics exponential decay from 
        # tensorflow/python/keras/optimizer_v2/exponential_decay 

        # Get value of current number of processed batches from graph node
        # and convert to numeric value for use in K.pow()
        curr_batch = float(K.get_value(self.iterations))

        # Create graph node containing lr decay factor
        # Note: self.lr_decay_steps is a number, not a node
        #       self.lr_decay is a node, not a number
        decay_factor =  K.pow(self.lr_decay, (curr_batch / self.lr_decay_steps)) 

        # Reassign lr to graph node formed by
        # product of graph node containing decay factor
        # and graph node containing original learning rate.
        lr = lr * decay_factor

        # Get product of two numbers to calculate number of batches processed
        # in warmup period
        num_warmup_batches = self.steps_per_epoch_num * self.warmup_epochs

        # Make comparisons between numbers to determine if we're in warmup period
        if (self.warmup_epochs > 0) and (curr_batch < num_warmup_batches):

            # Create node with value of learning rate by multiplying a number
            # by a node, and then dividing by a number
            lr = (self.initial_lr  *
                  K.cast(self.iterations, K.floatx()) / curr_batch)

1 Ответ

1 голос
/ 07 апреля 2020

Проще, чем возиться с исходным кодом Keras (это возможно, но это сложно и разумно), вы можете использовать обратный вызов.

from keras.callbacks import LambdaCallback

total_batches = 0
def what_to_do_when_batch_ends(batch, logs):
   total_batches += 1 #or use the "batch" variable,
                      #which is the batch index of the last finished batch

   #change learning rate at will
   if your_condition == True:
       keras.backend.set_value(model.optimizer.lr, newLrValueAsPythonFloat)

При обучении используйте обратный вызов:

lrUpdater = LambdaCallback(on_batch_end = what_to_do_when_batch_ends)
model.fit(........, callbacks = [lrUpdater, ...other callbacks...])
...