6

背景:

通常我会用'x = fmatrix()'之类的输入定义一个theano函数,但是,在修改keras(一个基于theano的深度学习库)以使其与CTC成本一起工作时,我注意到一个非常奇怪的问题:如果一个输入成本函数的声明为

x = tensor.zeros(shape=[M,N], dtype='float32')

代替

x = fmatrix()

训练过程会收敛得更快。

一个简化的问题:

上面的整个代码都很大。所以我尝试将问题简化如下:说一个用于计算 Levenshtein 编辑距离的函数

import theano
from theano import tensor
from theano.ifelse import ifelse
def editdist(s, t):
    def update(x, previous_row, target):
        current_row = previous_row + 1
        current_row = tensor.set_subtensor(current_row[1:], tensor.minimum(current_row[1:], tensor.add(previous_row[:-1], tensor.neq(target,x))))
        current_row = tensor.set_subtensor(current_row[1:], tensor.minimum(current_row[1:], current_row[0:-1] + 1))
        return current_row
    source, target = ifelse(tensor.lt(s.shape[0], t.shape[0]), (t, s), (s, t))
    previous_row = tensor.arange(target.size + 1, dtype=theano.config.floatX)
    result, updates = theano.scan(fn = update, sequences=source, outputs_info=previous_row, non_sequences=target, name='editdist')
    return result[-1,-1]

然后我定义了两个函数 f1 和 f2 像:

x1 = tensor.fvector()
x2 = tensor.fvector()
r1 = editdist(x1,x2)
f1 = theano.function([x1,x2], r1)
x3 = tensor.zeros(3, dtype='float32')
x4 = tensor.zeros(3, dtype='float32')
r2 = editdist(x3,x4)
f2 = theano.function([x3,x4], r2)

使用 f1 和 f2 计算时,结果不同:

>>f1([1,2,3],[1,3,3])
   array(1.0)

>>f2([1,2,3],[1,3,3])
   array(3.0)

f1 给出了正确的结果,但 f2 没有。

所以我的问题是:定义 theano 函数的正确方法是什么?而且,f2到底出了什么问题?

更新:

我正在使用版本 0.8.0.dev0 的 theano。我刚刚尝试了 theano 0.7.0,f1 和 f2 都给出了正确的结果。也许这是theano的错误?

Update_1st 2016 年 1 月 27 日:

根据@lamblin 对此问题的解释(https://github.com/Theano/Theano/issues/3925#issuecomment-175088918),这实际上是theano的一个错误,并且已在最新(1- 26-2016) 版本。为方便起见,这里引用了lamblin的解释:

第一种方式是最自然的方式,但理论上两者应该是等价的。x3 和 x4 被创建为“alloc”操作的输出,其输入将是常量 3,而不是像 x1 和 x2 这样的自由输入,但这无关紧要,因为您将 [x3, x4] 作为输入传递给theano.function,它应该在那里切割计算图。

我的猜测是 scan 过早地优化,相信 x3 或 x4 保证始终为常数 0,并且在为它们提供值时进行了一些证明不正确的简化。那将是扫描中的一个实际错误。”

2016 年 1 月 27 日第二次更新:

不幸的是,该错误尚未完全修复。在背景部分中我提到如果将成本函数的一个输入声明为 tensor.zeros() 收敛过程会快得多,我找到了原因:当输入声明为 tensor.zeros() 时,成本函数给出了结果不正确,尽管神秘地这有助于收敛。我在这里管理了一个简化的问题重现演示(https://github.com/daweileng/TheanoDebug),运行 ctc_bench.py​​,你可以看到结果。

4

1 回答 1

2

theano.tensor.zeros(...)不能取除 0 以外的任何其他值。

当然,除非您将节点添加到图中并使用theano.tensor.set_subtensor.

输入张量theano.tensor.fmatrix可以采用您输入的任何值。

于 2016-01-25T08:45:15.520 回答