Tim
Tim

Reputation: 7474

Passing and working with sparse matrix in TensorFlow

Say that I have a matrix:

X = [
    [0, 0, 0, 0, 0],
    [0, 0, 1, 0, 0],
    [0, 0, 0, 0, 0],
    [2, 0, 0, 3, 0],
    [0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0],
    [0, 4, 0, 0, 0]
]

but it is stored in a sparse format:

# [row, column, value]
X_sparse = [
    [1, 2, 1],
    [3, 0, 2],
    [3, 3, 3]
    [6, 1, 4],
]

I also have a vector

b = [1,2,3,4,5]

I would like to pass X_sparse to TensorFlow as data and multiply it with b (i.e. np.dot(X, b)). What is the correct way to do this in TensorFlow? Additionally, this is a toy example, while in real-life X has many rows and columns, so I'd rather not want to work with it converted to non-sparse format.

Upvotes: 3

Views: 3538

Answers (2)

middle
middle

Reputation: 61

Probably there was no better option back then, there is a function for this now - doing the matrix multiplication after converting to dense makes the whole thing kind of pointless...

import tensorflow as tf
import numpy as np

A_vals = np.array([
    [1, 2, 1],
    [3, 0, 2],
    [3, 3, 3],
    [6, 1, 4],
])  
A_sparse = tf.SparseTensor(A_vals[:,:2], tf.cast(A_vals[:,2], tf.float32), [7, 5])
b = tf.constant([1,2,3,4,5], tf.float32)

# sparse-dense matrix multiplication
res = tf.sparse.sparse_dense_matmul(A_sparse, b[:,None])

Upvotes: 1

benjaminplanche
benjaminplanche

Reputation: 15159

I don't see an easy way to do so without using a dense tensor representation (tf.sparse_tensor_to_dense()). Tensorflow is however built for operations on huge matrices, so in many cases it shouldn't be a problem...

A quick example:

import tensorflow as tf
import numpy as np

X_sparse_np = np.array([
    [1, 2, 1],
    [3, 0, 2],
    [3, 3, 3],
    [6, 1, 4],
])  
b_np = np.array([1,2,3,4,5])
b = tf.constant(b_np)

# Converting your input data into a SparseTensor:
indices = X_sparse_np[:, :2].reshape((-1, 2))
values = X_sparse_np[:, 2]
dense_shape = [7, 5]
X_sparse = tf.SparseTensorValue(indices, values, dense_shape)

# Performing your operation on its dense representation:
res = tf.sparse_tensor_to_dense(X_sparse) * b

# opt. Re-obtaining the sparse representation of your result:
sparse_res = tf.SparseTensor(indices, tf.gather_nd(res, indices), dense_shape)

with tf.Session() as sess:
    print(sess.run(res))
    # [[ 0  0  0  0  0]
    #  [ 0  0  3  0  0]
    #  [ 0  0  0  0  0]
    #  [ 2  0  0 12  0]
    #  [ 0  0  0  0  0]
    #  [ 0  0  0  0  0]
    #  [ 0  8  0  0  0]]
    print(sess.run(sparse_res))
    # SparseTensorValue(
    #       indices=array([[1, 2],
    #                      [3, 0],
    #                      [3, 3],
    #                      [6, 1]]), 
    #       values=array([ 3,  2, 12,  8]), 
    #       dense_shape=array([7, 5]))

Upvotes: 4

Related Questions