例如,Keras中Adagrad的实现如下:
class Adagrad(Optimizer):"""Adagrad优化器。建议将此优化器的参数保持在其默认值。# 参数 lr: float >= 0. 学习率。 epsilon: float >= 0. decay: float >= 0. 每次更新的学习率衰减。# 参考文献 - [Adaptive Subgradient Methods for Online Learning and Stochastic Optimization](http://www.jmlr.org/papers/volume12/duchi11a/duchi11a.pdf)"""def __init__(self, lr=0.01, epsilon=1e-8, decay=0., **kwargs): super(Adagrad, self).__init__(**kwargs) self.lr = K.variable(lr) self.epsilon = epsilon self.decay = K.variable(decay) self.initial_decay = decay self.iterations = K.variable(0.)def get_updates(self, params, constraints, loss): grads = self.get_gradients(loss, params) shapes = [K.get_variable_shape(p) for p in params] accumulators = [K.zeros(shape) for shape in shapes] self.weights = accumulators self.updates = [] lr = self.lr if self.initial_decay > 0: lr *= (1. / (1. + self.decay * self.iterations)) self.updates.append(K.update_add(self.iterations, 1)) for p, g, a in zip(params, grads, accumulators): new_a = a + K.square(g) # 更新累加器 self.updates.append(K.update(a, new_a)) new_p = p - lr * g / (K.sqrt(new_a) + self.epsilon) # 应用约束 if p in constraints: c = constraints[p] new_p = c(new_p) self.updates.append(K.update(p, new_p)) return self.updates
‘get_update()’函数似乎是一次更新的步骤。然而,累加器应该存储历史信息吗?为什么每次步骤都初始化为零?它如何在整个训练过程中作为累加器?
这一行代码做什么?
self.weights = accumulators
看起来self.weights再也没有被调用过。
回答:
你是对的…对于Keras中的所有优化器,get_updates()
实现了一步更新的张量逻辑。这个函数在每次model.fit()
调用时,从_make_train_function()
被调用这里,通过将更新规则作为update=
传递来创建张量函数这里。这个更新规则被用于迭代更新模型参数和其他参数。
优化器类的self.weights
是其内部参数。这不用于训练。它只是用于保持优化器的状态(指向参数/累加器张量的指针列表),并且当调用model.save
时,它们通过调用get_weights()
被保存这里,并在调用model.load
时通过set_weights()
被加载回来这里。