2017-06-21 87 views
4

我试图用tensorflow生成斐波纳契数:F(n + 2)= F(n + 1)+ F(n)。每次运行我的代码时,它都会产生不同的结果,非常奇怪。代码很简单,并粘贴在下面。这是张力流中的错误吗?

import tensorflow as tf 

a = tf.Variable(1) 
b = tf.Variable(1) 
c = tf.Variable(2) 
sum=tf.add(a,b) 

as0 = tf.assign(a,b) 
as1=tf.assign(b, c) 
as2=tf.assign(c, sum) 

sess = tf.Session() 
init = tf.global_variables_initializer() 
sess.run(init) 
for i in range(10): 
    print(sess.run([as2, as1,as0])) 
+0

你是什么意思它返回不同的结果?我只是尝试过,每次都是一样的。似乎没有正确地产生你的序列,虽然 – JCooke

+0

这是一个有趣的!我每次都会得到不同的值,总是不正确的,并且总是第二和第三个元素相等,as2 [i] = as1 [i] + as1 [i-1]。我的猜测是,当你调用sess.run()时,你只是不知道图表执行的顺序是什么,所以分配和总和是以错误的(每次可能不同的)顺序执行的,到目前为止这是可能的你们知道吗? – gdelab

+0

顺便说一句,问题的标题太宽泛,你应该改变它来描述你的问题更好 – gdelab

回答

0

这是一个有趣的!

当你调用sess.run()时,你似乎只是不知道图的执行顺序,或者至少你不知道每个张量的计算结果是以何种顺序完成的,所以分配和总和在错误(每次可能不同)顺序中执行。下面的代码工作正常,通过强制图形做的事情以正确的顺序:

import tensorflow as tf 
a = tf.Variable(1) 
b = tf.Variable(1) 
c = tf.Variable(2) 
sum=tf.add(a,b) 
as0 = tf.assign(a,b) 
as1=tf.assign(b, c) 
as2=tf.assign(c, sum) 
sess = tf.Session() 
init = tf.global_variables_initializer() 
sess.run(init) 
for i in range(10): 
    sess.run(as0) 
    sess.run(as1) 
    print(sess.run(as2)) 

这是不是很实用,因为它是从图表的。 您可能会使用flow control ops强制它们按正确的顺序执行。

3

我认为@gdelab回答的不是完全是没错。我的意思是,解决问题的确是事实,但我认为这不是真正的原因。这是我的猜测。

我强烈地认为你试图在Jupyter笔记本上运行该代码。如果那不是真的,那么可能我错了。那么,假设是这样的:

  1. 第一次运行代码时,它给出了正确的输出。 First Time

  2. 第二次运行代码时,它会给出另一个输出。 enter image description here

  3. 但那是因为你没有从头开始运行。这是,内核不重新启动并且变量不会被擦除,所以输出更改。如果你“重启核”,然后再次运行该代码时,输出始终是相同的(第一图像的输出)enter image description here

现在,请不要告诉我你不使用Jupyter笔记本:)

0

如果一些操作可以与另一个并行执行,他们可能会。因此,执行顺序不是您编写的操作的顺序。

执行的顺序仅在明确强制执行时(与tf.control_dependencies一致)或者在计算另一个节点(当节点是另一个节点的先决条件时)之前必须计算节点时存在。

让我们深入到代码:

a = tf.Variable(1) 
b = tf.Variable(1) 
c = tf.Variable(2) 
sum=tf.add(a,b) 

到现在为止,你刚才定义3个变量和操作。 请注意:你的定义了一个节点。什么都没有发生。

as0 = tf.assign(a,b) 
as1=tf.assign(b, c) 
as2=tf.assign(c, sum) 

在这里,您定义 3分配操作。他们之间有无订单。 没有人知道之前和之后会执行什么,因为它们之间没有因果关系。

您唯一可以确定的是,在将sum的值分配给c之前,必须执行总和。

因此,在您的图形中,只有一个箭头从sum节点到assign(c,sum)节点。

P.S:这不是像斐波那契数列那样计算操作的推荐方式。相反,你应该使用tf.scan,它有一个可以帮助你很多的参数accumulator