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

Tensorflow 为什么tf.assign()会减慢执行时间?,tensorflow,Tensorflow,今天,我在Tensorflow的LSTM中添加了一个学习率衰减 我改变 train_op = tf.train.RMSPropOptimizer(lr_rate).minimize(loss) 到 跑每一步 sess.run(tf.assign(lr, lr_rate*0.9**epoch)) 但是,此更改将执行时间从~7分钟增加到~20分钟以上 我的问题是: 为什么此更改会增加执行时间 一个明显的解决办法是每1000次迭代只做一次赋值。然而,我想了解这背后的原因 sess.run()是否

今天,我在Tensorflow的LSTM中添加了一个学习率衰减

我改变

train_op = tf.train.RMSPropOptimizer(lr_rate).minimize(loss)

跑每一步

sess.run(tf.assign(lr, lr_rate*0.9**epoch))
但是,此更改将执行时间从~7分钟增加到~20分钟以上

我的问题是: 为什么此更改会增加执行时间

一个明显的解决办法是每1000次迭代只做一次赋值。然而,我想了解这背后的原因

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

计算时间增加3似乎有点奇怪,但以下是一些您可以尝试的方法:

  • 在图表中创建op以更新您的学习率。在代码中,每一步都创建一个新操作,该操作将添加到图形中,因此可能需要额外的时间。通常,最佳做法是在
    tf.Session()之前创建所有必要的操作
update\u lr=tf.assign(lr,lr\u速率*0.9**epoch)
  • 每次迭代仅使用1个
    sess.run()
    ,将训练op和
    update\u lr
sess.run([train\u op,update\u lr],…)
  • 实现衰减学习率的更有效方法是使用。如果希望每个历元衰减0.9,可以执行以下操作:
training_size=60000#一个时代的大小
全局步长=tf.变量(0,可训练=False)
初学者学习率=0.1
学习率=tf.训练指数衰减(起始学习率、全局步长、,
培训(尺寸,0.9,楼梯=真实)
#将全局_步骤传递到minimize()将在每一步递增它。
列车运行=tf.train.RMSPropOptimizer(lr\u率)。最小化(损失,全局步数=全局步数)

您遇到的问题与
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)),
片段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),

它们都返回相同的值,看起来它们做的事情都一样。问题是它们创建了不同的图,如果在循环后
打印len(tf.get\u default\u graph().get\u operations())
,您将看到代码段1比代码段2有更多的节点。将范围增加到几千,差异将是显著的


对于臃肿的图形,您也有同样的问题。因为在循环的每次迭代中,您都会在图中创建
tf.assign(lr,lr\u rate*0.9**epoch)
3个节点。将图形定义与图形运行分开移动,您将看到改进。

虽然我不确定为什么这会使过程减慢这么多(因为不断创建新的图形节点可能会导致这种情况),但我认为最好使用feed\u dict来执行此操作:

learn_rate = tf.placeholder(tf.float32, shape=[])
optiizer = tf.train.AdamOptimizer(learn_rate)
...
learnrate = 1e-5
...
sess.run(minimizer, feed_dict={learn_rate: learnrate})

我使用这种方法,没有发现性能问题。此外,您可以传递任意数字,因此您甚至可以根据训练/验证数据的错误来增加/减少学习率。

感谢Olivier,我将实现指数衰减()。在本周末之前,我将报告改进。当你在每一个全局步骤后更新学习率时,很好的解释,臃肿的图表可能是一个严重的问题。
learn_rate = tf.placeholder(tf.float32, shape=[])
optiizer = tf.train.AdamOptimizer(learn_rate)
...
learnrate = 1e-5
...
sess.run(minimizer, feed_dict={learn_rate: learnrate})