【问题标题】:Python/Theano: Is it possible to construct truly recursive theano functions?Python/Theano:是否可以构造真正递归的 theano 函数?
【发布时间】:2018-08-15 22:03:06
【问题描述】:

例如,我可以定义一个递归 Python lambda 函数来计算斐波那契数列,如下所示:

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))

运行此命令会导致“超出最大递归深度”。怎么了?如果我将 fn 的定义替换为

,我会得到相同的“超出最大递归深度”错误
fn = lambda z: theano.ifelse(theano.tensor.gt(z,1),fn(z-1)+fn(z-2),z)

PS 我不希望使用 theano.scan 来执行此操作...因为我想学习递归地执行此计算而不诉诸显式循环。

--肯

【问题讨论】:

  • 在递归 python 函数上使用 theano.as_op 装饰器是一种不折不扣的方式。但这并没有得到任何优化。

标签: python recursion theano


【解决方案1】:

在 Theano 中,您可以使用 theano.scan(fn=myfunc(), outputs_info=...)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]))

输出:

[ 1  1  2  3  5  8 13 21 34 55]

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-20
    • 2015-10-24
    • 1970-01-01
    • 2016-06-07
    • 1970-01-01
    • 1970-01-01
    • 2014-12-17
    相关资源
    最近更新 更多