在Tensorflow 1.9中,我想创建一个网络,然后将网络的输出(预测)递归地反馈到网络的输入中。在此循环中,我想将网络做出的预测存储在列表中。
这是我的尝试:
# Define the number of steps over which to loop the network
num_steps = 5
# Define the network weights
weights_1 = np.random.uniform(0, 1, [1, 10]).astype(np.float32)
weights_2 = np.random.uniform(0, 1, [10, 1]).astype(np.float32)
# Create a variable to store the predictions, one for each loop
predictions = tf.Variable(np.zeros([num_steps, 1]), dtype=np.float32)
# Define the initial prediction to feed into the loop
initial_prediction = np.array([[0.1]], dtype=np.float32)
x = initial_prediction
# Loop through the predictions
for step_num in range(num_steps):
x = tf.matmul(x, weights_1)
x = tf.matmul(x, weights_2)
predictions[step_num-1].assign(x)
# Define the final prediction
final_prediction = x
# Start a session
sess = tf.Session()
sess.run(tf.global_variables_initializer())
# Make the predictions
last_pred, all_preds = sess.run([final_prediction, predictions])
print(last_pred)
print(all_preds)
并输出:
[[48.8769]]
[[0.]
[0.]
[0.]
[0.]
[0.]]
因此,尽管
final_prediction
的值看起来正确,但predictions
的值却不是我所期望的。尽管行predictions
似乎实际上从未分配predictions[step_num-1].assign(x)
。请有人可以向我解释为什么这不起作用,我应该怎么做?谢谢!
最佳答案
发生这种情况是因为assign
与其他任何变量一样仅是TF op,因此仅在需要时才执行。由于final_prediction
的路径上没有任何内容依赖于assign op,并且predictions
只是一个变量,因此该赋值永远不会执行。
我认为最直接的解决方案是更换生产线
predictions[step_num-1].assign(x)
通过
x = predictions[step_num-1].assign(x)
这是可行的,因为
assign
还会返回其分配的值。现在,要计算final_prediction
TF,实际上需要“遍历” assign
op,因此应执行分配。另一种选择是使用
tf.control_dependencies
,这是一种在计算其他操作时“强制” TF计算特定操作的方法。但是在这种情况下,可能有点棘手,因为我们要强制执行的操作(assign
)取决于循环中正在计算的值,在这种情况下,我不确定TF填充的顺序。以下应该工作:for step_num in range(num_steps):
x = tf.matmul(x, weights_1)
x = tf.matmul(x, weights_2)
with tf.control_dependencies([predictions[step_num-1].assign(x)]):
x = tf.identity(x)
我们使用
tf.identity
作为noop只是为了用control_dependencies
包装一些东西。我认为这是两者之间更灵活的选择。但是,它带有the docs中讨论的一些警告。关于python - 在递归循环中分配给TensorFlow变量,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51937445/