2017-02-03 93 views
0

我有一个正常的前馈网络,产生一个矢量v。v的元素然后被用作稀疏矩阵M的非零条目(假设坐标是预定义的)。稀疏矩阵然后乘以一个密集向量,并在结果标量上定义一个损失。我想反向传播损失w.r.t.网络的权重,这需要通过稀疏矩阵。通过稀疏张量反向传播梯度?

这似乎是一个完全合理的用例的稀疏矩阵,但现在看来,这样的功能是不支持的。事实上,即使调用tf.gradients(男,[V])产生一个错误:

AttributeError: 'SparseTensor' object has no attribute 'value_index'

难道我做错了什么,或我的假设,这个功能不(没?)有正确吗?如果是后者,那么对于这种特殊的用例来说,是否存在一种解决方法,即重写所有具有渐变定义的稀疏张量操作?

回答

0

我在这里黑暗中钓鱼,从代码和文档工作,没有经验。

Tensor类创建者是:

def __init__(self, op, value_index, dtype): 
    # value_index: An `int`. Index of the operation's endpoint that produces this tensor. 

value_index被用于生成Tensor名称。

SparseTensor一个是

def __init__(self, indices, values, dense_shape): 

无处在它的定义文件tensorflow/tensorflow/python/framework/sparse_tensor.pyvalue_index引用。

它的参数是张量,大概每个都有自己的value_index

否则看起来SparseTensor是另一种IndexedSlices,它也包含张量。

tf.gradients的输入都是

A `Tensor` or list of tensors 

gradients定义文件有_IndexedSlicesToTensor方法,但没有等效SparseTensor。所以在IndexedSlices的情况下(如果结果太大,会出现警告),但似乎有某种自动转换为致密的情况,但不是SparseTensors。我不知道这是一个不完整的发展情况,还是一个不可兼容的情况。

1

上这方面的一个微小变化不工作,以直接的values一个SparseTensor的梯度:

import tensorflow as tf 
sparse_values = tf.identity(tf.Variable(tf.constant([1., 2., 3.]))) 
sparse_indices = tf.constant([[0, 0], [1, 1], [2, 2]], dtype=tf.int64) 
sparse_matrix = tf.SparseTensor(sparse_indices, sparse_values, [3, 3]) 
multiplied = tf.sparse_tensor_dense_matmul(sparse_matrix, tf.eye(3)) 
loss = tf.reduce_sum(multiplied) 
gradients = tf.gradients(loss, [sparse_values]) 
with tf.Session() as session: 
    tf.global_variables_initializer().run() 
    print(session.run(gradients)) 

打印(上TensorFlow 0.12.1):

[array([ 1., 1., 1.], dtype=float32)] 

为什么tf.identity运是必要的梯度被定义我还没有弄清楚(可能与ref dtypes有关)。