所以我有以下代码
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)]