TensorFlow 优化器是否学习带有分配的图形中的梯度?
Do TensorFlow optimizers learn gradients in a graph with assignments?
我正在复制 Elman 网络 (Elman, 1990) 的原始论文——连同 Jordan 网络,称为简单循环网络 (SRN)。据我所知,我的代码正确地实现了前向传播,而学习阶段是不完整的。我在 Python.
中使用 TensorFlow 的低级 API 实现网络
Elman 网络是由两层组成的人工神经网络,其中隐藏层被复制为 "context layer,",在我们下次 运行 前向传播网络时与输入连接。最初,上下文层初始化为 activation = 0.5 并具有固定权重 1.0.
我的问题是关于梯度的计算,在网络的反向传播中。在我的代码中,我使用 tf.assign
通过隐藏层的激活来更新上下文单元。在将赋值运算符添加到图形之前,TensorBoard 显示 GradientDescentOptimizer 将从图形中的所有变量学习梯度。在我包含此语句后,渐变不会显示为来自 "before" 分配的节点中的变量。换句话说,我希望 b_1
、w_x
、w_c
和 a_1
出现在优化器学习的梯度列表中,即使在图。
我相信我的前向传播实现是正确的,因为我比较了使用 tf.assign
的激活的最终值和使用普通 Numpy 数组的另一个实现的值。值相等。
最后:这种行为是故意的还是我做错了什么?
这是一个笔记本,其中包含我所描述的网络实现:
https://gist.github.com/Irio/d00b9661023923be7c963395483dfd73
参考文献
埃尔曼,J.L.(1990 年)。在时间中寻找结构。认知科学,14(2),179-211。检索自 https://crl.ucsd.edu/~elman/Papers/fsit.pdf
不,分配操作不会反向传播梯度。这是故意的,因为为变量赋值不是可微分操作。但是,您可能不想要赋值的梯度,而是变量新值的梯度。您可以使用该梯度,但不要将其用作赋值操作的输出。例如,您可以这样做:
import tensorflow as tf
my_var = tf.Variable(var_intial_value, name="MyVar")
# Compute new value for the variable
new_my_var = ...
# Make the assignment operation a control dependency
with tf.control_dependencies([tf.assign(my_var, new_my_var)]):
# Passing the value through identity here will ensure assignment is done
# while keeping it differentiable
new_my_var = tf.identity(new_my_var)
# Continue using the value
这意味着 my_var
不用于反向传播,因此优化器不会对其进行更新。但是,我想如果你自己给 my_var
赋值,那么它不应该被优化器更新。
我正在复制 Elman 网络 (Elman, 1990) 的原始论文——连同 Jordan 网络,称为简单循环网络 (SRN)。据我所知,我的代码正确地实现了前向传播,而学习阶段是不完整的。我在 Python.
中使用 TensorFlow 的低级 API 实现网络Elman 网络是由两层组成的人工神经网络,其中隐藏层被复制为 "context layer,",在我们下次 运行 前向传播网络时与输入连接。最初,上下文层初始化为 activation = 0.5 并具有固定权重 1.0.
我的问题是关于梯度的计算,在网络的反向传播中。在我的代码中,我使用 tf.assign
通过隐藏层的激活来更新上下文单元。在将赋值运算符添加到图形之前,TensorBoard 显示 GradientDescentOptimizer 将从图形中的所有变量学习梯度。在我包含此语句后,渐变不会显示为来自 "before" 分配的节点中的变量。换句话说,我希望 b_1
、w_x
、w_c
和 a_1
出现在优化器学习的梯度列表中,即使在图。
我相信我的前向传播实现是正确的,因为我比较了使用 tf.assign
的激活的最终值和使用普通 Numpy 数组的另一个实现的值。值相等。
最后:这种行为是故意的还是我做错了什么?
这是一个笔记本,其中包含我所描述的网络实现:
https://gist.github.com/Irio/d00b9661023923be7c963395483dfd73
参考文献
埃尔曼,J.L.(1990 年)。在时间中寻找结构。认知科学,14(2),179-211。检索自 https://crl.ucsd.edu/~elman/Papers/fsit.pdf
不,分配操作不会反向传播梯度。这是故意的,因为为变量赋值不是可微分操作。但是,您可能不想要赋值的梯度,而是变量新值的梯度。您可以使用该梯度,但不要将其用作赋值操作的输出。例如,您可以这样做:
import tensorflow as tf
my_var = tf.Variable(var_intial_value, name="MyVar")
# Compute new value for the variable
new_my_var = ...
# Make the assignment operation a control dependency
with tf.control_dependencies([tf.assign(my_var, new_my_var)]):
# Passing the value through identity here will ensure assignment is done
# while keeping it differentiable
new_my_var = tf.identity(new_my_var)
# Continue using the value
这意味着 my_var
不用于反向传播,因此优化器不会对其进行更新。但是,我想如果你自己给 my_var
赋值,那么它不应该被优化器更新。