提交 28496857 authored 作者: ChienliMa's avatar ChienliMa

gradient still not implemented fot there is an undefined gradient

上级 d498f7e0
...@@ -8,6 +8,7 @@ tensor = basic ...@@ -8,6 +8,7 @@ tensor = basic
from theano.gradient import DisconnectedType from theano.gradient import DisconnectedType
class CumsumOp(theano.Op): class CumsumOp(theano.Op):
# See function cumsum for docstring # See function cumsum for docstring
def __init__(self, axis=None): def __init__(self, axis=None):
...@@ -730,7 +731,7 @@ def fill_diagonal(a, val): ...@@ -730,7 +731,7 @@ def fill_diagonal(a, val):
# Offset version of fill_diagonal # Offset version of fill_diagonal
class FillDiagonalOffset(gof.Op): class FillDiagonalOffset(gof.Op):
# See function fill_diagonal for docstring # See function fill_diagonal_offset for docstring
def __eq__(self, other): def __eq__(self, other):
return type(self) == type(other) return type(self) == type(other)
...@@ -778,7 +779,7 @@ class FillDiagonalOffset(gof.Op): ...@@ -778,7 +779,7 @@ class FillDiagonalOffset(gof.Op):
start = offset start = offset
num_of_step = min( min(width,height), width - offset) num_of_step = min( min(width,height), width - offset)
else: else:
start = - offset * a.shape[0] start = - offset * a.shape[1]
num_of_step = min( min(width,height), height + offset) num_of_step = min( min(width,height), height + offset)
step = a.shape[1] + 1 step = a.shape[1] + 1
end = start + step * num_of_step end = start + step * num_of_step
...@@ -797,14 +798,18 @@ class FillDiagonalOffset(gof.Op): ...@@ -797,14 +798,18 @@ class FillDiagonalOffset(gof.Op):
grad = cost_grad[0] grad = cost_grad[0]
if (a.dtype.startswith('complex')): if (a.dtype.startswith('complex')):
return [None, None] return [None, None]
elif a.ndim > 2:
raise NotImplementedError('%s: gradient is currently implemented' # only valid for matrices
' for matrices only' % self.__class__.__name__) wr_a = fill_diagonal_offset(grad, 0, offset)
wr_a = fill_diagonal_offset(grad, 0, offset) # valid for any number of dimensions
# diag is only valid for matrices
import theano.sandbox.linalg import theano.sandbox.linalg
wr_val = theano.sandbox.linalg.ops.diag(grad).sum() wr_val = theano.sandbox.linalg.ops.diag(grad).sum()
return [wr_a, wr_val] wr_offset = axis_grad = theano.gradient.grad_undefined(
self, 2, offset,
"offset is not defined for non-integer offset so"
" fill_diagonal_offset(a,val,offset+eps) is undefined")
return [wr_a, wr_val,wr_offset]
fill_diagonal_offset_ = FillDiagonalOffset() fill_diagonal_offset_ = FillDiagonalOffset()
......
...@@ -479,32 +479,46 @@ class TestFillDiagonalOffset(utt.InferShapeTester): ...@@ -479,32 +479,46 @@ class TestFillDiagonalOffset(utt.InferShapeTester):
y = tensor.scalar() y = tensor.scalar()
z = tensor.scalar() z = tensor.scalar()
f = function([x, y, z], fill_diagonal(x, y, z)) test_offset = numpy.array(numpy.random.randint(-5,5),
dtype = config.floatX)
f = function([x, y, z], fill_diagonal_offset(x, y, z))
for shp in [(8, 8), (5, 8), (8, 5)]: for shp in [(8, 8), (5, 8), (8, 5)]:
a = numpy.random.rand(*shp).astype(config.floatX) a = numpy.random.rand(*shp).astype(config.floatX)
val = numpy.cast[config.floatX](numpy.random.rand()) val = numpy.cast[config.floatX](numpy.random.rand())
out = f(a, val, offset) out = f(a, val, test_offset)
# We can't use numpy.fill_diagonal as it is bugged. # We can't use numpy.fill_diagonal as it is bugged.
assert numpy.allclose(numpy.diag(out, offset), val) #pdb.set_trace()
assert (out == val).sum() == min(a.shape) assert numpy.allclose(numpy.diag(out, test_offset), val)
#pdb.set_trace()
if test_offset >= 0:
assert (out == val).sum() == min( min(a.shape),
a.shape[1]-test_offset )
else:
assert (out == val).sum() == min( min(a.shape),
a.shape[0]+test_offset )
def test_gradient(self): def test_gradient(self):
test_offset = numpy.array(numpy.random.randint(-5,5),
dtype = config.floatX)
utt.verify_grad(fill_diagonal_offset, [numpy.random.rand(5, 8), utt.verify_grad(fill_diagonal_offset, [numpy.random.rand(5, 8),
numpy.random.rand()], numpy.random.rand(),
test_offset],
n_tests=1, rng=TestFillDiagonalOffset.rng) n_tests=1, rng=TestFillDiagonalOffset.rng)
utt.verify_grad(fill_diagonal_offset, [numpy.random.rand(8, 5), utt.verify_grad(fill_diagonal_offset, [numpy.random.rand(8, 5),
numpy.random.rand()], numpy.random.rand(),
test_offset],
n_tests=1, rng=TestFillDiagonalOffset.rng) n_tests=1, rng=TestFillDiagonalOffset.rng)
def test_infer_shape(self): def test_infer_shape(self):
x = tensor.dmatrix() x = tensor.dmatrix()
y = tensor.dscalar() y = tensor.dscalar()
z = tensor.dscalar() z = tensor.dscalar()
test_offset = numpy.array(numpy.random.randint(-5,5),
dtype = config.floatX)
self._compile_and_check([x, y, z], [self.op(x, y, z)], self._compile_and_check([x, y, z], [self.op(x, y, z)],
[numpy.random.rand(8, 5), [numpy.random.rand(8, 5),
numpy.random.rand(), numpy.random.rand(),
numpy.random.randint(0,5)], test_offset],
self.op_class) self.op_class)
if __name__ == '__main__':
unittest.main()
\ No newline at end of file
...@@ -143,3 +143,5 @@ def test_argsort(): ...@@ -143,3 +143,5 @@ def test_argsort():
gv = f(m_val) gv = f(m_val)
gt = np.argsort(m_val, None) gt = np.argsort(m_val, None)
assert np.allclose(gv, gt) assert np.allclose(gv, gt)
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论