提交 2eccc507 authored 作者: Vivek Kulkarni's avatar Vivek Kulkarni

Taken care of all comments

上级 e68ccc58
......@@ -20,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']
......@@ -3290,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)
......@@ -6523,7 +6523,7 @@ class AdvancedSubtensor1(Op):
gz, = grads
assert len(inputs) == 2
rval1 = [ConstructSparse()(inputs[0], gz, inputs[1])]
rval1 = [theano.sparse.ConstructSparseFromList()(inputs[0], gz, inputs[1])]
return rval1 + [DisconnectedType()()] * (len(inputs) - 1)
def R_op(self, inputs, eval_points):
......@@ -6535,77 +6535,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], [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()
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论