提交 9b57d59d authored 作者: fsavard's avatar fsavard

Added grad for elemise:Prod, plus small test

上级 b5772743
...@@ -1155,8 +1155,40 @@ class Prod(CAReduce): ...@@ -1155,8 +1155,40 @@ class Prod(CAReduce):
def grad(self, (x, ), (gz, )): def grad(self, (x, ), (gz, )):
if x.dtype[0:3] in ('int','uin'): if x.dtype[0:3] in ('int','uin'):
return [None] return [None]
else:
raise NotImplementedError('Will be implemented shortly') prod_out = self(x)
gz = as_tensor_variable(gz)
axis = self.axis
if axis is None:
axis = range(x.type.ndim)
if axis == ():
return gz,
new_dims = []
i = 0
for j, _ in enumerate(x.type.broadcastable):
if j in axis:
new_dims.append('x')
else:
new_dims.append(i)
i += 1
# fill a matrix with the same shape as x by broadcasting
# values taken from gz, which has the same shape as the output
# of prod().
gz_filled_x = Elemwise(scalar.second)(x,
DimShuffle(gz.type.broadcastable, new_dims)(gz))
# do the same with the output of prod, by broadcasting along
# axises where the product was taken
prod_out_filled_x = Elemwise(scalar.second)(x,
DimShuffle(prod_out.type.broadcastable,
new_dims)(prod_out))
return [theano.tensor.mul(gz_filled_x,
theano.tensor.true_div(prod_out_filled_x, x))]
#else:
# raise NotImplementedError('Will be implemented shortly')
def __str__(self): def __str__(self):
if self.axis is None: if self.axis is None:
......
...@@ -253,6 +253,34 @@ class test_CAReduce(unittest.TestCase): ...@@ -253,6 +253,34 @@ class test_CAReduce(unittest.TestCase):
#self.with_linker(gof.CLinker(), or_) #self.with_linker(gof.CLinker(), or_)
#self.with_linker(gof.CLinker(), and_) #self.with_linker(gof.CLinker(), and_)
def test_prod_grad():
x_val = numpy.asarray([[1,2,3],[4,5,6],[7,8,9]], dtype='float32')
x = theano.tensor.dmatrix()
p = Prod(axis=0)(x)
# sanity check
fn = theano.function([x], [p])
assert numpy.allclose(fn(x_val), numpy.array([ 28., 80., 162.]))
# very basic case for the product; no broadcasting in x
g = theano.tensor.grad(p.sum(), x)
g_fn = theano.function([x], g)
assert numpy.allclose(g_fn(x_val),
numpy.asarray([[28.,40.,54.],[7.,16.,27.],[4.,10.,18.]]))
# now with some tranposition in input
x_bc = x.dimshuffle(1, 0)
p_bc = Prod(axis=0)(x_bc)
p_bc_sum = p_bc.sum()
g_bc = theano.tensor.grad(p_bc_sum, x)
g_fn_bc = theano.function([x], [p_bc,g_bc])
p_bc_ret, g_bc_ret = g_fn_bc(x_val)
assert numpy.allclose(p_bc_ret, numpy.array([ 6., 120., 504.]))
assert numpy.allclose(g_bc_ret,
numpy.asarray([[6.,3.,2.],[30.,24.,20.],[72.,63.,56.]]))
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() #unittest.main()
test_prod_grad()
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论