Python递归Tensorflow Fibonacci数计算

时间:2017-03-30 22:09:53

标签: python recursion tensorflow

我是tensorflow的新手,我正在尝试编写一个递归计算fibonacci数的张量流程序。以下程序是我最终得到的,但它失败了许多我不理解的错误。有人可以帮助我理解我做错了什么以及如何解决它。这是我的计划:

import tensorflow as tf
tf.logging.set_verbosity(tf.logging.ERROR)

with tf.Graph().as_default() as g:
    fib_seed_0 = tf.Variable(0, name = "fib_seed_0")
    fib_seed_1 = tf.Variable(1, name = "fib_seed_1")

    def fib(n):
        return tf.cond(tf.equal(n, fib_seed_0), lambda: tf.identity(n),
       lambda: tf.cond(tf.equal(n, fib_seed_1), lambda: tf.identity(n),
       lambda: tf.add(fib(tf.subtract(n, 1)), fib(tf.subtract(n, 2)))))

    fib_to_calc = tf.Variable(5, name = "fib_to_calc")

    init = tf.global_variables_initializer()

    with tf.Session() as sess:
        sess.run(init)
        print(sess.run(fib(fib_to_calc)))

以上是tensorflow程序在python翻译中尝试做的事情:

def F(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return F(n-1) + F(n-2)

以下是错误日志的示例。它一直在继续:

Traceback (most recent call last):
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\ops\control_flow_ops.py", line 1775, in cond
    return merges[0] if len(merges) == 1 else merges
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\contextlib.py", line 77, in __exit__
    self.gen.throw(type, value, traceback)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 4169, in name_scope
    yield scope
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\contextlib.py", line 77, in __exit__
    self.gen.throw(type, value, traceback)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 3625, in get_controller
    yield default
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 4169, in name_scope
    yield scope
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\contextlib.py", line 77, in __exit__
    self.gen.throw(type, value, traceback)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 2860, in name_scope
    yield "" if new_stack is None else new_stack + "/"
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 4169, in name_scope
    yield scope
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\ops\control_flow_ops.py", line 1748, in cond
    _, res_f = context_f.BuildCondBranch(fn2)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\ops\control_flow_ops.py", line 1642, in BuildCondBranch
    r = fn()
  File "fib.py", line 13, in <lambda>
    lambda: tf.add(fib(tf.subtract(n, 1)), fib(tf.subtract(n, 2)))))
  File "fib.py", line 12, in fib
    lambda: tf.cond(tf.equal(n, fib_seed_1), lambda: tf.identity(n),
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\ops\control_flow_ops.py", line 1775, in cond
    return merges[0] if len(merges) == 1 else merges
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\contextlib.py", line 77, in __exit__
    self.gen.throw(type, value, traceback)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 4169, in name_scope
    yield scope
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\contextlib.py", line 77, in __exit__
    self.gen.throw(type, value, traceback)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 3625, in get_controller
    yield default
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 4169, in name_scope
    yield scope
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\contextlib.py", line 77, in __exit__
    self.gen.throw(type, value, traceback)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 2860, in name_scope
    yield "" if new_stack is None else new_stack + "/"
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 4169, in name_scope
    yield scope
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\ops\control_flow_ops.py", line 1748, in cond
    _, res_f = context_f.BuildCondBranch(fn2)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\ops\control_flow_ops.py", line 1642, in BuildCondBranch

... 上述错误重复多次,然后出现以下错误 ...

    r = fn()
  File "fib.py", line 12, in <lambda>
    lambda: tf.cond(tf.equal(n, fib_seed_1), lambda: tf.identity(n),
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\ops\gen_array_ops.py", line 1343, in identity
    result = _op_def_lib.apply_op("Identity", input=input, name=name)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\op_def_library.py", line 777, in apply_op
    return op
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\contextlib.py", line 77, in __exit__
    self.gen.throw(type, value, traceback)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 3625, in get_controller
    yield default
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\op_def_library.py", line 777, in apply_op
    return op
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\contextlib.py", line 77, in __exit__
    self.gen.throw(type, value, traceback)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 4169, in name_scope
    yield scope
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\contextlib.py", line 77, in __exit__
    self.gen.throw(type, value, traceback)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 3625, in get_controller
    yield default
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 4169, in name_scope
    yield scope
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\contextlib.py", line 77, in __exit__
    self.gen.throw(type, value, traceback)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 2860, in name_scope
    yield "" if new_stack is None else new_stack + "/"
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 4169, in name_scope
    yield scope
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\op_def_library.py", line 777, in apply_op
    return op
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\contextlib.py", line 77, in __exit__
    self.gen.throw(type, value, traceback)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\op_def_library.py", line 255, in _MaybeColocateWith
    yield
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\op_def_library.py", line 768, in apply_op
    op_def=op_def)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 2336, in create_op
    original_op=self._default_original_op, op_def=op_def)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 1232, in __init__
    self._control_flow_context.AddOp(self)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\ops\control_flow_ops.py", line 1598, in AddOp
    self._AddOpInternal(op)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\ops\control_flow_ops.py", line 1613, in _AddOpInternal
    real_x = self.AddValue(x)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\ops\control_flow_ops.py", line 1587, in AddValue
    result = _SwitchRefOrTensor(result, self._pred)[self._branch]
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\ops\control_flow_ops.py", line 364, in _SwitchRefOrTensor
    return switch(data, pred, name=name)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\contextlib.py", line 77, in __exit__
    self.gen.throw(type, value, traceback)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 2974, in colocate_with
    yield
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\ops\control_flow_ops.py", line 364, in _SwitchRefOrTensor
    return switch(data, pred, name=name)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\ops\control_flow_ops.py", line 320, in switch
    sparse_tensor.SparseTensor(ind_t, val_t, dense_shape_t))
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\contextlib.py", line 77, in __exit__
    self.gen.throw(type, value, traceback)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 4169, in name_scope
    yield scope
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\contextlib.py", line 77, in __exit__
    self.gen.throw(type, value, traceback)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 3625, in get_controller
    yield default
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 4169, in name_scope
    yield scope
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\contextlib.py", line 77, in __exit__
    self.gen.throw(type, value, traceback)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 2860, in name_scope
    yield "" if new_stack is None else new_stack + "/"
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 4169, in name_scope
    yield scope
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\ops\control_flow_ops.py", line 299, in switch
    return gen_control_flow_ops._switch(data, pred, name=name)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\ops\gen_control_flow_ops.py", line 371, in _switch
    result = _op_def_lib.apply_op("Switch", data=data, pred=pred, name=name)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\op_def_library.py", line 777, in apply_op
    return op
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\contextlib.py", line 77, in __exit__
    self.gen.throw(type, value, traceback)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 3625, in get_controller
    yield default
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\op_def_library.py", line 777, in apply_op
    return op
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\contextlib.py", line 77, in __exit__
    self.gen.throw(type, value, traceback)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 4169, in name_scope
    yield scope
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\contextlib.py", line 77, in __exit__
    self.gen.throw(type, value, traceback)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 3625, in get_controller
    yield default
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 4169, in name_scope
    yield scope
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\contextlib.py", line 77, in __exit__
    self.gen.throw(type, value, traceback)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 2860, in name_scope
    yield "" if new_stack is None else new_stack + "/"
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 4169, in name_scope
    yield scope
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\op_def_library.py", line 777, in apply_op
    return op
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\contextlib.py", line 77, in __exit__
    self.gen.throw(type, value, traceback)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\op_def_library.py", line 255, in _MaybeColocateWith
    yield
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\op_def_library.py", line 768, in apply_op
    op_def=op_def)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 2336, in create_op
    original_op=self._default_original_op, op_def=op_def)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\tensorflow\python\framework\ops.py", line 1180, in __init__
    if node_def.ByteSize() >= (1 << 31) or node_def.ByteSize() < 0:
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\google\protobuf\internal\python_message.py", line 1012, in ByteSize
    size += field_descriptor._sizer(field_value)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\google\protobuf\internal\encoder.py", line 359, in FieldSize
    entry_msg = message_type._concrete_class(key=key, value=value)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\google\protobuf\internal\python_message.py", line 511, in init
    copy = field._default_constructor(self)
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\google\protobuf\internal\python_message.py", line 423, in MakeSubMessageDefault
    result = message_type._concrete_class()
  File "C:\IronKey\DeveloperTools\Anaconda3\lib\site-packages\google\protobuf\internal\python_message.py", line 480, in init
    self._listener_for_children = _Listener(self)
