如何在Keras或Theano中实现具有指数衰减学习率的卷积神经网络

时间:2016-10-27 02:44:59

标签: python machine-learning neural-network theano keras

我想在Keras或Theano中实现具有指数衰减学习率的卷积神经网络(CNN)。学习率根据以下更新法动态更改:

eta = et0*exp(LossFunction)
where et0 is the initial learning rate and LossFunction is a cost function

我知道Keras允许设置SGD优化器:

SGD(lr, momentum0, decay, nesterov) 

衰减期仅允许每个时期的固定衰减学习率衰减。

如何使用在成本函数方面呈指数衰减的学习率来设置或编码SGD?为了您的信息,我在Keras发布了SGD的源代码:

class SGD(Optimizer):

'''Stochastic gradient descent, with support for momentum,
learning rate decay, and Nesterov momentum.


# Arguments
    lr: float >= 0. Learning rate.
    momentum: float >= 0. Parameter updates momentum.
    decay: float >= 0. Learning rate decay over each update.
    nesterov: boolean. Whether to apply Nesterov momentum.
'''

def __init__(self, lr=0.01, momentum=0., decay=0.,

             nesterov=False, **kwargs):

    super(SGD, self).__init__(**kwargs)
    self.__dict__.update(locals())
    self.iterations = K.variable(0.)
    self.lr = K.variable(lr)
    self.momentum = K.variable(momentum)
    self.decay = K.variable(decay)
    self.inital_decay = decay

def get_updates(self, params, constraints, loss):
    grads = self.get_gradients(loss, params)
    self.updates = []

    lr = self.lr
    if self.inital_decay > 0:
        lr *= (1. / (1. + self.decay * self.iterations))
        self.updates .append(K.update_add(self.iterations, 1))

    # momentum
    shapes = [K.get_variable_shape(p) for p in params]
    moments = [K.zeros(shape) for shape in shapes]
    self.weights = [self.iterations] + moments

    for p, g, m in zip(params, grads, moments):
        v = self.momentum * m - lr * g  # velocity
        self.updates.append(K.update(m, v))

        if self.nesterov:
            new_p = p + self.momentum * v - lr * g
        else:
            new_p = p + v

        # apply constraints
        if p in constraints:
            c = constraints[p]
            new_p = c(new_p)

        self.updates.append(K.update(p, new_p))
    return self.updates

def get_config(self):
    config = {'lr': float(K.get_value(self.lr)),
              'momentum': float(K.get_value(self.momentum)),
              'decay': float(K.get_value(self.decay)),
              'nesterov': self.nesterov}

    base_config = super(SGD, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

2 个答案:

答案 0 :(得分:1)

我认为您可以使用以下架构获取行为:

  1. 使用this创建新的学习速率控制器类。
  2. 在提供给fit方法时,让构造函数接受训练集并开始学习率。
  3. 让它计算每个纪元后的损失并更新学习率。

答案 1 :(得分:0)

Keras具有用于计划学习率的内置功能。您可以查看here中的Keras回调文档。这是一个示例:

from keras.callbacks import LearningRateScheduler

LearningRateScheduler(schedule)函数采用一个称为调度功能的输入。

您可以定义一个计划学习率衰减的函数。此函数将以epoch作为输入参数。逐步衰减的示例:

 def step_decay(epoch):
     initial_lrate = 0.00125
     drop = 0.5
     epochs_drop = 10.0
     lrate = initial_lrate * math.pow(drop,  
             math.floor((1+epoch)/epochs_drop))
     return lrate

现在使用此功能创建学习率计划程序。

lrScheduler = LearningRateScheduler(step_decay)

在您的model.compile中,将此调度程序传递给回调参数

model.compile(...,callbacks=lrScheduler,...)

类似地,对于每个时期或每次迭代的指数衰减,请创建一个函数,然后在学习速率调度器中调用该函数。

我希望这种解释对您有所帮助。