例如,我可以定义一个递归的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做这个...因为我想学习递归地进行这个计算,而不需要求助于显式循环。
- 肯
答案 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