tensorflow:如何在两个稀疏矩阵

时间:2017-08-17 09:34:51

标签: tensorflow sparse-matrix multiplication elementwise-operations

我使用tf.sparse_placeholder声明了两个稀疏矩阵。我需要在两个矩阵之间执行逐元素乘法。但我在tensorflow找不到这样的实现。最相关的函数是tf.sparse_tensor_dense_matmul,但这是一个在一个稀疏矩阵和一个密集矩阵之间执行矩阵乘法的函数。

我希望找到的是在两个稀疏矩阵之间执行逐元素乘法tensorflow中是否有任何实现?

我展示了以下在密集矩阵之间执行乘法的例子。我期待看到解决方案。

import tensorflow as tf
import numpy as np

# Element-wise multiplication, two dense matrices
A = tf.placeholder(tf.float32, shape=(100, 100))
B = tf.placeholder(tf.float32, shape=(100, 100))
C = tf.multiply(A, B)
sess = tf.InteractiveSession()
RandA = np.random.rand(100, 100)
RandB = np.random.rand(100, 100)
print sess.run(C, feed_dict={A: RandA, B: RandB})

# matrix multiplication, A is sparse and B is dense
A = tf.sparse_placeholder(tf.float32)
B = tf.placeholder(tf.float32, shape=(5,5))
C = tf.sparse_tensor_dense_matmul(A, B)
sess = tf.InteractiveSession()
indices = np.array([[3, 2], [1, 2]], dtype=np.int64)
values = np.array([1.0, 2.0], dtype=np.float32)
shape = np.array([5,5], dtype=np.int64)
Sparse_A = tf.SparseTensorValue(indices, values, shape)
RandB = np.ones((5, 5))
print sess.run(C, feed_dict={A: Sparse_A, B: RandB})

非常感谢!!!

4 个答案:

答案 0 :(得分:0)

您也可以将tf.matmultf.sparse_matmul用于稀疏矩阵;将a_is_sparseb_is_sparse设为True

matmul(
    a,
    b,
    transpose_a=False,
    transpose_b=False,
    adjoint_a=False,
    adjoint_b=False,
    a_is_sparse=False,
    b_is_sparse=False,
    name=None
)

对于逐元素乘法,一种解决方法是使用tf.sparse_to_dense将稀疏张量转换为密集表示,并使用tf.multiply进行逐元素乘法

答案 1 :(得分:0)

TensorFlow目前没有稀疏稀疏元素乘法运算。

我们目前不打算为此添加支持,但绝对欢迎捐款!欢迎在这里创建一个github问题:https://github.com/tensorflow/tensorflow/issues/new也许你或社区中的某个人可以选择它:)

谢谢!

答案 2 :(得分:0)

另一篇文章的解决方案。

https://stackoverflow.com/a/45103767/2415428

使用'Undefined'执行逐元素乘法。

TF2.1参考:https://www.tensorflow.org/api_docs/python/tf/sparse/SparseTensor#mul

答案 3 :(得分:0)

我使用的是 Tensorflow 2.4.1。

这是我将两个稀疏张量相乘元素的解决方法:

def sparse_element_wise_mul(a: tf.SparseTensor, b: tf.SparseTensor):
    a_plus_b = tf.sparse.add(a, b)
    a_plus_b_square = tf.square(a_plus_b)
    minus_a_square = tf.negative(tf.square(a))
    minus_b_square = tf.negative(tf.square(b))
    _2ab = tf.sparse.add(
        tf.sparse.add(
            a_plus_b_square,
            minus_a_square
        ),
        minus_b_square
    )
    ab = tf.sparse.map_values(tf.multiply, _2ab, 0.5)
    return ab

这里有一些简单的解释:

鉴于

<块引用>

(a+b)^2 = a^2 + 2a*b + b^2

我们可以计算出a*b

<块引用>

a*b = ((a+b)^2 - a^2 - b^2) / 2

似乎可以使用这种变通方法正确计算梯度。