【问题标题】:How to alternate train op's in tensorflow?如何在张量流中交替训练操作?
【发布时间】:2017-11-07 10:53:59
【问题描述】:

我正在实施交替训练计划。该图包含两个训练操作。培训应在这些之间交替进行。

这与 thisthis 等研究相关

下面是一个小例子。但它似乎在每一步都更新了两个操作。我怎样才能明确地在这些之间交替?

from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
# Import data
mnist = input_data.read_data_sets('/tmp/tensorflow/mnist/input_data', one_hot=True)

# Create the model
x = tf.placeholder(tf.float32, [None, 784])
W = tf.Variable(tf.zeros([784, 10]), name='weights')
b = tf.Variable(tf.zeros([10]), name='biases')
y = tf.matmul(x, W) + b

# Define loss and optimizer
y_ = tf.placeholder(tf.float32, [None, 10])
cross_entropy = tf.reduce_mean(
    tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y))
global_step = tf.Variable(0, trainable=False)

tvars1 = [b]
train_step1 = tf.train.GradientDescentOptimizer(0.5).apply_gradients(zip(tf.gradients(cross_entropy, tvars1), tvars1), global_step)
tvars2 = [W]
train_step2 = tf.train.GradientDescentOptimizer(0.5).apply_gradients(zip(tf.gradients(cross_entropy, tvars2), tvars2), global_step)
train_step = tf.cond(tf.equal(tf.mod(global_step,2), 0), true_fn= lambda:train_step1, false_fn=lambda : train_step2)


sess = tf.InteractiveSession()
tf.global_variables_initializer().run()


# Train
for i in range(1000):
    batch_xs, batch_ys = mnist.train.next_batch(100)
    sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})
    if i % 100 == 0:
        print(sess.run([cross_entropy, global_step], feed_dict={x: mnist.test.images,
                                         y_: mnist.test.labels}))

这会导致

[2.0890141, 2]
[0.38277805, 202]
[0.33943111, 402]
[0.32314575, 602]
[0.3113254, 802]
[0.3006627, 1002]
[0.2965056, 1202]
[0.29858461, 1402]
[0.29135355, 1602]
[0.29006076, 1802]      

全局步骤迭代到 1802,因此每次调用 train_step 时都会执行两个训练操作。 (例如,always-false 条件为 tf.equal(global_step,-1) 时也会发生这种情况。)

我的问题是如何交替执行train_step1train_step2

【问题讨论】:

    标签: python machine-learning tensorflow gradient-descent autodiff


    【解决方案1】:

    我认为最简单的方法就是

    for i in range(1000):
      batch_xs, batch_ys = mnist.train.next_batch(100)
      if i % 2 == 0:
        sess.run(train_step1, feed_dict={x: batch_xs, y_: batch_ys})
      else:
        sess.run(train_step2, feed_dict={x: batch_xs, y_: batch_ys})
    

    但是如果需要通过 tensorflow 条件流进行切换,可以这样操作:

    optimizer = tf.train.GradientDescentOptimizer(0.5)
    train_step = tf.cond(tf.equal(tf.mod(global_step, 2), 0),
                         true_fn=lambda: optimizer.apply_gradients(zip(tf.gradients(cross_entropy, tvars1), tvars1), global_step),
                         false_fn=lambda: optimizer.apply_gradients(zip(tf.gradients(cross_entropy, tvars2), tvars2), global_step))
    

    【讨论】:

    • 我需要将其放入tf,esimator API,这需要一个 train_op。因此,我不能像你建议的那样在 for 循环中这样做
    • @RobRomijnders 我明白了。然后第二个变体应该可以工作
    • 是的,它有效。似乎唯一的区别是您的解决方案定义了与tf.cond() 一致的train_step1。知道为什么会有所不同吗?
    • @RobRomijnders 实际上,我希望您的原始变体也可以。我认为优化器之间可能存在内部依赖关系,但 tensorboard 什么也没显示。对我来说似乎是一个错误。
    猜你喜欢
    • 1970-01-01
    • 2016-10-05
    • 1970-01-01
    • 2020-02-27
    • 1970-01-01
    • 1970-01-01
    • 2019-09-30
    • 2016-05-12
    • 1970-01-01
    相关资源
    最近更新 更多