首页 文章

Tensorflow多GPU培训和可变范围

提问于
浏览
0

Context

我正在使用Tensorflow 1.0在多个GPU上研究探测器模型 . 正如建议here,梯度是在多个GPU上单独计算的,并在CPU上取平均值 . 要在GPU塔之间共享可训练变量(例如权重和偏差), reuse 标志将使用 tf.get_variable_scope().reuse_variables() 打开,如cifar10示例中所示 . 区别在于我使用 AdamOptimizer 而不是 GradientDescentOptimizer .

Problem

当我运行训练作业时,它打印出一个长堆栈跟踪并在 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?

Analysis

查看源代码,我发现 AdamOptimizer_create_slots() 方法中创建了许多零初始化的插槽,其中它调用 _zeros_slot() . 这会调用一个名为slot_creator的单独模块(源代码已链接) .

In line 62 of the slot_creator, it uses variable_scope.get_variable(). This used to be tf.Variable() in 0.12.

我对变量范围的理解是 variable_scope.get_variable() 无法创建变量 if reuse flag is on`. See here for source code.

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

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

Question

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

1 回答

  • 0

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

相关问题