是否有可能在每个训练步骤中获得目标函数值?

时间:2017-05-08 20:08:20

标签: python machine-learning tensorflow deep-learning

在通常的TensorFlow训练循环中,例如

train_op = tf.train.AdamOptimizer().minimize(cross_entropy)

with tf.Session() as sess:
    for i in range(num_steps):
        # ...
        train_op.run(feed_dict = feed_dict)

train_op.run返回None

但是,有时收集中间结果很有用,例如目标值或准确度。

添加额外的sess.run次呼叫需要再次进行前向传播,从而增加运行时间:

train_op = tf.train.AdamOptimizer().minimize(cross_entropy)

with tf.Session() as sess:
    for i in range(num_steps):
        # ...
        o, a = sess.run([objective, accuracy], feed_dict = feed_dict)
        train_op.run(feed_dict = feed_dict)

是否可以一次性在TensorFlow中执行此操作?

修改:

人们建议

sess.run([objective, accuracy, train_op], feed_dict = feed_dict)

但结果取决于列表元素的执行顺序:

[objective, accuracy, train_op]

似乎未定义 - you get different results depending on whether CUDA is being used

3 个答案:

答案 0 :(得分:2)

只需将style="resize:none添加到要评估的节点列表中。

train_op

关于培训步骤及其评估顺序,我做了以下小型实验:

o, a, _ = sess.run([objective, accuracy, train_op], feed_dict = feed_dict)

情况比我最初的想法更加困惑。似乎是给定的是,提取的执行顺序不依赖于它们在列表中的相应位置:import tensorflow as tf x = tf.Variable(0, dtype=tf.float32) loss = tf.nn.l2_loss(x-1) train_opt = tf.train.GradientDescentOptimizer(1) train_op = train_opt.minimize(loss) init_op = tf.global_variables_initializer() sess = tf.Session() sess.run(init_op) x_val, _, loss_val = sess.run([x, train_op, loss]) # returns x_val = 1.0, loss_val = 0.5 x_val将独立于它们在列表中的位置。

但是,正如@MaxB注意到的那样,他们的执行顺序并不能保证。在GPU上运行上述代码时,loss_val设置为0.0,即初始值。但是,在CPU上运行时,x_val为1.0,即x_val更新后的值

这种依赖于配置的行为可能仅限于由训练操作更新的变量,如上面的实验所示,但不能保证来自tf的文档。

答案 1 :(得分:1)

您可以在sess.run中提供任意数量的操作。在您的情况下,您使用objectiveaccuracy。在那里添加train_op。不需要它的结果,因此您可以使用_。基本上是:

o, a, _ = sess.run([objective, accuracy, train_op], feed_dict = feed_dict)

P.S。关于你的评论,sess.run将不会运行图3次。此外,它甚至不一定会运行图表一次。它将找出所有应评估的操作,以评估您提供的3件事并运行所有这些操作(因此运行子图一次)

答案 2 :(得分:0)

我通过对变量loss_after_train_op使用带有重复变量loss的tf.control_dependencies来解决问题。我建立在@ user1735003的答案上。

例如,如果您有兴趣在train_op“执行”后查找值,则可以将此代码添加到模型定义中:

with tf.control_dependencies([train_op]):
    loss_after_train_op = tf.nn.l2_loss(x - 1)

然后,如果您只是在loss_after_train_op来电中提到run,那么它会给出预期结果。

而且,不,你不能再次重用loss,因为那时你会重新定义它。回想一下,train_op已附加到上一个loss变量,因此您将失去对该变量的跟踪。

我还包括一个演示:

import tensorflow as tf

x = tf.Variable(0, dtype=tf.float32)

train_opt = tf.train.GradientDescentOptimizer(1)

init_op = tf.global_variables_initializer()

loss = tf.nn.l2_loss(x - 1)

train_op = train_opt.minimize(loss)
with tf.control_dependencies([train_op]):
    loss_after_train_op = tf.nn.l2_loss(x - 1)

sess = tf.Session()
sess.run(init_op)
loss_val_1 = sess.run(loss)

print loss_val_1

x_val, _, loss_val, loss_after_train_op_val = sess.run([x, train_op, loss, loss_after_train_op])

print x_val, loss_val, loss_after_train_op_val

输出

$ python test_control_dependencies.py
0.5
1.0 0.5 0.0
$