0

我正在尝试在 Tensorflow 中实现体验回放。我遇到的问题是存储模型试验的输出,然后同时更新梯度。我尝试过的几种方法是存储来自 sess.run(model) 的结果值,但是,这些不是张量,就张量流而言不能用于梯度下降。我目前正在尝试使用 tf.assign(),但是,我遇到的困难通过这个例子得到了最好的体现。

import tensorflow as tf
import numpy as np

def get_model(input):
   return input

a = tf.Variable(0)
b = get_model(a)
d = tf.Variable(0)
for i in range(10):
   assign = tf.assign(a, tf.Variable(i))
   b = tf.Print(b, [assign], "print b: ")
   c = b
   d = tf.assign_add(d, c)
e = d

with tf.Session() as sess:
   tf.global_variables_initializer().run()
   print(sess.run(e))

我对上述代码的问题如下: - 它在每次运行时打印不同的值,这看起来很奇怪 - 在 for 循环中的每一步都没有正确更新我感到困惑的部分原因是我理解你有运行分配操作以更新先前的引用,但是,我只是无法弄清楚如何在 for 循环的每个步骤中正确执行此操作。如果有更简单的方法,我愿意接受建议。此示例与我当前尝试输入一组输入并根据模型所做的每个预测获得总和的方式相同。如果对上述任何内容的澄清会有所帮助,我将非常乐意提供。

以下是上述代码运行 3 次的结果。

$ python test3.py
2018-07-03 13:35:08.380077: I T:\src\github\tensorflow\tensorflow\core\platform\cpu_feature_guard.cc:140] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
print b: [8]
print b: [8]
print b: [8]
print b: [8]
print b: [8]
print b: [8]
print b: [8]
print b: [8]
print b: [8]
print b: [8]
80


$ python test3.py
2018-07-03 13:35:14.055827: I T:\src\github\tensorflow\tensorflow\core\platform\cpu_feature_guard.cc:140] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
print b: [7]
print b: [6]
print b: [6]
print b: [6]
print b: [6]
print b: [6]
print b: [6]
print b: [6]
print b: [6]
print b: [6]
60

$ python test3.py
2018-07-03 13:35:20.120661: I T:\src\github\tensorflow\tensorflow\core\platform\cpu_feature_guard.cc:140] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
print b: [9]
print b: [9]
print b: [9]
print b: [9]
print b: [9]
print b: [9]
print b: [9]
print b: [9]
print b: [9]
print b: [9]
90

我期待的结果如下:

print b: [0]
print b: [1]
print b: [2]
print b: [3]
print b: [4]
print b: [5]
print b: [6]
print b: [7]
print b: [8]
print b: [9]
45

我感到困惑的主要原因是,有时它提供了所有 9,这让我认为它加载了最后一个分配的值 10 次,但是,有时它加载了不同的值,这似乎与这个理论形成对比。

我想做的是输入一组输入示例并同时计算所有示例的梯度。它需要同时进行,因为所使用的奖励取决于模型的输出,因此如果模型发生变化,结果奖励也会发生变化。

4

1 回答 1

0

当您调用tf.assign(a, tf.Variable(i))它时,它实际上并没有立即将第二个变量的值分配给第一个变量。它只是在 NN 中创建一个操作来在sess.run(...)调用时进行分配。

当它被调用时,所有 10 个作业都尝试同时完成它们的作业。其中一个随机获胜,然后传递给 10 个assign_add操作,这实际上将其乘以 10 倍。

至于您实施体验重放的动机问题,我遇到的大多数方法都用于tf.placeholder()将体验缓冲内容馈送到训练网络中。

于 2018-07-14T01:27:00.693 回答