2016-03-16 63 views
1

我试图在稀疏的theano变量中取非零元素的exp。我当前的代码:Theano:操作稀疏矩阵的非零元素

A = T.matrix("Some matrix with many zeros") 
A_sparse = theano.sparse.csc_from_dense(A) 

我试图做一些事情,这等同于以下numpy的语法:

mask = (A_sparse != 0) 
A_sparse[mask] = np.exp(A_sparse[mask]) 

但Theano不支持!=口罩呢。 (并且(A_sparse > 0) | (A_sparse < 0)似乎也不起作用。)

我该如何做到这一点?

回答

1

在Theano中对稀疏矩阵的支持是不完整的,所以有些东西很难实现。您可以在该特定情况下使用theano.sparse.structured_exp(A_sparse),但我会在下面更全面地回答您的问题。

比较

在Theano一个通常会使用这里所描述的比较操作符:http://deeplearning.net/software/theano/library/tensor/basic.html

例如,代替A != 0,一会写T.neq(A, 0)。对于稀疏矩阵,必须使用theano.sparse中的比较运算符。两个操作必须是稀疏矩阵,并且将结果也是一个稀疏矩阵:

mask = theano.sparse.neq(A_sparse, theano.sparse.sp_zeros_like(A_sparse)) 

修改子张

为了修改一个矩阵的一部分,可以使用theano.tensor.set_subtensor。与密集矩阵这会工作:

该Theano不具有分离的布尔型掩模
indices = mask.nonzero() 
A = T.set_subtensor(A[indices], T.exp(A[indices])) 

通知是零和一-所以nonzero()已经被称为第一取非零元素的索引。此外,这不适用于稀疏矩阵。

操作上非零元素的稀疏

Theano提供稀疏操作了据说被构造和仅在非零元素进行操作。参见: http://deeplearning.net/software/theano/tutorial/sparse.html#structured-operation

更准确地说,它们在稀疏矩阵的data属性上运行,与元素的索引无关。这些操作很容易实现。请注意,结构化操作将对data数组中的所有值进行操作,并且也将显式设置为零。

0

以下是使用scipy.sparse模块执行此操作的一种方法。我不知道theano如何实现它的稀疏。这很可能是基于类似的想法在dataindicesindptr(因为它使用的名称,如csc

In [224]: A=sparse.csc_matrix([[1.,0,0,2,0],[0,0,3,0,0],[0,1,1,2,0]]) 

In [225]: A.A 
Out[225]: 
array([[ 1., 0., 0., 2., 0.], 
     [ 0., 0., 3., 0., 0.], 
     [ 0., 1., 1., 2., 0.]]) 

In [226]: A.data 
Out[226]: array([ 1., 1., 3., 1., 2., 2.]) 

In [227]: A.data[:]=np.exp(A.data) 

In [228]: A.A 
Out[228]: 
array([[ 2.71828183, 0.  , 0.  , 7.3890561 , 0.  ], 
     [ 0.  , 0.  , 20.08553692, 0.  , 0.  ], 
     [ 0.  , 2.71828183, 2.71828183, 7.3890561 , 0.  ]]) 

csc格式的主要属性。如果你在创建之后捣鼓它们,data可能有一些0值,但是新创建的矩阵不应该。

该矩阵也有一个nonzero方法模拟numpy之一。在实践中,该矩阵转换为coo格式,过滤出所有零值,并返回rowcol属性:

In [229]: A.nonzero() 
Out[229]: (array([0, 0, 1, 2, 2, 2]), array([0, 3, 2, 1, 2, 3])) 

csc格式允许索引只是作为一个致密numpy的数组:

In [230]: A[A.nonzero()] 
Out[230]: 
matrix([[ 2.71828183, 7.3890561 , 20.08553692, 2.71828183, 
      2.71828183, 7.3890561 ]]) 
0

T.where的作品。

A_sparse = T.where(A_sparse == 0, 0, T.exp(A_sparse))

@Seppo Envari的答案似乎更快,虽然。所以我会接受他的回答。