我有一个正常的前馈网络,它产生一个向量v。然后将v的元素用作稀疏矩阵M的非零项(假设坐标是预定义的)。然后将稀疏矩阵乘以密集向量,并在得到的标量上定义损失。我想反向传播损失w.r.t.网络的权重,需要通过稀疏矩阵。
对于稀疏矩阵来说,这似乎是一个非常合理的用例,但似乎不支持这样的功能。实际上,即使调用tf.gradients(M,[v])也会产生错误:
AttributeError:' SparseTensor'对象没有属性' value_index'
我做错了什么,或者我认为这个功能还没有(但是?)存在?如果是后者,那么这个特定用例的解决方法是不能重写所有定义了渐变的稀疏张量操作?
答案 0 :(得分: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
op对于定义渐变是必要的我还没弄清楚(可能与ref dtypes有关)。
答案 1 :(得分: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.py
被value_index
引用。
它的论点是张量,可能每个都有自己的value_index
。
此外,SparseTensor
似乎是IndexedSlices
的替代品,tf.gradients
也包含张量。
A `Tensor` or list of tensors
的输入都是
gradients
_IndexedSlicesToTensor
定义文件有一个SparseTensor
方法,但IndexedSlices
没有任何等效方法。因此,在SparseTensors
的情况下似乎有某种自动转换为密集(如果结果太大则会发出警告),但l = ['Opinion, Journal, Editorial', 'Opinion, Magazine, Evidence-based', 'Evidence-based']
# Get list of unique classes
classes = list(set([j for i in l for j in i.split(', ')]))
=> ['Journal', 'Opinion', 'Editorial', 'Evidence-based', 'Magazine']
# Get indices in the matrix
indices = np.array([[k, classes.index(j)] for k, i in enumerate(l) for j in i.split(', ')])
=> array([[0, 1],
[0, 0],
[0, 2],
[1, 1],
[1, 4],
[1, 3],
[2, 3]])
# Generate output
output = np.zeros((len(l), len(classes)), dtype=int)
output[indices[:, 0], indices[:, 1]]=1
=> array([[ 1, 1, 1, 0, 0],
[ 0, 1, 0, 1, 1],
[ 0, 0, 0, 1, 0]])
则不然。我不知道这是一个不完全发展的情况,还是不相容的情况,使其无法实现。