如果在扫描内部或外部进行计算,则 theano.scan 输出梯度会有所不同



所以我有以下代码

def step(i, rng, prev, A, B):
    a = A*prev
    b = B*a
    return b, a, a+rng
rng = RandomStreams(lasagne.random.get_rng().randint(1,2147462579))
A = T.scalar("A")
B = T.scalar("B")
outputs, _ = theano.scan(step, 
                         sequences=[T.arange(1,5),rng.normal([4])], 
                         outputs_info=[T.ones_like(A),None, None], 
                         non_sequences=[A,B])
res, re, samp = outputs
grad = T.grad(cost=re.sum(), wrt=A)
func = theano.function([A,B],[grad])
print func(3.0,2.0)

上面的代码给出了 [array(985.0)] 的输出,这是正确的。但是,如果我改为执行以下渐变

grad = T.grad(cost=(re-samp).sum(), wrt=A, consider_constant=[samp])

梯度为 0。更有趣的是,如果我在扫描之外执行a+rng步骤,即使用 re 值生成samp,梯度再次正确出现 [array(985.0)] (使用 consider_constant=[samp] 时,这是我感兴趣的)。

有什么提示为什么会这样吗?我绝对需要在扫描内部执行随机计算,因此,很高兴知道在这种情况下是否有办法使梯度正常工作。

谢谢

使用theano.gradient.disconnected_grad怎么样

from theano import gradient
def step(i, rng, prev, A, B):
    a = A*prev
    b = B*a
    return b, a, a+rng
rng = RandomStreams(lasagne.random.get_rng().randint(1,2147462579))
A = T.scalar("A")
B = T.scalar("B")
outputs, _ = theano.scan(step,
                         sequences=[T.arange(1,5),rng.normal([4])],
                         outputs_info=[T.ones_like(A),None, None],
                         non_sequences=[A,B])
res, re, samp = outputs
grad = T.grad(cost=(re-gradient.disconnected_grad(samp)).sum(), wrt=A)
func = theano.function([A,B],[grad])
print func(3.0,2.0)

输出

[array(985.0, dtype=float32)]

最新更新