【发布时间】:2017-04-04 16:24:29
【问题描述】:
上下文
我正在使用 Tensorflow 1.0 在多个 GPU 上开发检测器模型。正如here 建议的那样,梯度是在多个 GPU 上单独计算的,并在 CPU 上进行平均。为了在 GPU 塔之间共享可训练变量(例如权重和偏差),使用 tf.get_variable_scope().reuse_variables() 打开 reuse 标志,如 cifar10 示例中所示。不同之处在于我使用的是AdamOptimizer 而不是GradientDescentOptimizer。
问题
当我运行训练作业时,它会打印出很长的堆栈跟踪,并在 opt.apply_gradients() 处引发以下错误:
ValueError: Variable conv1_1/kernel/Adam/ does not exist, or was not created with tf.get_variable(). Did you mean to set reuse=None in VarScope?
分析
查看源代码我发现AdamOptimizer 在_create_slots() 方法中创建了许多零初始化槽,其中它调用_zeros_slot()。这会调用一个名为slot_creator(源代码链接)的单独模块。
在slot_creator 的line 62 中,它使用variable_scope.get_variable()。这曾经是 0.12 中的 tf.Variable()。
我对变量作用域的理解是variable_scope.get_variable() 将无法创建变量如果reuse 标志打开`。源代码见here。
但 Tensorflow 创建者的 cifar10 示例似乎建议使用 tf.get_variable_scope().reuse_variables() 启用重用以在 GPU 塔之间共享变量。这发生在在我们平均和应用梯度之前。看起来 Tensorflow 1.0 拒绝为 AdamOptimizer 创建变量。
所有直接或间接调用 slot_creator 模块的优化器都会发生这种情况。
问题
作为快速修复,我在VariableScope 类中添加了一个自定义函数,以在调用opt.apply_gradients 之前禁用_reuse 标志。但是,我确信强制将reuse 标志设置为True 是有好处的。我不确定更好的解决方法是什么。有什么建议吗?
【问题讨论】:
标签: tensorflow computer-vision