Python / Theano:是否有可能构建真正的递归theano函数?

时间:2017-02-27 08:01:01

标签: python recursion theano

例如,我可以定义一个递归的Python lambda函数来计算Fibonacci序列,如下所示:

fn = lambda z: fn(z-1)+fn(z-2) if z > 1 else z

但是,如果我尝试将其转换为Theano函数,Theano不会接受fn,因为fn调用布尔运算">"。所以这段代码崩溃了:

z = T.scalar('z')
fn = lambda z: fn(z-1)+fn(z-2) if z > 1 else z
fibby = theano.function([z], fn(z))

但是如果我用theano.tensor.gt(z,1)替换布尔运算符,则代码会进入无限递归,因此theano.tensor.gt(z,1)不会扮演角色">":

z = T.scalar('z')
fn = lambda z: fn(z-1)+fn(z-2) if theano.tensor.gt(z,1) else z
lappy = theano.function([z], fn(z))
print(lappy(4))

运行此结果会导致"超出最大递归深度"。怎么了?我得到了相同的#34;超过了最大递归深度"如果我用

替换fn的定义,则会出错
fn = lambda z: theano.ifelse(theano.tensor.gt(z,1),fn(z-1)+fn(z-2),z)

PS我不打算使用theano.scan做这个...因为我想学习递归地进行这个计算,而不需要求助于显式循环。

- 肯

1 个答案:

答案 0 :(得分:1)

在Theano中,您可以使用outputs_info的{​​{1}}参数进行递归,并在theano.scan(fn=myfunc(), outputs_info=...)的下一次迭代中将myfunc()的先前输出作为参数传递。

在斐波那契数列的情况下,代码可能如下所示:

myfunc()

输出:

import numpy as np
import theano
import theano.tensor as T

# placeholder for the number of elements in the Fibonacci sequence
t_N = T.iscalar('N')

# first two elements for Fibonacci sequence
initial = np.array([1,1], dtype=np.int32)
t_initial = theano.shared(initial)

def fibonacci_iter(prev1_value, prev2_value):
    return prev1_value + prev2_value

# Iterate N-2 times over fibonacci() function
# ('taps': [-2,-1] means take two previous values in the sequence of outputs):
outputs, updates = theano.scan(
    fn=fibonacci_iter,
    outputs_info = [{'initial': t_initial, 'taps': [-2,-1]}],  # a list of dicts or a dict
    n_steps=t_N-2)

# compiled function:
fibonacci = theano.function(
    inputs=[t_N],
    outputs=outputs)

n = 10
fibonacci_seq = fibonacci(n)
print(np.concatenate([initial, fibonacci_seq]))

参考:
http://deeplearning.net/software/theano/library/scan.html#theano.scan