为什么 AdamOptimizer 在我的图表中重复?
Why is AdamOptimizer duplicated in my graph?
我对 TensorFlow 的内部结构还很陌生。为了试图理解 TensorFlow 对 AdamOptimizer 的实现,我查看了 TensorBoard 中的相应子图。似乎有一个名为 name + '_1'
的重复子图,默认情况下为 name='Adam'
。
以下 MWE 生成下图。 (注意我把x
节点展开了!)
import tensorflow as tf
tf.reset_default_graph()
x = tf.Variable(1.0, name='x')
train_step = tf.train.AdamOptimizer(1e-1, name='MyAdam').minimize(x)
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
with tf.summary.FileWriter('./logs/mwe') as writer:
writer.add_graph(sess.graph)
我很困惑,因为我希望上面的代码在图中只生成一个命名空间。即使检查了相关的源文件(即 adam.py
, optimizer.py
and training_ops.cc
),我也不清楚 how/why/where 是否创建了副本。
问题:重复AdamOptimizer
子图的来源是什么?
我能想到以下几种可能:
- 我的代码中有一个错误
- TensorBoard 中生成的某种工件
- 这是预期的行为(如果是,那是为什么?)
- TensorFlow 中的错误
编辑:清理和澄清
由于最初的一些困惑,我用关于如何使用 TensorFlow/TensorBoard 重现此图来设置可重现环境的详细说明使我最初的问题变得混乱。我现在已经用关于扩展 x
节点的说明替换了所有内容。
这不是错误,只是一种可能有问题的泄漏到您自己范围之外的方式。
首先,不是错误:Adam 优化器没有重复。从您的图表中可以看出,只有一个 /MyAdam
范围,而不是两个。这里没问题。
但是, 两个 MyAdam
和 MyAdam_1
子范围 添加到您的变量范围。它们分别对应Adam优化器针对该变量的m
和v
变量(及其初始化操作)。
这是优化器做出的选择值得商榷的地方。您确实可以合理地期望 Adam 优化器操作和变量在其分配的范围内严格定义。相反,他们选择潜入优化变量的范围以定位统计变量。
所以,至少可以说,有争议的选择,但不是错误,因为 Adam 优化器确实没有重复。
编辑
请注意,这种定位变量的方式在优化器中很常见——例如,您可以使用 MomentumOptimizer
观察到相同的效果。实际上,这是创建 slots for optimizers -- see here:
的标准方法
# Scope the slot name in the namespace of the primary variable.
# Set "primary.op.name + '/' + name" as default name, so the scope name of
# optimizer can be shared when reuse is True. Meanwhile when reuse is False
# and the same name has been previously used, the scope name will add '_N'
# as suffix for unique identifications.
所以据我了解,他们选择将变量的统计信息定位在变量本身范围的子范围内,这样如果变量是shared/reused,那么它的统计信息也是shared/reused,不需要重新计算。这确实是一件合理的事情,即使再一次,爬出你的范围有点令人不安。
我对 TensorFlow 的内部结构还很陌生。为了试图理解 TensorFlow 对 AdamOptimizer 的实现,我查看了 TensorBoard 中的相应子图。似乎有一个名为 name + '_1'
的重复子图,默认情况下为 name='Adam'
。
以下 MWE 生成下图。 (注意我把x
节点展开了!)
import tensorflow as tf
tf.reset_default_graph()
x = tf.Variable(1.0, name='x')
train_step = tf.train.AdamOptimizer(1e-1, name='MyAdam').minimize(x)
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
with tf.summary.FileWriter('./logs/mwe') as writer:
writer.add_graph(sess.graph)
我很困惑,因为我希望上面的代码在图中只生成一个命名空间。即使检查了相关的源文件(即 adam.py
, optimizer.py
and training_ops.cc
),我也不清楚 how/why/where 是否创建了副本。
问题:重复AdamOptimizer
子图的来源是什么?
我能想到以下几种可能:
- 我的代码中有一个错误
- TensorBoard 中生成的某种工件
- 这是预期的行为(如果是,那是为什么?)
- TensorFlow 中的错误
编辑:清理和澄清
由于最初的一些困惑,我用关于如何使用 TensorFlow/TensorBoard 重现此图来设置可重现环境的详细说明使我最初的问题变得混乱。我现在已经用关于扩展 x
节点的说明替换了所有内容。
这不是错误,只是一种可能有问题的泄漏到您自己范围之外的方式。
首先,不是错误:Adam 优化器没有重复。从您的图表中可以看出,只有一个 /MyAdam
范围,而不是两个。这里没问题。
但是, 两个 MyAdam
和 MyAdam_1
子范围 添加到您的变量范围。它们分别对应Adam优化器针对该变量的m
和v
变量(及其初始化操作)。
这是优化器做出的选择值得商榷的地方。您确实可以合理地期望 Adam 优化器操作和变量在其分配的范围内严格定义。相反,他们选择潜入优化变量的范围以定位统计变量。
所以,至少可以说,有争议的选择,但不是错误,因为 Adam 优化器确实没有重复。
编辑
请注意,这种定位变量的方式在优化器中很常见——例如,您可以使用 MomentumOptimizer
观察到相同的效果。实际上,这是创建 slots for optimizers -- see here:
# Scope the slot name in the namespace of the primary variable.
# Set "primary.op.name + '/' + name" as default name, so the scope name of
# optimizer can be shared when reuse is True. Meanwhile when reuse is False
# and the same name has been previously used, the scope name will add '_N'
# as suffix for unique identifications.
所以据我了解,他们选择将变量的统计信息定位在变量本身范围的子范围内,这样如果变量是shared/reused,那么它的统计信息也是shared/reused,不需要重新计算。这确实是一件合理的事情,即使再一次,爬出你的范围有点令人不安。