提交 2eb3a2c0 authored 作者: Rami Al-Rfou''s avatar Rami Al-Rfou'

Merge pull request #3 from viveksck/TheanoBugFix

Add a flag to decide which gradient should be returned from AdvSubtensor1
......@@ -8,9 +8,11 @@ http://www-users.cs.umn.edu/~saad/software/SPARSKIT/paper.ps
# Automatic methods for determining best sparse format?
import sys
import numpy
import theano
import scipy.sparse
from theano import gof, tensor, compile, scalar, config
from theano.gof.python25 import all
from theano.gradient import DisconnectedType
......@@ -18,6 +20,7 @@ from theano.sparse.utils import hash_from_sparse
import theano.tests.unittest_tools as utt
from theano.gradient import grad_not_implemented
from theano.sparse.type import SparseType, _is_sparse
from numpy.lib.stride_tricks import as_strided
sparse_formats = ['csc', 'csr']
......@@ -1754,8 +1757,8 @@ class AddSD(gof.op.Op):
%(z)s = (PyArrayObject *) PyArray_NewCopy(%(y)s, NPY_CORDER);
}else{
%(z)s = %(y)s;
Py_XINCREF(%(z)s);
}
Py_XINCREF(%(z)s);
npy_intp N = PyArray_DIMS(%(_indptr)s)[0]-1;
const npy_int32 * __restrict__ indptr = (npy_int32 *)%(_indptr)s->data;
......@@ -3288,3 +3291,68 @@ class Usmm(gof.op.Op):
out[0] = rval
usmm = Usmm()
class ConstructSparseFromList(gof.Op):
"""Constructs a sparse matrix out of a list of 2-D matrix rows"""
def __hash__(self):
return hash((type(self)))
def __eq__(self, other):
return (type(self) == type(other))
def __str__(self):
return self.__class__.__name__
def make_node(self, x, y, ilist):
x_ = theano.tensor.as_tensor_variable(x)
y_ = theano.tensor.as_tensor_variable(y)
ilist_ = theano.tensor.as_tensor_variable(ilist)
if ilist_.type.dtype[:3] not in ('int', 'uin'):
raise TypeError('index must be integers')
if ilist_.type.ndim != 1:
raise TypeError('index must be vector')
if x_.type.ndim == 0:
raise TypeError('cannot index into a scalar')
if y_.type.ndim > x_.type.ndim:
raise TypeError('cannot construct sparse matrix as dimensions differ')
return gof.Apply(self, [x_, y_, ilist_], [theano.sparse.csc_matrix(dtype=x.dtype)])
def perform(self, node, inp, out_):
x, values, idx = inp
out, = out_
rows, cols = values.shape
assert rows == len(idx)
indptr = numpy.arange(cols + 1) * rows
indices = as_strided(idx,
strides=(0, idx.strides[0]),
shape = (cols, idx.shape[0])).flatten()
data = values.T.flatten()
out[0] = scipy.sparse.csc_matrix((data, indices, indptr), shape=x.shape,
dtype=x.dtype)
def infer_shape(self, node, ishapes):
x, y, ilist = ishapes
return [x]
def R_op(self, inputs, eval_points):
if None in eval_points[:2]:
return [None]
return self.make_node(eval_points[0], eval_points[1],
*inputs[2:]).outputs
def connection_pattern(self, node):
rval = [[True], [True], [False]]
return rval
def grad(self, inputs, grads):
g_output, = grads
x, y = inputs[:2]
idx_list = inputs[2:]
gx = g_output
gy = theano.tensor.advanced_subtensor1(g_output, *idx_list)
return [gx, gy] + [DisconnectedType()()] * len(idx_list)
......@@ -619,7 +619,7 @@ class TensorType(Type):
Inf entries. (Used in `DebugMode`)
"""
def __init__(self, dtype, broadcastable, name=None):
def __init__(self, dtype, broadcastable, name=None, sparsegrad=False):
"""Initialize self.dtype and self.broadcastable.
:Parameters:
......@@ -644,6 +644,7 @@ class TensorType(Type):
self.dtype_specs() # error checking is done there
self.name = name
self.numpy_dtype = numpy.dtype(self.dtype)
self.sparsegrad = sparsegrad
def filter(self, data, strict=False, allow_downcast=None):
"""Convert `data` to something which can be associated to a
......@@ -6523,7 +6524,10 @@ class AdvancedSubtensor1(Op):
gz, = grads
assert len(inputs) == 2
rval1 = [ConstructSparse()(inputs[0], gz, inputs[1])]
if inputs[0].type.sparsegrad:
rval1 = [theano.sparse.ConstructSparseFromList()((inputs[0]), gz, inputs[1])]
else:
rval1 = [advanced_inc_subtensor1(zeros_like(inputs[0]), gz, inputs[1])]
return rval1 + [DisconnectedType()()] * (len(inputs) - 1)
def R_op(self, inputs, eval_points):
......@@ -6535,81 +6539,6 @@ class AdvancedSubtensor1(Op):
x, ilist = ishapes
return [ilist + x[1:]]
class ConstructSparse(Op):
"""Constructs a sparse matrix out of a list of 2-D matrix rows"""
def __init__(self):
import scipy.sparse as ssparse
from numpy.lib.stride_tricks import as_strided
self.m_ssparse = ssparse
self.m_as_strided = as_strided
def __hash__(self):
return hash((type(self)))
def __eq__(self, other):
return (type(self) == type(other))
def __str__(self):
return self.__class__.__name__
def make_node(self, x, y, ilist):
x_ = as_tensor_variable(x)
y_ = as_tensor_variable(y)
ilist_ = as_tensor_variable(ilist)
if ilist_.type.dtype[:3] not in ('int', 'uin'):
raise TypeError('index must be integers')
if ilist_.type.ndim != 1:
raise TypeError('index must be vector')
if x_.type.ndim == 0:
raise TypeError('cannot index into a scalar')
if y_.type.ndim > x_.type.ndim:
raise TypeError('cannot construct sparse matrix as dimensions differ')
return Apply(self, [x_, y_, ilist_], [theano.sparse.csc_matrix(dtype=x.dtype)])
def perform(self, node, inp, out_):
x, values, idx = inp
out, = out_
rows, cols = values.shape
assert rows == len(idx)
indptr = numpy.arange(cols + 1) * rows
indices = self.m_as_strided(idx,
strides=(0, idx.strides[0]),
shape = (cols, idx.shape[0])).flatten()
data = values.T.flatten()
out[0] = self.m_ssparse.csc_matrix((data, indices, indptr), shape=x.shape,
dtype=x.dtype)
def infer_shape(self, node, ishapes):
x, y, ilist = ishapes
return [x]
def R_op(self, inputs, eval_points):
if None in eval_points[:2]:
return [None]
return self.make_node(eval_points[0], eval_points[1],
*inputs[2:]).outputs
def connection_pattern(self, node):
rval = [[True], [True]]
for ipt in node.inputs[2:]:
rval.append([False])
return rval
def grad(self, inputs, grads):
g_output, = grads
x, y = inputs[:2]
idx_list = inputs[2:]
gx = g_output
gy = advanced_subtensor1(g_output, *idx_list)
return [gx, gy] + [DisconnectedType()()] * len(idx_list)
advanced_subtensor1 = AdvancedSubtensor1()
......@@ -6700,11 +6629,7 @@ class AdvancedIncSubtensor1(Op):
def connection_pattern(self, node):
rval = [[True], [True]]
for ipt in node.inputs[2:]:
rval.append([False])
rval = [[True], [True], [False]]
return rval
def grad(self, inputs, grads):
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论