我试图在稀疏的theano变量中取exp
个非零元素。我有当前的代码:
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)
似乎也无效。)
我怎样才能做到这一点?
答案 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
。使用密集矩阵,这将起作用:
indices = mask.nonzero()
A = T.set_subtensor(A[indices], T.exp(A[indices]))
请注意,Theano没有分离的布尔类型 - 掩码为零和1 - 因此必须先调用nonzero()
来获取非零元素的索引。此外,这不适用于稀疏矩阵。
在非零稀疏元素上运行
Theano提供稀疏操作,据说这些操作是结构化的,仅在非零元素上运行。看到: http://deeplearning.net/software/theano/tutorial/sparse.html#structured-operation
更确切地说,它们在稀疏矩阵的data
属性上运行,与元素的索引无关。这些操作很容易实现。请注意,结构化操作将对data
数组中的所有值进行操作,也将显式设置为零。
答案 1 :(得分:0)
以下是使用scipy.sparse
模块执行此操作的方法。我不知道theano
如何实现稀疏。它可能基于类似的想法(因为它使用类似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
,indices
,indptr
。如果你在创建后摆弄它们,data
可能有0个值,但是新创建的矩阵不应该。
矩阵还有一个nonzero
方法,模仿numpy
个方法。实际上,它会将矩阵转换为coo
格式,过滤掉任何零值,并返回row
和col
属性:
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 ]])
答案 2 :(得分:0)
T.where
有效。
A_sparse = T.where(A_sparse == 0, 0, T.exp(A_sparse))
@Seppo Envari的回答似乎更快了。所以我会接受他的回答。