关于tf.zeros()返回值与Keras SGD优化器get_updates模块的技术问询
问题解答
1. tf.zeros() 是否会返回 tf.get_variable()?
完全不会,这两个函数的返回值本质天差地别:
tf.zeros()返回的是常量张量(Tensor),它的值固定为零,无法通过K.update()这类操作修改,也不会被当作模型参数或优化器的状态变量。tf.get_variable()是用来创建或获取可更新的变量(Variable),这类对象能在训练过程中被修改,常用来存储模型权重、优化器的状态(比如动量项、Adam的一阶/二阶矩)等。
举个直观的例子:
import tensorflow as tf # 常量零张量,无法被更新 zero_tensor = tf.zeros([2,2]) # 可更新的变量,初始值为零 zero_var = tf.get_variable("zero_var", shape=[2,2], initializer=tf.zeros_initializer())
2. Keras SGD优化器动量部分代码逻辑解析
咱们逐行拆解你给出的这段代码(K = keras.backend):
代码行逐一解读
shapes = [K.int_shape(p) for p in params]
获取所有模型可训练参数的形状,因为动量项需要和对应参数保持相同形状,才能正确累积梯度信息。moments = [K.zeros(shape) for shape in shapes]
这里用K.zeros创建了一组零初始化的张量,但要注意:这些张量并不是最终的常量,当它们被加入到self.weights后,Keras会自动将其转换为优化器的状态变量(Variable),用来存储每个参数的动量累积值。self.weights = [self.iterations] + moments
将优化器的迭代次数(self.iterations,用来跟踪训练步数)和所有动量项都标记为优化器的权重,这些状态会在训练过程中被持久化、持续更新,不会随着批次结束而重置。循环核心逻辑:
for p, g, m in zip(params, grads, moments): v = self.momentum * m - lr * g # velocity self.updates.append(K.update(m, v))
p是模型的可训练参数,g是该参数对应的梯度,m是该参数对应的动量状态变量。- 动量更新公式
v = self.momentum * m - lr * g:这里的逻辑是让动量项m保留上一次的动量(乘以动量系数self.momentum),再叠加当前梯度的反向更新(-lr * g,因为梯度是损失对参数的导数,要往损失减小的方向更新,所以用减号)。 K.update(m, v)是把动量变量m的值更新为新计算的v,在TensorFlow后端,这个操作本质是对Variable进行赋值,所以每一批次训练都会更新动量状态。
核心逻辑总结
动量优化的本质是通过累积过去的梯度信息,让参数更新更平滑(避免震荡)。这段代码里的moments从初始零张量转化为优化器的状态变量,在训练过程中不断累积梯度的“动量”,最终实现带动量的SGD更新。
内容的提问来源于stack exchange,提问作者dashnick
相关产品推荐
相关产品推荐

