Tensorflow多GPU培训和可变范围

时间:2017-04-04 16:24:30

标签: tensorflow computer-vision

上下文

我正在使用Tensorflow 1.0在多个GPU上运行探测器模型。根据建议here,梯度是在多个GPU上单独计算的,并在CPU上进行平均。要在GPU塔上共享可训练变量(例如权重和偏差),使用reuse打开tf.get_variable_scope().reuse_variables()标志,如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的单独模块(源代码已链接)。

line 62的{​​{1}}中,它使用slot_creator。这在0.12中曾是variable_scope.get_variable()

我对变量范围的理解是,如果tf.Variable()标志打开,variable_scope.get_variable()将无法创建变量。有关源代码,请参阅here

但Tensorflow创建者的cifar10示例似乎建议使用reuse启用重用以跨GPU塔共享变量。这种情况发生在之前我们平均并应用渐变。看起来Tensorflow 1.0拒绝为tf.get_variable_scope().reuse_variables()创建变量。

对于直接或间接调用AdamOptimizer模块的所有优化器都会发生这种情况。

问题

作为快速修复,我在slot_creator类中添加了一个自定义函数,以便在调用VariableScope之前禁用_reuse标志。但是,我确信强制opt.apply_gradients标志仅设置为reuse是有好处的。我不确定更好的解决方法是什么。有什么建议吗?

1 个答案:

答案 0 :(得分:0)

在cifar10代码中,在grads = opt.compute_gradients(loss)行前面移动tf.get_variable_scope().reuse_variables()可以解决问题。