RecursionError: maximum recursion depth exceeded

1 个答案:

答案 0 :(得分:4)

TensorFlow不支持对tf.cond()的递归调用,因为它的实现急切地调用为两个分支传递的两个lambda函数中的每一个(构建符号图),以及终止条件在图形构建时不知道,因此它会递归,直到用完堆栈空间。

使用当前不属于公共API的tensorflow.python.framework.function库,可以在TensorFlow中定义(可能是递归的)函数。对递归函数的支持是基本的,但您可以使用显式前向声明来定义一个,如下所示:

import tensorflow as tf
from tensorflow.python.framework import function

fib = function.Declare("Fib", [("n", tf.int32)], [("ret", tf.int32)])

@function.Defun(tf.int32, func_name="Fib", out_names=["ret"])
def FibImpl(n):
  return tf.cond(tf.less_equal(n, 1), 
                 lambda: tf.constant(1),
                 lambda: fib(n - 1) + fib(n - 2))

FibImpl.add_to_graph(tf.get_default_graph())

n = tf.placeholder(tf.int32, shape=[])
result = fib(n)

sess = tf.Session()
print(sess.run(result, feed_dict={n: 0}))  # 1
print(sess.run(result, feed_dict={n: 1}))  # 1
print(sess.run(result, feed_dict={n: 2}))  # 2
print(sess.run(result, feed_dict={n: 3}))  # 3
print(sess.run(result, feed_dict={n: 4}))  # 5
print(sess.run(result, feed_dict={n: 5}))  # 8
print(sess.run(result, feed_dict={n: 20}))  # 10946

当然,使用tf.while_loop()的迭代解决方案会更有效率!

相关问题