提交 933eeb94 authored 作者: Valentin Bisson's avatar Valentin Bisson 提交者: Frederic

Implemented non-sparse grad.

上级 2babd2d6
...@@ -31,7 +31,7 @@ class SpSum(Op): ...@@ -31,7 +31,7 @@ class SpSum(Op):
:param sparse_grad: if True, this instance ignores the gradient on matrix elements which are implicitly 0. :param sparse_grad: if True, this instance ignores the gradient on matrix elements which are implicitly 0.
""" """
super(SpSum, self).__init__() super(SpSum, self).__init__()
self.axis=axis self.axis = axis
self.sparse_grad = sparse_grad self.sparse_grad = sparse_grad
if self.axis not in (None, 0, 1): if self.axis not in (None, 0, 1):
raise ValueError('illegal value for self.axis') raise ValueError('illegal value for self.axis')
...@@ -54,9 +54,8 @@ class SpSum(Op): ...@@ -54,9 +54,8 @@ class SpSum(Op):
# At least for small matrices (5x5), the .sum() method of a csc matrix returns a dense matrix # At least for small matrices (5x5), the .sum() method of a csc matrix returns a dense matrix
# as the result whether axis is 0 or 1... weird! # as the result whether axis is 0 or 1... weird!
### ###
#make sure a sparse type has been given in input
assert isinstance(x.type, theano.sparse.SparseType) assert isinstance(x.type, theano.sparse.SparseType)
b=() b = ()
if self.axis is not None: if self.axis is not None:
b=(False,) b=(False,)
z = tensor.tensor(broadcastable=b, dtype=x.dtype) z = tensor.tensor(broadcastable=b, dtype=x.dtype)
...@@ -75,8 +74,8 @@ class SpSum(Op): ...@@ -75,8 +74,8 @@ class SpSum(Op):
def perform(self,node, (x,), (z,)): def perform(self,node, (x,), (z,)):
if self.axis is None: if self.axis is None:
z[0] = numpy.asarray(x.sum()) z[0] = numpy.asarray(x.sum())
else: else:
s = set(xrange(len(x.shape)))-set([self.axis]) s = set(xrange(len(x.shape))) - set([self.axis])
myreshape = map((lambda i: x.shape[i]), s) myreshape = map((lambda i: x.shape[i]), s)
if x.format not in ('csc', 'csr'): if x.format not in ('csc', 'csr'):
x = x.asformat(x.format) x = x.asformat(x.format)
...@@ -95,30 +94,19 @@ class SpSum(Op): ...@@ -95,30 +94,19 @@ class SpSum(Op):
# z[0] = numpy.asarray(x.asformat(x.format).sum(axis=self.axis)).reshape((x.shape[0],)) # z[0] = numpy.asarray(x.asformat(x.format).sum(axis=self.axis)).reshape((x.shape[0],))
def grad(self,(x,), (gz,)): def grad(self,(x,), (gz,)):
print 'grad (sparse:%s):'%self.sparse_grad,x,gz if self.axis is None:
if self.sparse_grad: r = gz * theano.sparse.sp_ones_like(x)
if self.axis is None: elif self.axis == 0:
return [gz * theano.sparse.sp_ones_like(x)] r = col_scale(theano.sparse.sp_ones_like(x), gz)
elif self.axis == 0: elif self.axis == 1:
return col_scale(theano.sparse.sp_ones_like(x), gz) r = row_scale(theano.sparse.sp_ones_like(x), gz)
elif self.axis == 1:
return row_scale(theano.sparse.sp_ones_like(x), gz)
else:
assert False
else: else:
# if sparse_grad is False, this instance does not ignore the assert False
# gradient on matrix elements which are implicitly 0,
# and return a dense version of the data. if not self.sparse_grad:
if self.axis is None: r = theano.sparse.dense_from_sparse(r)
return [gz * tensor.ones_like(theano.sparse.dense_from_sparse(x))]
elif self.axis == 0: return [r]
raise NotImplementedError('non sparse grad, axis=0')
pass
elif self.axis == 1:
raise NotImplementedError('non sparse grad, axis=1')
pass
else:
assert False
def sp_sum(x, axis=None, sparse_grad=False): def sp_sum(x, axis=None, sparse_grad=False):
return SpSum(axis, sparse_grad)(x) return SpSum(axis, sparse_grad)(x)
......
...@@ -372,21 +372,19 @@ class TestSP(unittest.TestCase): ...@@ -372,21 +372,19 @@ class TestSP(unittest.TestCase):
# TODO: test both grad. # TODO: test both grad.
rng = numpy.random.RandomState(42) rng = numpy.random.RandomState(42)
from theano.sparse.basic import SparseFromDense,DenseFromSparse from theano.sparse.basic import SparseFromDense,DenseFromSparse
for format,cast in [("csc",scipy.sparse.csc_matrix), ("csr",scipy.sparse.csr_matrix)]: cases = [("csc", scipy.sparse.csc_matrix), ("csr", scipy.sparse.csr_matrix)]
for format, cast in cases:
print 'format: %(format)s'%locals() print 'format: %(format)s'%locals()
x = theano.sparse.SparseType(format=format, x = theano.sparse.SparseType(format=format,
dtype=theano.config.floatX)() dtype=theano.config.floatX)()
x_data = numpy.arange(20).reshape(5,4).astype(theano.config.floatX) x_data = numpy.arange(20).reshape(5,4).astype(theano.config.floatX)
#print 'x_data:',x_data
#print 'x_data.sum():',x_data.sum()
# Sum on all axis # Sum on all axis
print 'sum on all axis...' print 'sum on all axis...'
z = theano.sparse.sandbox.sp.sp_sum(x) z = theano.sparse.sandbox.sp.sp_sum(x)
assert z.type.broadcastable==() assert z.type.broadcastable == ()
f = theano.function([x], z) f = theano.function([x], z)
x_val = cast(x_data) x_val = cast(x_data)
out = f(x_val) out = f(x_val)
...@@ -396,17 +394,17 @@ class TestSP(unittest.TestCase): ...@@ -396,17 +394,17 @@ class TestSP(unittest.TestCase):
# Sum on axis 0 # Sum on axis 0
print 'sum on axis 0...' print 'sum on axis 0...'
z = theano.sparse.sandbox.sp.sp_sum(x, axis=0) z = theano.sparse.sandbox.sp.sp_sum(x, axis=0)
assert z.type.broadcastable==(False,) assert z.type.broadcastable == (False,)
f = theano.function([x], z) f = theano.function([x], z)
x_val = cast(x_data) x_val = cast(x_data)
out = f(x_val) out = f(x_val)
expected=x_val.sum(axis=0) expected = x_val.sum(axis=0)
assert (out == expected).all() assert (out == expected).all()
# Sum on axis 1 # Sum on axis 1
print 'sum on axis 1...' print 'sum on axis 1...'
z = theano.sparse.sandbox.sp.sp_sum(x, axis=1) z = theano.sparse.sandbox.sp.sp_sum(x, axis=1)
assert z.type.broadcastable==(False,) assert z.type.broadcastable == (False,)
f = theano.function([x], z) f = theano.function([x], z)
x_val = cast(x_data) x_val = cast(x_data)
out = f(x_val) out = f(x_val)
...@@ -414,7 +412,7 @@ class TestSP(unittest.TestCase): ...@@ -414,7 +412,7 @@ class TestSP(unittest.TestCase):
assert (out == expected).all() assert (out == expected).all()
# Sparse gradient on Sum on all axis # Sparse gradient on Sum on all axis
# suspended until som estuff get fixed =/ # unfinished, and suspended until verify_grad get fixed
if False: if False:
print 'grad on sum on all axis...' print 'grad on sum on all axis...'
def fun(x): def fun(x):
...@@ -422,7 +420,7 @@ class TestSP(unittest.TestCase): ...@@ -422,7 +420,7 @@ class TestSP(unittest.TestCase):
# x is a dense matrix: make it sparse # x is a dense matrix: make it sparse
sparse_var = SparseFromDense(format)(x) sparse_var = SparseFromDense(format)(x)
# apply op # apply op
dense_sum = theano.sparse.sandbox.sp.SpSum(axis=None,sparse_grad=False)(sparse_var) dense_sum = theano.sparse.sandbox.sp.SpSum(axis=None, sparse_grad=False)(sparse_var)
return dense_sum return dense_sum
# cast back to dense so that verify_grad can work # cast back to dense so that verify_grad can work
dense_sum = theano.sparse.DenseFromSparse()(sparse_sum) dense_sum = theano.sparse.DenseFromSparse()(sparse_sum)
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论