Что такое правильный путь плотного вектора при умножении разреженной матрицы в тензорном потоке?
Согласно документации tf.matmul поддерживает умножение разреженных матриц, поэтому мне нужно использовать tf.sparse_matmul ? (А также tf.sparse_tensor_dense_matmul существует, поэтому в каких случаях следует использовать каждый из них?)
Также нужно ли преобразовать мою разреженную матрицу в tf.SparseTensor ? Также не очевидно, что tf.convert_to_tensor_or_sparse_tensor делает и как преобразовать плотную матрицу с нулевыми значениями или разреженную матрицу для подходящего ввода в тензорном потоке.
Вот что я попробовал (время для процессора):
import numpy as np
import tensorflow as tf
np.random.seed(2018)
# Parameters
n = 10*1000
m = 4*1000
p = 0.1
%%time
# Data preparation
dense_vector = np.random.rand(1,n).astype(np.float32)
print('dense_vector.shape', dense_vector.shape)
#print('dense_vector:')
#print(dense_vector)
dense_matrix = np.random.rand(n*m)
idx = np.random.choice(range(n*m), int((1.0-p)*n*m), replace=False)
dense_matrix[idx] = 0.0
dense_matrix = dense_matrix.reshape(n,m).astype(np.float32)
print('dense_matrix.shape', dense_matrix.shape)
#print('dense_matrix:')
#print(dense_matrix)
dense_vector.shape (1, 10000)
dense_matrix.shape (10000, 4000)
CPU times: user 9.8 s, sys: 2.38 s, total: 12.2 s
Wall time: 12.2 s
%%time
# Dense vector on dense matrix multiplication using numpy
res = dense_vector @ dense_matrix
print('res.shape', res.shape)
#print('res:')
#print(res)
%%time
# Dense vector on dense matrix multiplication using tensorflow tf.matmul V1
dense_vector_tf = tf.convert_to_tensor(dense_vector, np.float32)
dense_matrix_tf = tf.convert_to_tensor(dense_matrix, np.float32)
res_tf = tf.matmul(dense_vector_tf, dense_matrix_tf)
with tf.Session() as sess:
res = sess.run(res_tf)
print('res.shape', res.shape)
#print('res:')
#print(res)
res.shape (1, 4000)
CPU times: user 1.88 s, sys: 1.82 s, total: 3.7 s
Wall time: 3.54 s
%%time
# Dense vector on dense matrix multiplication using tensorflow tf.matmul V2
dense_vector_tf = tf.convert_to_tensor(dense_vector, np.float32)
dense_matrix_tf = tf.convert_to_tensor(dense_matrix, np.float32)
res_tf = tf.matmul(dense_vector_tf, dense_matrix_tf,
a_is_sparse=False,
b_is_sparse=True)
with tf.Session() as sess:
res = sess.run(res_tf)
print('res.shape', res.shape)
#print('res:')
#print(res)
res.shape (1, 4000)
CPU times: user 4.91 s, sys: 4.28 s, total: 9.19 s
Wall time: 9.07 s
%%time
# Dense vector on sparse matrix multiplication using tensorflow tf.sparse_matmul V1
dense_vector_tf = tf.convert_to_tensor(dense_vector, np.float32)
dense_matrix_tf = tf.convert_to_tensor(dense_matrix, np.float32)
res_tf = tf.sparse_matmul(dense_vector_tf, dense_matrix_tf,
a_is_sparse=False,
b_is_sparse=True)
with tf.Session() as sess:
res = sess.run(res_tf)
print('res.shape', res.shape)
#print('res:')
#print(res)
res.shape (1, 4000)
CPU times: user 4.82 s, sys: 4.18 s, total: 8.99 s
Wall time: 9 s
%%time
# Dense vector on sparse matrix multiplication using tensorflow tf.sparse_matmul V2
dense_vector_tf = tf.convert_to_tensor(dense_vector, np.float32)
dense_matrix_tf = tf.convert_to_tensor_or_sparse_tensor(dense_matrix, np.float32)
res_tf = tf.sparse_matmul(dense_vector_tf, dense_matrix_tf,
a_is_sparse=False,
b_is_sparse=True)
with tf.Session() as sess:
res = sess.run(res_tf)
print('res.shape', res.shape)
#print('res:')
#print(res)
res.shape (1, 4000)
CPU times: user 5.07 s, sys: 4.53 s, total: 9.6 s
Wall time: 9.61 s
Также я не вижу каких-либо улучшений при использовании разреженных матриц, что я делаю не так?