为什么tf.assign()会减慢执行时间?

Rob*_*ers 0 tensorflow

今天我在Tensorflow中为我的LSTM添加学习率衰减.

我改变

train_op = tf.train.RMSPropOptimizer(lr_rate).minimize(loss)
Run Code Online (Sandbox Code Playgroud)

lr = tf.Variable(0.0,trainable=False)
Run Code Online (Sandbox Code Playgroud)

并运行每一个火车步骤

sess.run(tf.assign(lr, lr_rate*0.9**epoch))
Run Code Online (Sandbox Code Playgroud)

但是,这种变化会将执行时间从大约7分钟增加到大约20分钟.

我的问题是:为什么这种改变会增加执行时间?

一个明显的解决方法是每1000次迭代只进行一次分配.但是,我想了解这背后的原因.

  • sess.run()需要额外的时间吗?
  • tf.asign()需要额外的时间吗?
  • 我可以用另一种更高效的方式实现这个tf.assign()吗?

Sal*_*ali 9

你遇到的问题与sess.run或无关tf.assign.在许多模型中,这是一个非常受欢迎的问题,由于图形膨胀,您的模型很慢.我将在一个与您的代码无关的非常简单的示例中解释所有这些意味着什么.看看这两个片段:

片段1

a = tf.Variable(1, name='a')
b = tf.Variable(2, name='b')
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for _ in range(3):
        print sess.run(tf.add(a, b)),
Run Code Online (Sandbox Code Playgroud)

片段2

a = tf.Variable(1, name='a')
b = tf.Variable(2, name='b')
res = tf.add(a, b)
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for _ in range(3):
        print sess.run(res),
Run Code Online (Sandbox Code Playgroud)

它们都返回相同的值,看起来它们都做同样的事情.问题是他们创建了不同的图形,如果你将print len(tf.get_default_graph().get_operations())在循环之后,你将看到Snippet 1比Snippet 2有更多的节点.将范围增加到几千,差异将是显着的.

膨胀图表存在同样的问题.因为在循环的每次迭代中,您都会tf.assign(lr, lr_rate*0.9**epoch)在图中创建3个节点.将图表定义与图表运行分开移动,您将看到改进.